目录
1. 数据源自动管理
1.1 引入jdbc的依赖和SpringBoot的应用场景
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
spring-boot-starter-jdbc直接依赖于HikariCP和spring-jdbc。
1.2 使用yaml方式配置
创建application.yaml
spring:
datasource:
username: root
password: 2020
url: jdbc:mysql://localhost:3306/boot_demo
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
在默认情况下, 数据库连接可以使用DataSource池进行自动配置
不同的数据库有不同的驱动程序,每个驱动程序都有对应的类名,而 driver-class-name 就是用来指定使用哪个数据库驱动类的。
- 如果Hikari可用, Springboot将使用它。
- 如果Commons DBCP2可用, 我们将使用它。
spring:
datasource:
username: root
password: 2020
url: jdbc:mysql://localhost:3306/boot_demo
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
# type: org.apache.commons.dbcp2.BasicDataSource
2.配置druid数据源
2.1 引入druid的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
2.2 修改yaml配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
在application.yaml中加入
spring:
datasource:
username: root
password: 2020
url: jdbc:mysql://localhost:3306/boot_demo
driver-class-name: com.mysql.jdbc.Driver
# type: com.zaxxer.hikari.HikariDataSource
# type: org.apache.commons.dbcp2.BasicDataSource
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
1. 连接池基本配置
- initialSize: 5:
- 该配置指定了连接池在初始化时创建的连接数量。设置为 5 意味着在应用启动时,Druid 连接池会创建 5 个数据库连接并放入连接池中。
- minIdle: 5:
- 它表示连接池保持的最小空闲连接数。即使在没有数据库操作时,连接池也会确保至少有 5 个连接处于空闲状态,这样可以避免在有新的数据库请求时频繁创建连接,提高响应速度。
- maxActive: 20:
- 此配置定义了连接池允许的最大活动连接数。当有数据库请求时,连接池最多可以同时提供 20 个连接给应用程序使用。如果达到这个上限,新的请求将等待,直到有连接被释放。
2. 链接获取和超时配置
- maxWait: 60000:
- 单位为毫秒,指的是当连接池中的连接都被占用时,新的请求等待获取连接的最大时间。这里设置为 60000 毫秒(即 60 秒),如果在 60 秒内没有可用连接,请求将抛出异常。
3. 连接池维护配置
- timeBetweenEvictionRunsMillis: 60000:
- 单位为毫秒,它表示连接池进行空闲连接检查的时间间隔。每隔 60000 毫秒(即 60 秒),连接池会执行一次空闲连接的检查操作。
- minEvictableIdleTimeMillis: 300000:
- 单位为毫秒,该配置规定了连接在连接池中保持空闲状态的最小时间,超过这个时间的空闲连接可能会被移除。这里设置为 300000 毫秒(即 5 分钟),意味着空闲时间超过 5 分钟的连接可能会被清理。
4. 链接有效性验证配置
- validationQuery: SELECT 1 FROM DUAL:
- 这是一个用于验证连接是否有效的 SQL 查询语句。对于不同的数据库,该语句可能不同,例如在 MySQL 中可以使用 SELECT 1。连接池会执行这个查询来检查连接是否正常。
- testWhileIdle: true:
- 当设置为 true 时,连接池在进行空闲连接检查时,会使用 validationQuery 来验证连接的有效性。如果连接无效,会将其从连接池中移除。
- testOnBorrow: false:
- 若设置为 true,在从连接池获取连接时,会先使用 validationQuery 验证连接的有效性,确保获取到的连接是可用的。这里设置为 false,表示不进行此验证。
- testOnReturn: false:
- 当设置为 true 时,在将连接归还到连接池时,会使用 validationQuery 验证连接的有效性。这里设置为 false,表示不进行此验证。
5. 预编译语句配置
- poolPreparedStatements: true:
- 当设置为 true 时,连接池会开启预编译语句缓存功能,这样可以提高预编译语句的执行效率,避免重复编译相同的 SQL 语句。
- maxPoolPreparedStatementPerConnectionSize: 20:
- 该配置指定了每个连接最多可以缓存的预编译语句数量。这里设置为 20,表示每个连接最多可以缓存 20 条预编译语句。
6. 监控和日志配置
- filters: stat,wall,log4j:
- 此配置指定了连接池使用的过滤器。stat 过滤器用于统计 SQL 执行的性能信息,wall 过滤器用于防止 SQL 注入攻击,log4j 过滤器用于将相关信息记录到日志中。
- useGlobalDataSourceStat: true:
- 当设置为 true 时,会使用全局的数据源统计信息,方便对整个应用的数据库连接和 SQL 执行情况进行统一监控。
- connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500:
- druid.stat.mergeSql=true 表示合并相同的 SQL 语句进行统计,这样可以减少统计数据的数量,提高统计效率。
- druid.stat.slowSqlMillis=500 表示将执行时间超过 500 毫秒的 SQL 语句标记为慢 SQL,并记录相关信息,方便后续进行性能优化。
2.3 创建数据源注册类
package com.qcby.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource(){
return new DruidDataSource();
}
}
代码解释:
把 DruidDataSource 实例注册成 Spring 应用上下文中的一个 Bean,这样一来,其他组件就能够通过依赖注入的方式获取这个数据源,进而进行数据库操作。
依赖注入:
传统的方式是在对象内部创建依赖对象,而依赖注入则是将依赖对象的创建和管理交给外部容器,由容器将依赖对象注入到需要的对象中。
常用的依赖注入的方式有构造函数的方法和通过setter方法注入,这里明显使用的是构造函数的方法注入依赖。
在配置类这里配置更灵活(在yml文件里配了为什么还要在配置类配置)。
2.4 配置druid运行期监控
package com.qcby.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource(){
return new DruidDataSource();
}
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
Map<String,String> initParams = new HashMap<>();
initParams.put("loginUsername","root");
initParams.put("loginPassword","root");
initParams.put("allow","");//默认就是允许所有访问
initParams.put("deny","192.168.43.195");
bean.setInitParameters(initParams);
return bean;
}
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean;
bean=new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams=new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
代码解释:
statViewServlet()解释:
statViewServlet方法的主要作用是配置并注册 Druid 监控页面的 Servlet,为访问 Druid 监控页面设置登录用户名、密码、允许访问的 IP 地址和拒绝访问的 IP 地址等参数。
ServletRegistrationBean 是 Spring 提供的一个类,用于在 Spring 应用中注册 Servlet。
"/druid/*":
指定 StatViewServlet 所映射的 URL 路径,意味着所有以 /druid/ 开头的请求都会被 StatViewServlet 处理。
"deny" 参数
用于指定拒绝访问 Druid 监控页面的 IP 地址。这里将 192.168.43.195 这个 IP 地址加入拒绝列表,即该 IP 无法访问 Druid 监控页面。
监控页面:
Druid 监控页面是 Druid 数据库连接池提供的一个可视化工具,主要用于监控和管理数据库连接池以及相关的数据库操作,具有以下功能:
- 连接池信息展示:可以显示数据库连接池的基本信息,如当前连接数、最大连接数、最小连接数、连接等待时间等。通过这些信息,管理员可以直观地了解连接池的使用情况,判断是否存在连接泄漏、连接不足等问题。
- SQL 执行监控:能够记录和展示应用程序执行的 SQL 语句,包括 SQL 的执行时间、执行次数、返回结果集大小等。这有助于开发人员和管理员分析 SQL 的性能,找出执行效率低下的 SQL 语句,进行优化以提高系统性能。
- 性能指标统计:提供各种性能指标的统计数据,如吞吐量、平均响应时间、SQL 执行成功率等。通过这些指标,可以评估系统的整体性能,及时发现性能瓶颈,并采取相应的措施进行调整和优化。
- 慢 SQL 查询分析:能够识别出执行时间较长的慢 SQL 查询,并详细展示其执行计划、耗时等信息。开发人员可以根据这些信息对慢 SQL 进行优化,例如调整查询语句、添加索引等,以提高系统的响应速度。
- 数据库连接状态监控:展示数据库连接的状态,如连接是否活跃、空闲时间等。可以帮助管理员及时发现异常连接,如长时间未释放的连接,从而避免资源浪费和潜在的系统问题。
- 应用系统信息关联:将数据库操作与应用系统的相关信息进行关联,如应用程序的线程信息、请求路径等。这有助于在出现问题时,快速定位到具体的应用代码位置,方便排查问题。
- 监控数据持久化:支持将监控数据持久化到数据库中,以便进行历史数据查询和分析。通过对历史数据的分析,可以了解系统性能的变化趋势,为容量规划和性能优化提供依据。
- 访问控制:提供访问控制功能,可以设置登录用户名和密码,限制对监控页面的访问权限,确保只有授权人员能够查看和操作监控信息,保证系统的安全性。
webStatFilter()解释
FilterRegistrationBean 是 Spring 框架提供的一个工具类,其用途是在 Spring 应用中注册 Servlet 过滤器。
bean.setFilter(new WebStatFilter());
调用 setFilter 方法,把 WebStatFilter 实例设置到 FilterRegistrationBean 中。WebStatFilter 是 Druid 提供的过滤器,可对 Web 应用的请求和响应进行拦截,进而收集统计信息。
"exclusions" 参数的作用是指定不需要被 WebStatFilter 拦截的请求路径。这里的 "*.js,*.css,/druid/*" 表明所有 .js 文件、.css 文件以及以 /druid/ 开头的请求都不会被拦截。
调用 setUrlPatterns 方法,把过滤器的 URL 匹配模式设置为 "/*",这意味着该过滤器会拦截所有的请求。不过,由于前面配置了 exclusions 参数,部分请求不会被实际拦截。
打开监控页面
3. SpringBoot整合jdbcTemplate
JdbcTemplate的特点
- 速度快,相对于ORM框架,JDBC的方式是最快的。
- 配置简单,Spring封装的,除了数据库连接之外,几乎没有额外的配置。
- 使用方便,就像DBUtils工具类,只需注入JdbcTemplate对象即可。
JdbcTemplate虽然简单,功能却非常强大。它提供了非常丰富、实用的方法,归纳起来主要有以下几种类型的方法:
(1)execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句。
(2)update、batchUpdate方法:用于执行新增、修改与删除等语句。
(3)query和queryForXXX方法:用于执行查询相关的语句。
(4)call方法:用于执行数据库存储过程和函数相关的语句。
总的来说,新增、删除与修改三种类型的操作主要使用update和batchUpdate方法来完成。query和queryForObject方法中主要用来完成查询功能。execute方法可以用来执行任意的SQL、call方法来调用存储过程。
3.1 在数据源建表
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tx_user
-- ----------------------------
DROP TABLE IF EXISTS `tx_user`;
CREATE TABLE `tx_user` (
`username` varchar(10) DEFAULT NULL,
`userId` int(10) NOT NULL,
`password` varchar(10) DEFAULT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.2 创建Controller
package com.qcby.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
@Controller
public class TestController {
@Autowired
JdbcTemplate jdbcTemplate;
@ResponseBody
@RequestMapping("/query")
public List<Map<String, Object>> query(){
List<Map<String, Object>> maps = jdbcTemplate.queryForList("SELECT * FROM tx_user");
return maps;
}
}
代码解释:
@Autowired 注解
@Autowired 是 Spring 框架提供的一个注解,其作用是实现自动装配,也就是让 Spring 容器自动将需要的 Bean 注入到当前类中。当 Spring 容器启动时,它会扫描所有带有 @Autowired 注解的字段、方法或者构造函数,接着依据类型(默认情况)去查找匹配的 Bean 并进行注入。
JdbcTemplate:
这是 Spring 框架提供的一个核心类,它对 JDBC(Java Database Connectivity)进行了封装,从而简化了 Java 代码和数据库之间的交互。JdbcTemplate 能够处理数据库连接的创建、关闭、SQL 语句的执行、结果集的处理等操作,让开发者无需手动编写大量的样板代码。
queryForList 方法:
是 JdbcTemplate 提供的一个用于执行 SQL 查询并返回结果集的方法。它接受一个 SQL 查询语句作为参数。
启动springboot访问
Springboot中提供了JdbcTemplateAutoConfiguration的自动配置
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
JdbcTemplateAutoConfiguration源码: