一、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配置文件中增加数据库连接配置
代码语言:javascript复制spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost.com:3306/test
在test包下的DataApplicationTests类中增加测试方法testGetConnection(),测试获取数据源
代码语言:javascript复制@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初始化类。
代码语言:javascript复制@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
代码语言:javascript复制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访问数据库
代码语言:javascript复制@Data
public class Porsche {
private Integer porId;
private String porName;
private Double porPrice;
private Integer porStock;
}
增加PorscheMapper类,新增selectAll方法
代码语言:javascript复制@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测试类
代码语言:javascript复制@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
代码语言:javascript复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
执行testGetConnection
debug查看设置的属性有没有生效
druid 配置
代码语言:javascript复制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
代码语言:javascript复制@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监控