SpringBoot整合JDBC、Druid
对于数据访问层,无论是SQL(关系型数据库)还NOSQL(非关系型数据库),SpringBoot底层采用的事SpringData的方式进行统一处理。SpringData在spring全家桶中也是和SpringBoot、SpringCloud等齐名的项目。
springboot整合数据库的话,需要的启动器jar包如下,都是和data有关的
1、SpringBoot整合JDBC
1.1、知识补充:数据源和数据库连接池
Java中的数据源就是javax.sql.DataSource。DataSource的创建可以有不同的实现。DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池。
JNDI
方式创建DataSource: (Java Naming and Directory Interface,Java命名和目录接口)。首先要配置数据源的相关连接信息,也就是数据源连接池。该配置应该在Tomcat安装目录下的conf/context.xml文件中配置。
连接池基本的思想原理:
- 在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。
- 数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
连接池通俗理解:
数据库连接池就是准备一个池子,里面放着很多生成好的Connection,用户请求获得连接,就不需要getConnection,只要从池子里拿一个给他就行了,这样省掉了生成Connection的时间,效率上会有很大提高,不过当然会占用一些内存,稍微大点网站都会用到数据库连接池的~
数据库连接池技术的优点:
- 资源重用
- 更快的系统反应速度
- 新的资源分配手段
- 统一的连接管理,避免数据库连接泄露
综上:
- 配置一个数据库连接就是配置一些账户、密码、数据库url等。
- 配置一个数据库连接池就是批量配置这些多个数据库连接【方便】
1.2、导入JDBC场景
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
点击该jdbc场景源码:通过查看依赖,我们可以看见通过导入jdbc场景,SpringBoot给我们自动导入了数据源、数据库操作、事务管理等配置。
但是从上容易发现:为什么导入了JDBC场景,官方为何不导入数据库的驱动?因为
- 官方不知道我们接下要操作什么数据库。
- 我们在导入数据库驱动时,要注意导入的数据库驱动与本机的数据库版本对应。(高版本mysql驱动向下兼容)
1.3、导入数据库驱动包(MySQL为例)
mysql自动仲裁的版本:默认最新版本,这里是8.0的版本
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
但是如果想要改变版本[数据库版本应该和驱动版本一样]:有下面两种方式【maven的时候讲过】
- 直接依赖引入具体版本(maven的就近依赖原则)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version> //直接写上,最短路径优先
</dependency>
- 重新声明版本(maven的属性的就近优先原则)
<properties>
<java.version>1.8</java.version>
<mysql.version>5.1.49</mysql.version>
</properties>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
补充: 可以在创建SpringBoot工程的时候,提前选择好JDBC和Mysql driver的场景
1.4、相关数据源自动配置类分析
进入jdbc的依赖包:可以看见如下信息
DataSourceAutoConfiguration
: 数据源的自动配置。
- 修改数据源相关的配置:
spring.datasource
开头的配置 - 数据库连接池的配置,是自己容器中没有DataSource才自动配置的。
- 底层自动配置好的连接池是:
HikariDataSource
- DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置。
- JdbcTemplateAutoConfiguration: JdbcTemplate的自动配置(spring用来操作数据库的一个小组件),可以来对数据库进行CRUD。
- 可以修改前缀为spring.jdbc的配置项【@ConfigurationProperties(prefix = “spring.jdbc”)】来修改JdbcTemplate。
spring:
jdbc:
query-timeout: 3
- @Bean @Primary JdbcTemplate:Spring容器中有这个JdbcTemplate组件,使用@Autowired自动注入
-
JndiDataSourceAutoConfiguration
: JNDI的自动配置。 -
XADataSourceAutoConfiguration
: 分布式事务相关的。
1.5、修改配置项,配置数据源
spring:
datasource:
url: jdbc:mysql://localhost:3306/runoob?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
注意:mysql8.0以上版本数据库连接配置:
- className发生了变更,现在为
com.mysql.cj.jdbc.Driver
- 8.0以上必须配置时区,应该是为了数据库的时间戳全球一致性serverTimezone=UTC ,否则会报错
driverClassName=com.mysql.cj.jdbc.Driver
#8.0版本Driver会标红,但是不影响
#serverTimezone-UTC表示在springboot中设置时区,才会不报错
#useUnicode-true&charac terEncoding=utf- 8表示:使用unicode和utf-8编码,防止乱码
url=jdbc:mysql://localhost:3306/project?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username=root
password=root
1.6、单元测试数据源【test目录下】
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Slf4j
@SpringBootTest
class Boot05WebAdminApplicationTests {
//springboot已经帮我们把大部分都配置好了,我们只需要配置少部分信息就可以实现连接数据库
//这里我们直接注入
@Autowired
DataSource dataSource ;
@Autowired
JdbcTemplate jdbcTemplate;
@Test//用@org.junit.Test会报空指针异常,可能跟JUnit新版本有关
void contextLoads() {
//jdbcTemplate.queryForObject("select * from account_tbl")
//jdbcTemplate.queryForList("select * from account_tbl",)
Long aLong = jdbcTemplate.queryForObject("select count(*) from account_tbl", Long.class);
log.info("记录总数:{}",aLong);
//查看数据源对象的class对象,即默认数据源对象
System.out.println(dataSource.getClass());
}
}
结果
2、自定义方式整合第三方数据源--druid
1、Druid是什么?
Java程序很大一部分需要操作数据库,为了提高操作数据库的性能,就不得不使用数据库连接池。Druid是阿里巴巴开源平台上的一个数据库连接池的实现,结合了C3P0、DBCP等DB池的优点,同时加入了日志监控。
Druid能很好的监控DB池连接和SQL的执行情况,是针对监控而生的连接池。SpringBoot2.0以上默认使用Hikari数据源,而Hikari和Druid都是当前JAVAweb上最优秀的数据源。
Druid官网:github.com/alibaba/dru…
官方文档 - Druid连接池介绍:
2、SpringBoot整合第三方druid连接池
- 找starter场景
官方文档 - Druid Spring Boot Starter:简化上述的配置
引入场景依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
分析自动配置:
- 扩展配置项 spring.datasource.druid
- 自动配置类DruidDataSourceAutoConfigure
- DruidSpringAopConfiguration.class, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
- DruidStatViewServletConfiguration.class, 监控页的配置。spring.datasource.druid.stat-view-servlet默认开启。
- DruidWebStatFilterConfiguration.class,web监控配置。spring.datasource.druid.web-stat-filter默认开启。
- DruidFilterConfiguration.class所有Druid的filter的配置:
private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";
private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";
private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";
private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";
private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";
private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";
private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";
private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";
配置数据源示例:这里我们没有用到上面的这些druid提供的监控配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/db_account
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
测试:写一个控制器,使用jdbc的方式获取一下信息:
package com.example.boot.controller;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class JdbcController {
@Resource
JdbcTemplate jdbcTemplate;
@GetMapping("/getCount")
public int getCount(){
String sql = "select count(*) from student";
Integer number = jdbcTemplate.queryForObject(sql, Integer.class);
return number;
}
}
3、配置Druid的监控页功能,开启sql监控、web防火墙功能:
yaml文件配置相应监控功能
spring:
datasource:
url: jdbc:mysql://localhost:3306/runoob?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: ajt19980607###
driver-class-name: com.mysql.jdbc.Driver
druid:
aop-patterns: com.lemon.admin.* #监控SpringBean
filters: stat,wall # 底层开启功能,stat(sql监控),wall(防火墙)
stat-view-servlet: # 配置监控页功能
enabled: true
login-username: admin
login-password: admin
resetEnable: false
web-stat-filter: # 监控web
enabled: true
urlPattern: /*
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
filter:
stat: # 对上面filters里面的stat的详细配置
slow-sql-millis: 1000
logSlowSql: true
enabled: true
wall:
enabled: true
config:
drop-table-allow: false
测试:
再次使用jdbc的方式获取一下信息:
package com.example.boot.controller;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class JdbcController {
@Resource
JdbcTemplate jdbcTemplate;
@GetMapping("/getCount")
public int getCount(){
String sql = "select count(*) from student";
Integer number = jdbcTemplate.queryForObject(sql, Integer.class);
return number;
}
}
配置好以后,启动服务器,打开地址:localhost:8080/druid/html
并利用配置的信息进行登录,就可以看到一些本次程序执行的信息
我们再看看Druid的监控: 他告诉了我们,那个网页我刷新了1次,执行时间用了165秒,最慢的一次用了165秒。读取的行数有1行。