一、Spring Boot Data Access
Spring Boot默认使用Spring Data对SQL和NoSQL进行统一的访问处理,并添加了自动大量的自动配置,引入XxxTemplate如JdbcTemplate、RedisTemplate以及XxxRepository如JpaRepository、CrudRepository等来简化对数据访问层的操作,只需要进行简单的配置即可实现。
Spring Data的模块划分,查看官网
Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.
It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services.
Spring Data的使命是为数据访问提供熟悉且一致的基于Spring的编程模型,同时仍保留底层数据存储的特殊特性。使数据访问技术,关系数据库和非关系数据库,map-reduce框架和基于云的数据服务变得简单易用。
Spring Boot 中关于 Spring Data的starters
二、Integrate Spring Data JDBC
Spring Boot 默认数据源
创建项目spring-boot-data,引入JDBC依赖和MySQL依赖
在application.yml配置文件中增加数据库连接配置
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root url: jdbc:mysql://localhost.com:3306/test 复制代码
在test包下的DataApplicationTests类中增加测试方法testGetConnection(),测试获取数据源
@SpringBootTest public class DataApplicationTests { @Autowired private DataSource dataSource; @Test public void testGetConnection() throws SQLException { System.out.println("数据源类型为:" + dataSource.getClass()); Connection connection = dataSource.getConnection(); System.out.println("获取到到数据库连接为:" + connection); connection.close(); } } 复制代码
执行测试
成功获取到HikarPool数据源。
自动配置原理
数据源相关的配置都在DataSourceProperties类中。数据源的自动配置类是 org.springframework.boot.autoconfigure.jdbc DataSourceAutoConfiguration
Spring Boot默认支持的数据源有
- com.zaxxer.hikari.HikariDataSource
- org.apache.tomcat.jdbc.pool.DataSource
- org.apache.commons.dbcp2.BasicDataSource
- oracle.ucp.jdbc.PoolDataSource
DataSourceConfiguration类可以根据配置创建以上数据源,配置spring.datasource.type指定数据源,默认的数据源为HikariDataSource,如果配置的数据源不是以上这些数据源,则会通过Generic静态类的dataSource方法往容器中注入自定义的数据源。
源码中initializeDataSourceBuilder方法返回一个DataSourceBuilder
而DataSourceBuilder的builder方法通过反射创建出数据源,并将自定义数据源的properties属性和数据源进行绑定
DataSourceInitializer初始化数据
Spring Boot支持在应用启动时初始化数据。
首先创建一个自定义的DataSourceInitializerConfig类,该类是一个配置类需要标注@Configuration标签,需要通过该配置类往容器中导入一个绑定了数据源和SQL脚本的DataSourceInitializer初始化类。
@Configuration public class LilithDataSourceInitializerConfig { @Value("classpath:porsche.sql") private Resource script; @Bean public DataSourceInitializer dataSourceInitializer(final DataSource dataSource){ final DataSourceInitializer initializer = new DataSourceInitializer(); initializer.setDataSource(dataSource); initializer.setDatabasePopulator(databasePopulator()); return initializer; } private DatabasePopulator databasePopulator(){ final ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); populator.addScripts(script); //populator.setSeparator("$$"); return populator; } } 复制代码
在resource目录下放置porsche.sql
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for porsche -- ---------------------------- DROP TABLE IF EXISTS `porsche`; CREATE TABLE `porsche` ( `por_id` int(11) NOT NULL AUTO_INCREMENT, `por_name` char(100) CHARACTER SET gb2312 COLLATE gb2312_chinese_ci DEFAULT NULL, `por_price` double DEFAULT NULL, `por_stock` int(11) DEFAULT NULL, PRIMARY KEY (`por_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=gb2312; -- ---------------------------- -- Records of porsche -- ---------------------------- BEGIN; INSERT INTO `porsche` VALUES (2, 'Cayenne', 910000, 30); INSERT INTO `porsche` VALUES (3, 'Macan', 550000, 40); INSERT INTO `porsche` VALUES (4, 'Taycay 2022', 880000, 50); INSERT INTO `porsche` VALUES (5, 'Porsche 911', 1270000, 40); INSERT INTO `porsche` VALUES (6, 'Porsche 718', 540000, 70); INSERT INTO `porsche` VALUES (7, '918 Spyder', 13380000, 10); INSERT INTO `porsche` VALUES (8, 'Cayman', 720000, 30); INSERT INTO `porsche` VALUES (9, 'Boxster', 670000, 110); INSERT INTO `porsche` VALUES (10, 'Carrera GT', 6450000, 20); INSERT INTO `porsche` VALUES (11, 'Taycan Tubo S', 880000, 140); INSERT INTO `porsche` VALUES (12, 'Taycan 2023', 880000, 120); COMMIT; SET FOREIGN_KEY_CHECKS = 1; 复制代码
启动主程序,通过查看数据库可以确定程序启动时自动执行了指定的SQL脚本,需要注意的是每次程序启动都会重新初始化数据库,如果不想这样只需要将@Configuration注解注释即可。
测试初始化数据
Spring Boot数据源自动配置了JdbcTemplate,可以使用JdbcTemplate访问数据库
@Data public class Porsche { private Integer porId; private String porName; private Double porPrice; private Integer porStock; } 复制代码
增加PorscheMapper类,新增selectAll方法
@Component public class PorscheMapper { @Autowired private JdbcTemplate jdbcTemplate; public List<Map<String, Object>> selectAll(){ List<Map<String, Object>> maps = jdbcTemplate.queryForList("SELECT * FROM porsche"); return maps; } } 复制代码
在test包下增加PorscheMapperTest测试类
@SpringBootTest public class PorscheMapperTest { @Autowired private PorscheMapper porscheMapper; @Test public void selectAll() { List<Map<String, Object>> maps = porscheMapper.selectAll(); for (Map<String, Object> map : maps) { System.out.println(map); } } } 复制代码
执行测试
可以成功查出所有的数据
三、第三方数据源
Druid数据源配置
druid拥有成套的解决方案,如监控等,如何配置使用Druid数据源?
首先在pom文件中添加druid Staters
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.8</version> </dependency> 复制代码
执行testGetConnection
debug查看设置的属性有没有生效
druid 配置
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root url: jdbc:mysql://localhost:3306/test druid: # 初始化大小,最小,最大 initial-size: 5 max-active: 100 min-idle: 1 # 配置获取连接等待超时的时间 max-wait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒 time-between-eviction-runs-millis: 60000 # 配置一个连接在池中最小生存时间 min-evictable-idle-time-millis: 300000 # 用来检测连接是否有效的sql 必须是一个查询语句 注意没有此语句以下三个属性不会生效 validation-query: SELECT 1 FROM DUAL # 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true test-on-return: false # 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true test-on-borrow: true # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 test-while-idle: true # 配置监控统计拦截的 Filter,去掉后监控界面 SQL 无法统计,wall 用于防火墙 filters: stat,wall # 通过 connection-properties 属性打开 mergeSql 功能;慢 SQL 记录 connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 配置 DruidStatFilter web-stat-filter: enabled: true url-pattern: /* exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/* # 配置 DruidStatViewServlet stat-view-servlet: url-pattern: /druid/* # IP 白名单,没有配置或者为空,则允许所有访问 #allow: 127.0.0.1 # IP 黑名单,若白名单也存在,则优先使用 #deny: 192.168.31.253 # 禁用 HTML 中 Reset All 按钮 reset-enable: true # 登录用户名/密码 login-username: root login-password: 123 # 注意 此处必须开启,否则无法访问druid监控面板 enabled: true use-global-data-source-stat: true 复制代码
Druid自动配置原理
com.alibaba.druid.spring.boot.autoconfigure包中包含了Druid的自动配置类DruidDataSourceAutoConfigure
该自动配置类启用了DataSourceProperties和DruidStatProperties配置类中的配置
durid所有配置都是以spring.datasource或者spring.datasource.druid开头,这两个配置类中包含了druid在properties配置文件或者yml配置文件中的配置项
Druid 监控
输入地址 http://localhost:8080/druid/index.html 会显示登录界面,输入设置的用户名密码即可进入监控界面
新建controller包,增加PorscheController
@RestController public class PorscheController { @Autowired private PorscheMapper porscheMapper; @GetMapping("/porsche") public Map<String,Object> query(){ List<Map<String, Object>> maps = porscheMapper.selectAll(); return maps.get(0); } } 复制代码
浏览器输入 http://localhost:8080/porsche,页面显示出查询到的信息
查看Druid的SQL监控界面
plus:执行test包下的测试类执行的SQL不会被druid监控