简介

  • 对于数据访问层,无论是 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导入依赖

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-jdbc</artifactId>
    4. </dependency>
    5. <dependency>
    6. <groupId>mysql</groupId>
    7. <artifactId>mysql-connector-java</artifactId>
    8. <scope>runtime</scope>
    9. </dependency>
  • yml编写链接数据库配置

    1. # spring jdbc 链接属性配置
    2. spring:
    3. datasource:
    4. username: root
    5. password: 123456
    6. url: jdbc:mysql://localhost:8889/zentao?userUnicode=true&characterEncoding=utf-8
    7. driver-class-name: com.mysql.cj.jdbc.Driver
    8. # 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 {

  1. @Resource
  2. DataSource dataSource;
  3. @Test
  4. void contextLoads() throws SQLException {
  5. // 默认数据源打印出来为 class com.zaxxer.hikari.HikariDataSource
  6. System.out.println(dataSource.getClass());
  7. // 获取数据源链接 抛出异常处理
  8. Connection connection = dataSource.getConnection();
  9. // xxx Template springboot已经配置好的模板bean,拿来即用
  10. // jdbcTemplate
  11. // redisTemplate crud方法都防撞在template中
  12. System.out.println(connection);
  13. connection.close();
  14. }

}

  1. - 默认数据源打印为hikari
  2. - 接下来来看源码,全局搜索一下,找到数据源所有的自动配置在 DataSourceAutoConfiguration 这个类中
  3. <a name="P5QoN"></a>
  4. # JDBCTemplate
  5. - 有了数据源,然后可以拿到数据库链接,有了链接,就可以使用原声的JDBC语句来操作数据库。
  6. - 即使不使用第三方数据库操作框架,如MyBatis等,Spring 本身也对原生的JDBC做了轻量级的封装,即JdbcTemplate
  7. - 数据库操作的所有 CRUD 方法都在 JdbcTemplate
  8. - Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需要自己注入即可使用
  9. - JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的JdbcTemplateConfiguration
  10. - JdbcTemplate主要提供以下几类方法:
  11. - execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句
  12. - update方法以及batchUpdate方法:update方法用于执行新增,修改,删除等语句,batchUpdate方法用于执行批处理相关语句。
  13. - query方法及queryForXXX方法:用于执行查询相关语句
  14. - call方法:用于执行存储过程,函数相关语句
  15. <a name="QcF2G"></a>
  16. # 测试
  17. - 编写一个controller,注入jdbcTemplate,编写测试方法进行访问测试。
  18. ```java
  19. package com.kuang.controller;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.jdbc.core.JdbcTemplate;
  22. import org.springframework.web.bind.annotation.GetMapping;
  23. import org.springframework.web.bind.annotation.PathVariable;
  24. import org.springframework.web.bind.annotation.RequestMapping;
  25. import org.springframework.web.bind.annotation.RestController;
  26. import java.util.Date;
  27. import java.util.List;
  28. import java.util.Map;
  29. @RestController
  30. @RequestMapping("/jdbc")
  31. public class JdbcController {
  32. /**
  33. * Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate
  34. * JdbcTemplate 中会自己注入数据源,用于简化 JDBC操作
  35. * 还能避免一些常见的错误,使用起来也不用再自己来关闭数据库连接
  36. */
  37. @Autowired
  38. JdbcTemplate jdbcTemplate;
  39. //查询employee表中所有数据
  40. //List 中的1个 Map 对应数据库的 1行数据
  41. //Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
  42. @GetMapping("/list")
  43. public List<Map<String, Object>> userList(){
  44. String sql = "select * from employee";
  45. List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
  46. return maps;
  47. }
  48. //新增一个用户
  49. @GetMapping("/add")
  50. public String addUser(){
  51. //插入语句,注意时间问题
  52. String sql = "insert into employee(last_name, email,gender,department,birth)" +
  53. " values ('狂神说','24736743@qq.com',1,101,'"+ new Date().toLocaleString() +"')";
  54. jdbcTemplate.update(sql);
  55. //查询
  56. return "addOk";
  57. }
  58. //修改用户信息
  59. @GetMapping("/update/{id}")
  60. public String updateUser(@PathVariable("id") int id){
  61. //插入语句
  62. String sql = "update employee set last_name=?,email=? where id="+id;
  63. //数据
  64. Object[] objects = new Object[2];
  65. objects[0] = "xxx";
  66. objects[1] = "24736743@sina.com";
  67. jdbcTemplate.update(sql,objects);
  68. //查询
  69. return "updateOk";
  70. }
  71. //删除用户
  72. @GetMapping("/delete/{id}")
  73. public String delUser(@PathVariable("id") int id){
  74. //插入语句
  75. String sql = "delete from employee where id=?";
  76. jdbcTemplate.update(sql,id);
  77. //查询
  78. return "deleteOk";
  79. }
  80. }

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 的基本配置见下图

image.png
image.png
image.png

配置数据源

  • 添加上Druid 数据源依赖 ```java

