最近把一个项目的框架由 SpringMVC 转为 Spring Boot,顺便作为学习 Spring Boot 的入门实践。框架的使用入门很快,尤其是 Spring Boot 其实相当于对 SpringMVC 做了一些改进,去除配置,改为代码约定。
但是,没了配置,第三方库如何集成进来就是 Spring Boot 入门学习遇到的第一个坎,尤其是一些没有官方支持 Spring Boot 的库。我把我的项目框架转为 Spring Boot 的时候,就遇到了 Druid 和 Mybatis 集成的问题,Mybatis 有支持 Spring Boot 的包,Druid 没有,所以 Druid 的集成就略显麻烦一点。我搜索了很多其他人写的相关 Blog,结果发现很多人要么是互相抄,要么是语焉不详,只是贴出大版的代码,你照抄他的代码虽然也能集成成功,但是你只知其然,不知其所以然,或者有些代码根本是不必要的。
在走了不少弯路以及持续改进后,我最终以比较满意的结果集成 Druid + Mybatis,为此记录下来,作为个人对近期 Spring Boot 学习总结。本文是针对如何在 Spring Boot 中集成 Druid 和 Mybatis,所以读者必须先熟悉 Spring Boot、Druid 和 Mybatis,对于这三者的细节,不再展开描述。
引入 Druid 和 Mybatis包:
在项目 pom.xml 文件中,引入这两个库的 jar 包,其中数据库我是用 MySQL,所以我同时也引入了 MySQL 的驱动 jar 包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.5</version> </dependency>
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency>
|
集成 Druid:
Druid 是数据库连接池,负责管理数据库的连接,给Mybatis、JPA提供数据库的连接,所以先集成他进来。
首先在 Spring Boot 的配置文件中,配置好数据源的各种参数,我的配置文件使用的是 yml,如果你的配置文件为 Properties,请更换为对应的格式即可,我的配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test username: 数据库用户名 password: 数据库密码 initialSize: 3 minIdle: 3 maxActive: 30 maxWait: 15000 timeBetweenEvictionRunsMillis: 120000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 'x' validationQueryTimeout: 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: false maxPoolPreparedStatementPerConnectionSize: 20 removeAbandoned: true removeAbandonedTimeoutMillis: 20000 logAbandoned: true logDifferentThread: true filters: log4j,stat connectionProperties: druid.stat.mergeSql=true;druid.stat.logSlowSql=true;druid.stat.slowSqlMillis=3000 useGlobalDataSourceStat: true druidRegistrationUrl: /druid/* resetEnable: true loginUsername: 监控后台登录名称 loginPassword: 监控后台登录密码 filtersUrlPatterns: /* exclusions: '*.js,*.gif,*.jpg,*.jpeg,*.png,*.css,*.ico,*.jsp,/druid/*' sessionStatMaxCount: 2000 sessionStatEnable: true principalSessionName: session_user_key profileEnable: true
|
以上配置参数写好后,Druid 并未按照我们配置的参数进行初始化,因为 Druid 官方并未去实现相关代码,所以我们要自己去实现。
创建一个 DruidConfig 类,我们在这个类中获取配置文件里面的 spring.datasource 中配置的数据,通过 @Component 和 @ConfigurationProperties(prefix = “spring.datasource”) 注解,获取到了配置文件中的配置参数代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @Component @ConfigurationProperties(prefix = "spring.datasource") public class DruidConfig { private final Logger logger = LoggerFactory.getLogger(DruidConfig.class);
private String driverClassName; private String url; private String username; private String password; private int initialSize; private int minIdle; private int maxActive; private long maxWait; private long timeBetweenEvictionRunsMillis; private long minEvictableIdleTimeMillis; private String validationQuery; private boolean testWhileIdle; private boolean testOnBorrow; private boolean testOnReturn; private boolean poolPreparedStatements; private int maxPoolPreparedStatementPerConnectionSize; private long removeAbandonedTimeoutMillis; private boolean removeAbandoned; private boolean logAbandoned; private boolean logDifferentThread; private String filters; private String connectionProperties; private boolean useGlobalDataSourceStat;
private String druidRegistrationUrl; private boolean resetEnable; private String loginUsername; private String loginPassword;
private String filtersUrlPatterns; private String exclusions; private int sessionStatMaxCount; private boolean sessionStatEnable; private String principalSessionName; private boolean profileEnable;
…… setter & getter }
|
紧接着就是根据参数,创建 DruidDataSource 了,在 DruidConfig 中,创建一个方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @Bean(initMethod = "init", destroyMethod = "close") @Primary public DruidDataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClassName); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); dataSource.setInitialSize(initialSize); dataSource.setMinIdle(minIdle); dataSource.setMaxActive(maxActive); dataSource.setMaxWait(maxWait); dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); dataSource.setValidationQuery(validationQuery); dataSource.setTestWhileIdle(testWhileIdle); dataSource.setTestOnBorrow(testOnBorrow); dataSource.setTestOnReturn(testOnReturn); dataSource.setPoolPreparedStatements(poolPreparedStatements); dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); dataSource.setRemoveAbandonedTimeoutMillis(removeAbandonedTimeoutMillis); dataSource.setRemoveAbandoned(removeAbandoned); dataSource.setLogDifferentThread(logDifferentThread);
try { dataSource.setFilters(filters); } catch(SQLException e) { e.printStackTrace(); logger.error("Druid URL过滤设置失败", e); } dataSource.setConnectionProperties(connectionProperties); dataSource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
return dataSource; }
|
这个方法,就是告诉框架,数据源是由这个方法来提供,注解 @Primary 意思是告诉框架,如果开发者没有指定其他数据源,那么就默认调用这个方法来提供数据源。这一步进行完,其实 Druid 的最核心的配置已经进行完毕,可以使用 Druid 来给 Mybatis 或者 JPA 提供数据库连接了,下面的 Druid 监控可根据实际需求进行配置。
让 Druid 支持事务:通过上面的配置,虽然已经能提供数据库的连接来进行数据库操作了,但是开发过程中,除了调用 SQL,还会遇到调用数据库的事务,所以我们要让 Druid 支持事务才行,让 Druid 支持事务很简单,实现 Spring 的 TransactionManagementConfigurer 接口,重写该接口下的 annotationDrivenTransactionManager 方法,在这个方法里面给 DruidDataSource 开启事务,同时让这个类在 DruidConfig 被 Spring 加载之后,再去被 Spring 加载即可,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Configuration @EnableTransactionManagement @AutoConfigureAfter({DruidConfig.class}) @MapperScan(basePackages = {"Mybatis 的 DAO 接口所在的包路径"}) public class TransactionConfig implements TransactionManagementConfigurer { @Autowired private DruidDataSource mDataSource;
@Override public PlatformTransactionManager annotationDrivenTransactionManager() { return new DataSourceTransactionManager(mDataSource); } }
|
配置 Druid 监控页面。Druid 提供了数据库链接状态和 SQL 执行的页面,方便开发者查看自己的程序的数据库连接与操作状态,这个监控后台的页面 Servlet 是 StatViewServlet,我们配置好他,就能打开监控后台查看数据了,在 DruidConfig 中,新增一个如下的方法:
1 2 3 4 5 6 7 8 9
| @Bean public ServletRegistrationBean druidServlet() { ServletRegistrationBean servletBean = new ServletRegistrationBean(new StatViewServlet(), druidRegistrationUrl); servletBean.addInitParameter("resetEnable", String.valueOf(resetEnable)); servletBean.addInitParameter("loginUsername", loginUsername); servletBean.addInitParameter("loginPassword", loginPassword);
return servletBean; }
|
添加这个方法后,重新启动项目,你就能在浏览器中输入 项目URL/你配置的Druid监控后台路径(就是上面druidRegistrationUrl变量) 来访问到 Druid 的监控后台了。
- 现在是可以访问 Druid 的监控后台了,但是这样的配置不完美,还需要给监控后台加上一些过滤,避免一些没必要的资源和页面被统计进去,所以我们还要配置一个 WebStatFilter,关于 WebStatFilter 的配置参数,请查阅相关文档,我这里只是部分配置参数。我们在 DruidConfig 中,新增一个如下的方法:
1 2 3 4 5 6 7 8 9 10 11 12
| @Bean public FilterRegistrationBean filterRegistration() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); filterRegistrationBean.addUrlPatterns(filtersUrlPatterns); filterRegistrationBean.addInitParameter("exclusions", exclusions); filterRegistrationBean.addInitParameter("sessionStatMaxCount", String.valueOf(sessionStatMaxCount)); filterRegistrationBean.addInitParameter("sessionStatEnable", String.valueOf(sessionStatEnable)); filterRegistrationBean.addInitParameter("principalSessionName", principalSessionName); filterRegistrationBean.addInitParameter("profileEnable", String.valueOf(profileEnable));
return filterRegistrationBean; }
|
至此,Druid 的配置已全部完成。
集成 Mybatis:
Mybatis 的集成就要比 Druid 简单很多,因为我们引入的 org.mybatis.spring.boot 得包,已经帮我们实现了类似于 DruidConfig 的配置类了

所以我们只要在 Spring Boot 中配置好 Mybatis 的参数,写好你的 DAO 和 Service(如果你的 Mybatis 是使用 xml 来写 SQL 方式,就不用实现 Service,如果是注解,就要实现 DAO 的 Service),然后就能使用 Mybatis 了,配置如下,在你的 Spring Boot 中写上如下配置,注意,配置的参数要换上自己的,别照搬代码又不改成自己的参数,然后调用 Mybatis 进行操作发生异常时一头雾水:
1 2 3 4
| mybatis: config-location: classpath:/db/mybatis-config.xml mapper-locations: classpath:/db/mappers*Mapper.xml type-aliases-package: com.java.springboot.db.entity
|
结尾
至此,Spring Boot 集成 Druid 和 Mybatis 的工作已完成,至于里面的各个参数是什么意思,如何优化,不在本文范围之内,该文只说如何集成。如果文中有任何错误、改进方式,欢迎一起探讨。