2 Druid 数据源连接池配置
我们还可以在 Spring Boot 的配置文件中对 Druid 数据源连接池进行配置,示例代码如下
################################################## Druid连接池的配置 ########################################## spring: datasource: druid: initial-size: 5 #初始化连接大小 min-idle: 5 #最小连接池数量 max-active: 20 #最大连接池数量 max-wait: 60000 #获取连接时最大等待时间,单位毫秒 time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 min-evictable-idle-time-millis: 300000 #配置一个连接在池中最小生存的时间,单位是毫秒 validation-query: SELECT 1 FROM DUAL #测试连接 test-while-idle: true #申请连接的时候检测,建议配置为true,不影响性能,并且保证安全性 test-on-borrow: false #获取连接时执行检测,建议关闭,影响性能 test-on-return: false #归还连接时执行检测,建议关闭,影响性能 pool-prepared-statements: false #是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭 max-pool-prepared-statement-per-connection-size: 20 #开启poolPreparedStatements后生效 filters: stat,wall #配置扩展插件,常用的插件有=>stat:监控统计 wall:防御sql注入 connection-properties: 'druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000' #通过connectProperties属性来打开mergeSql功能;慢SQL记录
3 Druid 监控配置
我们还可以在 Spring Boot 的配置文件中对 Druid 内置监控页面、Web-JDBC 关联监控和 Spring 监控等功能进行配置,示例代码如下
###################################################### Druid 监控配置信息 ########################################## spring: datasource: druid: # StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置 stat-view-servlet: enabled: true #是否开启内置监控页面,默认值为 false url-pattern: '/druid/*' #StatViewServlet 的映射路径,即内置监控页面的访问地址 reset-enable: true #是否启用重置按钮 login-username: admin #内置监控页面的登录页用户名 username login-password: admin #内置监控页面的登录页密码 password # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter web-stat-filter: enabled: true #是否开启内置监控中的 Web-jdbc 关联监控的数据 url-pattern: '/*' #匹配路径 exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' #排除路径 session-stat-enable: true #是否监控session # Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置 aop-patterns: com.example.* #Spring监控AOP切入点,如x.y.z.abc.*,配置多个英文逗号分隔
配置完内置监控后我们访问http://localhost:8080/druid
,输入配置的用户名和密码:
即可进入到监控页面:
当然这里我们开启了SQL监控,所以添加一个Controller进行一下测试:
package com.example.springboot.controller; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; @Controller public class IndexController { //自动装配 jdbcTemplate @Resource JdbcTemplate jdbcTemplate; /** * 访问"/testSql",访问数据库 * @return */ @ResponseBody @GetMapping("/getPersonCount") public String testSql() { String SQL = "SELECT count(*) from `person`"; Integer integer = jdbcTemplate.queryForObject(SQL, Integer.class); return integer.toString(); } }
请求一下:
然后观察下监控的变化,发现SQL语句被监控到了
同时URI地址监控也监控到了请求信息:
4 Druid 内置 Filter 配置
Druid Spring Boot Starter 对以下 Druid 内置 Filter,都提供了默认配置:StatFilter,WallFilter,ConfigFilter,EncodingConvertFilter,Slf4jLogFilter,Log4jFilter,Log4j2Filter,CommonsLogFilter
:
- 可以通过
spring.datasource.druid.filters=stat,wall ...
的方式来启用相应的内置 Filter - 如果默认配置不能满足我们的需求,我们还可以在配置文件使用
spring.datasource.druid.filter.*
对这些 Filter 进行配置
示例代码如下
# ####################################################### Druid 监控配置信息 ########################################## spring: datasource: druid: # 对配置已开启的 filters 即 stat(sql 监控) wall(防火墙) filter: #配置StatFilter (SQL监控配置) stat: enabled: true #开启 SQL 监控 slow-sql-millis: 1000 #慢查询 log-slow-sql: true #记录慢查询 SQL #配置WallFilter (防火墙配置) wall: enabled: true #开启防火墙 config: update-allow: true #允许更新操作 drop-table-allow: false #禁止删表操作 insert-allow: true #允许插入操作 delete-allow: true #删除数据操作
在配置 Druid 内置 Filter 时,需要先将对应 Filter 的 enabled 设置为 true,否则内置 Filter 的配置不会生效
SpringBoot整合MyBatis
我们之前在SSM框架整合中了解过如何通过Spring整合MyBatis,那么SpringBoot既然要简化,也需要整合MyBatis,MyBatis 也开发了一套基于 Spring Boot 模式的 starter:mybatis-spring-boot-starter
1 引入mybatis-spring-boot-starter场景启动器
Spring Boot 整合 MyBatis 的第一步,就是在项目的 pom.xml 中引入 mybatis-spring-boot-starter
的依赖
使用当前最新版本:
<!--引入 mybatis-spring-boot-starter 的依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency>
2 配置 MyBatis
在 Spring Boot 的配置文件(application.properties/yml)中对 MyBatis 进行配置,例如指定 mapper.xml 的位置、实体类的位置、是否开启驼峰命名法等等
###################################### MyBatis 配置###################################### mybatis: # 指定 mapper.xml 的位置 mapper-locations: classpath:mapper/*.xml #扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名 type-aliases-package: com.example.model configuration: #默认开启驼峰命名法,可以不用设置该属性 map-underscore-to-camel-case: true
使用 MyBatis 时,必须配置数据源信息,例如数据库 URL、数据库用户型、数据库密码和数据库驱动等,也就是我们前面的数据库驱动相关配置:
#数据源连接信息 spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver
3 创建实体类
我们在model包下创建Person这个实体类用来映射数据表,也就是创建PO
代码如下:
package com.example.springboot.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /* * person表对应对象 * */ @Data @AllArgsConstructor @NoArgsConstructor public class Person { private int id; private String username; private String password; private int age; private int phone; private String email; private String hobby; }
4 PersonDao接口创建
在dao包下创建一个PersonDao接口,用来写接口方法:
package com.example.springboot.dao; import com.example.springboot.model.Person; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface PersonDao { List<Person> getPersonList(); }
5 personMapper.xml映射文件编写
在资源路径下的mapper文件夹添加personMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace=绑定一个指定的Dao/Mapper接口--> <mapper namespace="com.example.springboot.dao.PersonDao"> <select id="getPersonList" resultType="com.example.springboot.model.Person"> select * from person </select> </mapper>
6 测试访问数据库
我们写个单元测试访问下数据库:
package com.example.springboot; import com.example.springboot.dao.PersonDao; import com.example.springboot.model.Person; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import javax.sql.DataSource; import java.sql.SQLException; import java.util.List; @SpringBootTest class SpringbootApplicationTests { //数据源组件 @Resource DataSource dataSource; @Resource PersonDao personDao; @Test void testMyBatis() throws SQLException { System.out.println("默认数据源为:" + dataSource.getClass()); System.out.println("数据库连接实例:" + dataSource.getConnection()); //访问数据库 List<Person> personList=personDao.getPersonList(); System.out.println(personList); } }
打印结果如下:
还记得我们在之前的SSM整合中还有两个重要配置,这里没有出现,一个是MyBatis的核心配置文件
另外一个是Spring整合MyBatis的配置文件
其实可以看的出,SpringBoot做了一个大一统,数据源连接池选什么?数据库驱动信息选哪些?都是可以选配的,而在yml配置文件中由于有了自动配置,配置和容器注入也进行了分离,使我们的配置视角更加单纯,只关注配置信息,别的starter都帮我们做好了,简单看下代码:
MyBatis-Spring-Boot-Starter 将会完成以下功能:
- 自动发现存在的DataSource
- 利用SqlSessionFactoryBean创建并注册SqlSessionFactory
- 创建并注册SqlSessionTemplate
- 自动扫描Mappers,并注册到Spring上下文环境方便程序的注入使用
默认情况下,MyBatis-Spring-Boot-Starter会查找以@Mapper注解标记的映射器,所以这也就解释了为什么我们不需要那些额外的配置了,场景启动器都帮我们做好了。
整体yml文件配置清单
我们一步步从JDBC到连接池Druid到MyBatis整合到了SpringBoot中,返回来看看我们全部的yml配置内容吧:
#数据源连接信息 spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/test?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver ################################################## Druid连接池的配置 ########################################## druid: initial-size: 5 #初始化连接大小 min-idle: 5 #最小连接池数量 max-active: 20 #最大连接池数量 max-wait: 60000 #获取连接时最大等待时间,单位毫秒 time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 min-evictable-idle-time-millis: 300000 #配置一个连接在池中最小生存的时间,单位是毫秒 validation-query: SELECT 1 FROM DUAL #测试连接 test-while-idle: true #申请连接的时候检测,建议配置为true,不影响性能,并且保证安全性 test-on-borrow: false #获取连接时执行检测,建议关闭,影响性能 test-on-return: false #归还连接时执行检测,建议关闭,影响性能 pool-prepared-statements: false #是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭 max-pool-prepared-statement-per-connection-size: 20 #开启poolPreparedStatements后生效 filters: stat,wall #配置扩展插件,常用的插件有=>stat:监控统计 wall:防御sql注入 connection-properties: 'druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000' #通过connectProperties属性来打开mergeSql功能;慢SQL记录 ###################################################### Druid 监控配置信息 ########################################## # StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置 stat-view-servlet: enabled: true #是否开启内置监控页面,默认值为 false url-pattern: '/druid/*' #StatViewServlet 的映射路径,即内置监控页面的访问地址 reset-enable: true #是否启用重置按钮 login-username: admin #内置监控页面的登录页用户名 username login-password: admin #内置监控页面的登录页密码 password # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter web-stat-filter: enabled: true #是否开启内置监控中的 Web-jdbc 关联监控的数据 url-pattern: '/*' #匹配路径 exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' #排除路径 session-stat-enable: true #是否监控session # Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置 aop-patterns: net.biancheng.www.* #Spring监控AOP切入点,如x.y.z.abc.*,配置多个英文逗号分隔 ######################################################## Druid 监控配置信息 ########################################## # 对配置已开启的 filters 即 stat(sql 监控) wall(防火墙) filter: #配置StatFilter (SQL监控配置) stat: enabled: true #开启 SQL 监控 slow-sql-millis: 1000 #慢查询 log-slow-sql: true #记录慢查询 SQL #配置WallFilter (防火墙配置) wall: enabled: true #开启防火墙 config: update-allow: true #允许更新操作 drop-table-allow: false #禁止删表操作 insert-allow: true #允许插入操作 delete-allow: true #删除数据操作 ###################################### MyBatis 配置###################################### mybatis: # 指定 mapper.xml 的位置 mapper-locations: classpath:mapper/*.xml #扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名 type-aliases-package: com.example.springboot.model configuration: #默认开启驼峰命名法,可以不用设置该属性 map-underscore-to-camel-case: true
总结一下
其实本篇Blog涉及了三个数据相关的整合:JDBC+Druid+MyBatis,那么这三个有什么区别呢?我们平时是如何组合使用呢?
- JDBC:其实是一套标准和规范,最原始的数据库操作方式,负责:加载数据库驱动,创建连接,写原生语句,执行,关闭连接
- Druid:光有JDBC太简单了,我们需要连接池来解决高并发场景下的性能问题,这个时候就需要一些数据源工具,例如Druid,它是对JDBC的一些简单封装,最主要的就是连接池的加入,Druid可以创建很多的数据库连接放到连接池里供MyBatis使用
- MyBatis:MyBatis是对JDBC的封装,一个半自动的ORM框架,和JDBC的对比我在之前的Blog详细提到过,说白了就是一个方便我们使用的框架,MyBatis在让JDBC更好用的基础上还可以灵活驱动Druid提供的连接去进行操作。
那么这三者是如何配合工作的呢?
- 项目启动时Druid就已经使用JDBC创建好一堆连接留待后用
- 当请求到mapper(Dao)时,MyBatis框架创建临时类,并且将动态sql进行替换重写变成原始的native sql
- MyBatis从Druid拿到一个连接,将sql通过连接交给数据库执行,获取执行结果,最终将结果进行映射并返回数据
也就是MyBatis替我们选好了数据源(Druid),并且实际上最终调用JDBC原生方法执行数据操作。