com.alibaba druid 1.1.21

  1. - 切换数据源:springboot 2.0 以上默认使用 hikari数据源,但是可以通过spring.datasource.type 指定数据源
  2. ```java
  3. # spring jdbc 链接属性配置
  4. spring:
  5. datasource:
  6. username: root
  7. password: 123456
  8. url: jdbc:mysql://localhost:8889/zentao?userUnicode=true&characterEncoding=utf-8
  9. driver-class-name: com.mysql.cj.jdbc.Driver
  10. # 5.x 版本使用jdbc.driver,之后版本使用cj.driver
  11. # type: com.zaxxer.hikari.HikariDataSource
  12. type: com.alibaba.druid.pool.DruidDataSource
  • 切换之后在测试类中尝试获取到数据源,检查是否生效

image.png

  • 切换成功,既然切换成功,就可以设置数据源链接初始化大小,最大连接数,等待时间,最小连接数 等设置, 可以查看源码进行学习

    1. # spring jdbc 链接属性配置
    2. spring:
    3. datasource:
    4. username: root
    5. password: 123456
    6. url: jdbc:mysql://localhost:8889/zentao?userUnicode=true&characterEncoding=utf-8
    7. driver-class-name: com.mysql.cj.jdbc.Driver
    8. # 5.x 版本使用jdbc.driver,之后版本使用cj.driver
    9. # type: com.zaxxer.hikari.HikariDataSource
    10. type: com.alibaba.druid.pool.DruidDataSource
    11. #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    12. #druid 数据源专有配置
    13. initialSize: 5
    14. minIdle: 5
    15. maxActive: 20
    16. maxWait: 60000
    17. timeBetweenEvictionRunsMillis: 60000
    18. minEvictableIdleTimeMillis: 300000
    19. validationQuery: SELECT 1 FROM DUAL
    20. testWhileIdle: true
    21. testOnBorrow: false
    22. testOnReturn: false
    23. poolPreparedStatements: true
    24. #配置监控统计拦截的filtersstat:监控统计、log4j:日志记录、wall:防御sql注入
    25. #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
    26. #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    27. filters: stat,wall,log4j
    28. maxPoolPreparedStatementPerConnectionSize: 20
    29. useGlobalDataSourceStat: true
    30. connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  • 导入log4j依赖

    1. <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    2. <dependency>
    3. <groupId>log4j</groupId>
    4. <artifactId>log4j</artifactId>
    5. <version>1.2.17</version>
    6. </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 {

  1. /*
  2. 将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
  3. 绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
  4. @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
  5. 前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
  6. */
  7. @ConfigurationProperties(prefix = "spring.datasource")
  8. @Bean
  9. public DataSource druidDataSource() {
  10. return new DruidDataSource();
  11. }

}

  1. - 进行测试,是否有druid的属性配置注入
  2. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1608527/1617810610179-281cea13-e4d4-43f6-8a87-683b547846bb.png#align=left&display=inline&height=341&margin=%5Bobject%20Object%5D&name=image.png&originHeight=682&originWidth=1333&size=502733&status=done&style=none&width=666.5)
  3. <a name="lki4M"></a>
  4. ## 配置数据源监控
  5. - Druid 数据源具有监控的功能,并且提供了一个web页面方便用户进行查看,类似安装路由器时,提供的一个默认的web管理页面
  6. - 第一步需要设置Druid的后台管理页面,比如登陆账号,密码等,配置后台管理
  7. ```java
  8. package com.addicated.config;
  9. import com.alibaba.druid.pool.DruidDataSource;
  10. import com.alibaba.druid.support.http.StatViewServlet;
  11. import org.springframework.boot.context.properties.ConfigurationProperties;
  12. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  13. import org.springframework.context.annotation.Bean;
  14. import org.springframework.context.annotation.Configuration;
  15. import javax.sql.DataSource;
  16. import java.util.HashMap;
  17. import java.util.Map;
  18. @Configuration
  19. public class DruidConfig {
  20. /*
  21. 将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
  22. 绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
  23. @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
  24. 前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
  25. */
  26. @Bean
  27. @ConfigurationProperties(prefix = "spring.datasource")
  28. public DataSource druidDataSource(){
  29. return new DruidDataSource();
  30. }
  31. @Bean
  32. public ServletRegistrationBean statViewServlet(){
  33. ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
  34. // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet
  35. // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
  36. Map<String, String> initParams = new HashMap<>();
  37. initParams.put("loginUsername", "admin"); //后台管理界面的登录账号
  38. initParams.put("loginPassword", "123456"); //后台管理界面的登录密码
  39. //后台允许谁可以访问
  40. //initParams.put("allow", "localhost"):表示只有本机可以访问
  41. //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
  42. initParams.put("allow", "");
  43. //deny:Druid 后台拒绝谁访问
  44. //initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问
  45. //设置初始化参数
  46. bean.setInitParameters(initParams);
  47. return bean;
  48. }
  49. //2.配置一个web监控的filter
  50. @Bean
  51. public FilterRegistrationBean webStatFilter(){
  52. FilterRegistrationBean bean = new FilterRegistrationBean();
  53. bean.setFilter(new WebStatFilter());
  54. Map<String,String> initParams = new HashMap<>();
  55. initParams.put("exclusions","*.js,*.css,/druid/*");
  56. bean.setInitParameters(initParams);
  57. bean.setUrlPatterns(Arrays.asList("/*"));
  58. return bean;
  59. }
  60. }
  • 在工作中用到的时候按需进行配置,主要用来监控