简介
- 对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
- Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。
- Sping Data 官网:https://spring.io/projects/spring-data
数据库相关的启动器 :可以参考官方文档:https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter
整合JDBC
pom导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>
yml编写链接数据库配置
# spring jdbc 链接属性配置spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:8889/zentao?userUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.cj.jdbc.Driver# 5.x 版本使用jdbc.driver,之后版本使用cj.driver
配置完成之后可以直接去使用,因为springboot已经默认完成了一些自动配置,可以搞个类来测试一下 ```java package com.addicated;
import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException;
@SpringBootTest class Springboot03WebApplicationTests {
@ResourceDataSource dataSource;@Testvoid contextLoads() throws SQLException {// 默认数据源打印出来为 class com.zaxxer.hikari.HikariDataSourceSystem.out.println(dataSource.getClass());// 获取数据源链接 抛出异常处理Connection connection = dataSource.getConnection();// xxx Template springboot已经配置好的模板bean,拿来即用// jdbcTemplate// redisTemplate crud方法都防撞在template中System.out.println(connection);connection.close();}
}
- 默认数据源打印为hikari- 接下来来看源码,全局搜索一下,找到数据源所有的自动配置在 DataSourceAutoConfiguration 这个类中<a name="P5QoN"></a># JDBCTemplate- 有了数据源,然后可以拿到数据库链接,有了链接,就可以使用原声的JDBC语句来操作数据库。- 即使不使用第三方数据库操作框架,如MyBatis等,Spring 本身也对原生的JDBC做了轻量级的封装,即JdbcTemplate。- 数据库操作的所有 CRUD 方法都在 JdbcTemplate中- Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需要自己注入即可使用- JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的JdbcTemplateConfiguration 类- JdbcTemplate主要提供以下几类方法:- execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句- update方法以及batchUpdate方法:update方法用于执行新增,修改,删除等语句,batchUpdate方法用于执行批处理相关语句。- query方法及queryForXXX方法:用于执行查询相关语句- call方法:用于执行存储过程,函数相关语句<a name="QcF2G"></a># 测试- 编写一个controller,注入jdbcTemplate,编写测试方法进行访问测试。```javapackage com.kuang.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Date;import java.util.List;import java.util.Map;@RestController@RequestMapping("/jdbc")public class JdbcController {/*** Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate* JdbcTemplate 中会自己注入数据源,用于简化 JDBC操作* 还能避免一些常见的错误,使用起来也不用再自己来关闭数据库连接*/@AutowiredJdbcTemplate jdbcTemplate;//查询employee表中所有数据//List 中的1个 Map 对应数据库的 1行数据//Map 中的 key 对应数据库的字段名,value 对应数据库的字段值@GetMapping("/list")public List<Map<String, Object>> userList(){String sql = "select * from employee";List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);return maps;}//新增一个用户@GetMapping("/add")public String addUser(){//插入语句,注意时间问题String sql = "insert into employee(last_name, email,gender,department,birth)" +" values ('狂神说','24736743@qq.com',1,101,'"+ new Date().toLocaleString() +"')";jdbcTemplate.update(sql);//查询return "addOk";}//修改用户信息@GetMapping("/update/{id}")public String updateUser(@PathVariable("id") int id){//插入语句String sql = "update employee set last_name=?,email=? where id="+id;//数据Object[] objects = new Object[2];objects[0] = "xxx";objects[1] = "24736743@sina.com";jdbcTemplate.update(sql,objects);//查询return "updateOk";}//删除用户@GetMapping("/delete/{id}")public String delUser(@PathVariable("id") int id){//插入语句String sql = "delete from employee where id=?";jdbcTemplate.update(sql,id);//查询return "deleteOk";}}
Druid
简介
- JAVA程序很大一部分要操作DB,为了提高性能操作数据库的时候,又不得不使用数据库链接池。
- Druid 是阿里开源平台上一个数据库链接池实现,结合了 C3P0,DBCP 等 DB 池的优点,同时加入了日志监控。
- Druid 可以很好的监控 DB 池链接和 SQL 的执行情况,天生就是针对监控而生的DB链接池。
- Druid 已经在阿里部署了超过600个应用,经过很多考验。
- SpringBoot 2.0 以上默认使用Hikari 数据源,可以说 Hikari 与 Druid 都是当前 Java Web上最优秀的数据源,下面介绍一下springboot 如何集成 Druid 数据源,如何实现数据库监控。
- Git: https://github.com/alibaba/druid/
- com.alibaba.druid.pool.DruidDataSource 的基本配置见下图
配置数据源
- 添加上Druid 数据源依赖 ```java
- 切换数据源:springboot 2.0 以上默认使用 hikari数据源,但是可以通过spring.datasource.type 指定数据源```java# spring jdbc 链接属性配置spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:8889/zentao?userUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.cj.jdbc.Driver# 5.x 版本使用jdbc.driver,之后版本使用cj.driver# type: com.zaxxer.hikari.HikariDataSourcetype: com.alibaba.druid.pool.DruidDataSource
- 切换之后在测试类中尝试获取到数据源,检查是否生效

切换成功,既然切换成功,就可以设置数据源链接初始化大小,最大连接数,等待时间,最小连接数 等设置, 可以查看源码进行学习
# spring jdbc 链接属性配置spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:8889/zentao?userUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.cj.jdbc.Driver# 5.x 版本使用jdbc.driver,之后版本使用cj.driver# type: com.zaxxer.hikari.HikariDataSourcetype: com.alibaba.druid.pool.DruidDataSource#Spring Boot 默认是不注入这些属性值的,需要自己绑定#druid 数据源专有配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4jfilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
导入log4j依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
现在需要自己为 DuirdDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用SpringBoot的自动生成了,需要自己添加 DruidDataSource 组建到容器中,并绑定属性 ```java package com.kuang.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 {
/*将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效@ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中*/@ConfigurationProperties(prefix = "spring.datasource")@Beanpublic DataSource druidDataSource() {return new DruidDataSource();}
}
- 进行测试,是否有druid的属性配置注入- <a name="lki4M"></a>## 配置数据源监控- Druid 数据源具有监控的功能,并且提供了一个web页面方便用户进行查看,类似安装路由器时,提供的一个默认的web管理页面- 第一步需要设置Druid的后台管理页面,比如登陆账号,密码等,配置后台管理```javapackage com.addicated.config;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.support.http.StatViewServlet;import org.springframework.boot.context.properties.ConfigurationProperties;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.HashMap;import java.util.Map;@Configurationpublic class DruidConfig {/*将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效@ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中*/@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource druidDataSource(){return new DruidDataSource();}@Beanpublic ServletRegistrationBean statViewServlet(){ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");// 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet// 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到Map<String, String> initParams = new HashMap<>();initParams.put("loginUsername", "admin"); //后台管理界面的登录账号initParams.put("loginPassword", "123456"); //后台管理界面的登录密码//后台允许谁可以访问//initParams.put("allow", "localhost"):表示只有本机可以访问//initParams.put("allow", ""):为空或者为null时,表示允许所有访问initParams.put("allow", "");//deny:Druid 后台拒绝谁访问//initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问//设置初始化参数bean.setInitParameters(initParams);return bean;}//2.配置一个web监控的filter@Beanpublic FilterRegistrationBean webStatFilter(){FilterRegistrationBean 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;}}
- 在工作中用到的时候按需进行配置,主要用来监控


