一步一步学SpringBoot(三)---SpringBoot与德鲁伊(Druid)的故事

添加依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.0</version>
        </dependency>

配置连接池

# JDBC配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url = jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver

# 连接池的配置信息
# 初始化连接数量
spring.datasource.initialSize=5
# 最小连接数量
spring.datasource.minIdle=5
# 最大同时连接数量
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间,单位毫秒ms
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒ms
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
# SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录
# from dual:dual是一个虚拟的表,供测试使用
spring.datasource.validationQuery=SELECT 1 FROM DUAL
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
# 注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
spring.datasource.testWhileIdle=true
# 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.
# 注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
spring.datasource.testOnBorrow=false
# 指明是否在归还到池中前进行检验
#注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;

在spring.datasource.filters添加log4j会运行报这个错:
Factory method 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/log4j/Logger
去掉就行

为方便以后拓展,这里提供一个数据源配置接口

创建DatabaseConfig接口

package com.test.springbm.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 数据源配置接口:
 * 为方便以后拓展,这里提供一个数据源配置接口,druid配置也只是这个接口的一个实现类,方便以后切换不同的数据源
 */
public interface DatabaseConfig {
    /**
     * 定义数据源
     * @return
     * @throws Exception
     */
    DataSource dataSource() throws Exception;

    /**
     * 定义session工厂
     * @param dataSource
     * @return
     * @throws Exception
     */
    SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception;

    /**
     * 定义事务管理器
     * @param dataSource
     * @return
     */
    DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource);
}

创建DruidConfig类实现DatabaseConfig接口

package com.test.springbm.config.impl;

/**
 *                             _ooOoo_
 *                            o8888888o
 *                            88" . "88
 *                            (| -_- |)
 *                            O\  =  /O
 *                         ____/`---'\____
 *                       .'  \\|     |//  `.
 *                      /  \\|||  :  |||//  \
 *                     /  _||||| -:- |||||-  \
 *                     |   | \\\  -  /// |   |
 *                     | \_|  ''\---/''  |   |
 *                     \  .-\__  `-`  ___/-. /
 *                   ___`. .'  /--.--\  `. . __
 *                ."" '<  `.___\_<|>_/___.'  >'"".
 *               | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *               \  \ `-.   \_ __\ /__ _/   .-` /  /
 *          ======`-.____`-.___\_____/___.-`____.-'======
 *                             `=---='
 *          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *                     佛祖保佑        永无BUG
 *            佛曰:
 *                   写字楼里写字间,写字间里程序员;
 *                   程序人员写程序,又拿程序换酒钱。
 *                   酒醒只在网上坐,酒醉还来网下眠;
 *                   酒醉酒醒日复日,网上网下年复年。
 *                   但愿老死电脑间,不愿鞠躬老板前;
 *                   奔驰宝马贵者趣,公交自行程序员。
 *                   别人笑我忒疯癫,我笑自己命太贱;
 *                   不见满街漂亮妹,哪个归得程序员?
 */

import com.alibaba.druid.pool.DruidDataSource;
import com.test.springbm.config.DatabaseConfig;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
@ConfigurationProperties(value="application.properties")
@MapperScan(basePackages = DruidConfig.PACKAGE, sqlSessionFactoryRef = "sessionFactory")
public class DruidConfig implements DatabaseConfig {

	//你的Mapper.java所在的报的位置,扫描这个包下的类
    public static final String PACKAGE = "com.test.springbm.mapper";
	//你的Mapper.xml的位置,classpath是相对路径,*Mapper.xml表示所有以Mapper结尾的xml
    public static final String MAPPER = "classpath:/mapper/*Mapper.xml";

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;

    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    /**
     * 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.<br/>
     * 注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
     */
    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    /**
     * 指明是否在归还到池中前进行检验<br/>
     * 注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
     */
    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    /**
     * 当开启时, 将为每个连接创建一个statement池,并且被方法创建的PreparedStatements将被缓存起来:
     */
    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;

    /**
     * 不限制  statement池能够同时分配的打开的statements的最大数量,如果设置为0表示不限制
     */
    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;

    /*@Value("${spring.datasource.defaultAutoCommit:false}")
    private boolean defaultAutoCommit;*/

    @Value("${spring.datasource.filters}")
    private String filters;

    /**
     * 当建立新连接时被发送给JDBC驱动的连接参数
     */
    @Value("${spring.datasource.connectionProperties}")
    private String connectionProperties;

    /**
     * 定义数据源
     * 注意@Primary注解表示:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常。SpringBoot为我们提供
     * 了一个默认的dataSource,当我们需要用我们自己的连接池的时候可以使用@primary注解告诉SpringBoot优先使用自己的dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "dataSource")
    @Primary
    @Override
    public DataSource dataSource() throws Exception {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(this.username);
        datasource.setPassword(this.password);
        datasource.setDriverClassName(this.driverClassName);
        datasource.setInitialSize(this.initialSize);
        datasource.setMinIdle(this.minIdle);
        datasource.setMaxActive(this.maxActive);
        datasource.setMaxWait(this.maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(this.timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(this.minEvictableIdleTimeMillis);
        datasource.setValidationQuery(this.validationQuery);
        datasource.setTestWhileIdle(this.testWhileIdle);
        datasource.setTestOnBorrow(this.testOnBorrow);
        datasource.setTestOnReturn(this.testOnReturn);
        datasource.setPoolPreparedStatements(this.poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(this.maxPoolPreparedStatementPerConnectionSize);
        /*datasource.setDefaultAutoCommit(this.defaultAutoCommit);*/
        datasource.setFilters(this.filters);
        datasource.setConnectionProperties(this.connectionProperties);
        return datasource;
    }

    /**
     * 定义session工厂
     * 注:ualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的,
     * 我们修改调用代码,添加@Qualifier注解,需要注意的是@Qualifier的参数名称必须为我们之前定义@Service注解的名称之一!
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "sessionFactory")
    @Primary
    @Override
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources(DruidConfig.MAPPER));
        return sessionFactory.getObject();
    }

    /**
     * 定义事务管理器
     * @param dataSource
     * @return
     */
    @Bean(name = "transactionManager")
    @Override
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

因为所有属性我们都是通过@value注入,只要在application.properties里面设置好了,我们只需要更改

//你的Mapper.java所在的报的位置,扫描这个包下的类
public static final String PACKAGE = "com.test.springbm.mapper";
//你的Mapper.xml的位置,classpath是相对路径,*Mapper.xml表示所有以Mapper结尾的xml
public static final String MAPPER = "classpath:/mapper/*Mapper.xml";

这两个属性就行

接下来我们可以开启druid监控

首先新建配置文件druid-monitor.properties进行配置

# 是否启用StatFilter默认值true
spring.datasource.druid.web-stat-filter.enabled=true
# 多个白名单IP以逗号分隔
druid.monitor.allow=127.0.0.1
# 多个黑名单IP以逗号分隔--跟allow共同存在时,deny优先于allow
druid.monitor.deny=0.0.0.0
# druid监控管理界面登录帐号
druid.monitor.loginUsername=root
# druid监控管理界面登录密码
druid.monitor.loginPassword=root
# 是否开启重置数据功能
druid.monitor.resetEnable=false

新建

package com.test.springbm.monitor;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.test.springbm.config.impl.DruidConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = "classpath:config/druid-monitor.properties")
@EnableConfigurationProperties({DruidConfig.class})
public class DruidMonitorConfiguration {

    @Value("${spring.datasource.druid.web-stat-filter.enabled}")
    private String webStatFilterEnabled;
    @Value("${druid.monitor.allow}")
    private String allow;
    @Value("${druid.monitor.deny}")
    private String deny;
    @Value("${druid.monitor.loginUsername}")
    private String loginUsername;
    @Value("${druid.monitor.loginPassword}")
    private String loginPassword;
    @Value("${druid.monitor.resetEnable}")
    private String resetEnable;

    /**
     * 注册Servlet信息,配置监控视图
     * @return
     */
    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        servletRegistrationBean.addInitParameter("spring.datasource.druid.web-stat-filter.enabled",this.webStatFilterEnabled);
        servletRegistrationBean.addInitParameter("allow", this.allow);
        servletRegistrationBean.addInitParameter("deny", this.deny);
        servletRegistrationBean.addInitParameter("loginUsername", this.loginUsername);
        servletRegistrationBean.addInitParameter("loginPassword", this.loginPassword);
        servletRegistrationBean.addInitParameter("resetEnable", this.resetEnable);
        return servletRegistrationBean;
    }

    /**
     * 注册Filter信息,监控拦截器
     * @return
     */
    @Bean
    public FilterRegistrationBean druidStatFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //拦截url类型,*表示拦截所有请求
        filterRegistrationBean.addUrlPatterns("/*");
        //忽略资源
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

在这里只需要引入你的配置文件和上面的DruidConfig.java的字节码文件
@PropertySource(value = "classpath:config/druid-monitor.properties") @EnableConfigurationProperties({DruidConfig.class})

到这里就结束Druid的配置了

进行访问Druid监控页面

访问
http://localhost:8080/druid/login.html
出现Druid监控的登录页面在这里插入图片描述
恭喜你,配置成功

结束

猜你喜欢

转载自blog.csdn.net/burmem/article/details/89281430