SpringBoot整合JDBC、整合Druid数据源详解教程

SpringBoot整合JDBC、整合Druid数据源详解教程目录一、整合JDBC1.环境准备1.创建数据库2.创建SpringBoot项目3.IDEA连接数据库2.编写数据库配置信息3.编写测试类测试4.CRUD操作数据库1.JDBCTemplate简介2.CRUD测试二、整合Druid数据源1.Druid简介2.部分基本配置参数3.使用Durid数据源1.导入依赖2.切换数据源3.设置数据源属性4.使添加属性生效5.配置Druid后台监控Servlet6.配置Druid监控过滤器filter一、整合JDBC1.环境准备.

大家好,又见面了,我是你们的朋友全栈君。



一、整合JDBC

1. 环境准备

1. 创建数据

-- 创建数据库
CREATE DATABASE springboot;

-- 使用springboot数据库
use springboot;

-- 创建user表
CREATE TABLE IF NOT EXISTS `user`(
	`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '身份号',
	`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
	`pwd` VARCHAR(30) NOT NULL DEFAULT '123456' COMMENT '密码',
	PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-- 给user表插入数据
INSERT INTO `user`(`id`,`name`,`pwd`) 
VALUES ('1','zsr',000204),('2','gcc',000421),('3','BaretH',200024);

创建完成后得到下表
image-20201008203709973


2. 创建SpringBoot项目

首先创建一个springboot项目,勾选组件时勾选JDBC APIMySQL Driver

image-20201006110200651

项目创建完成之后,发现导入了以下两个启动器,这就是SpringBoot和JDBC整合所需要的两个依赖

<!--JDBC-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--MySQL驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

3. IDEA连接数据库

image-20201008203845928

打开我们刚刚创建的数据库
image-20201008203924600
然后可以看到我们前面创建的user
image-20201008204058928


2. 编写数据库配置信息

这里建议使用.yaml格式的数据文件,在resources目录下,新建一个application.yaml

填写自己的数据库相关的信息:

spring:
  datasource:
    username: root
    data-password: 200024
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

其中在配置driver-class-name时,有两个选择:
image-20201011163234479

  • com.mysql.jdbc.Drivermysql-connector-java 5中的

  • com.mysql.cj.jdbc.Drivermysql-connector-java 6 中的特性,相比5多了一个时区设置:serverTimezone

这里是 mysql 8.0.21,因此需要添加时区设置

  • 在设定时区的时候,如果设定serverTimezone=UTC,会比中国时间早8个小时

  • 如果在中国,可以选择 Asia/Shanghai 或者 Asia/Hongkong

spring:
  datasource:
    username: root
    password: 200024
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

如果没有添加时区设置,则会报以下错误
image-20201008191703728


3. 编写测试类测试

上述配置完成后,就可以直接使用了,因为SpringBoot已经默认帮我们进行了自动配置

我们接下来去测试类测试,SpringBoot提供了默认的数据源,我们只需要注入到spring容器中即可使用

package com.zsr;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@SpringBootTest
class Springboot05DataApplicationTests { 
   
    //注入数据源
    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException { 
   
        //查看默认的数据源
        System.out.println(dataSource.getClass());
        //获得数据库连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //关闭连接
        connection.close();
    }
}

运行测试,出现如下结果即代表数据库连接成功

可以看到SpringBoot默认的数据源是class com.zaxxer.hikari.HikariDataSource,即hikari
SpringBoot整合JDBC、整合Druid数据源详解教程
Hikari快速,简单,可靠,spring boot2.0 已经将 HikariCP 做为了默认的数据源链接池,在官网测试中秒杀一切其他数据源,比如 commons-dbcp,tomcat,c3po,druid等

了解更过Hikari数据源参考:https://cloud.tencent.com/developer/article/1554345


4. CRUD操作数据库

有了数据源,就拿到了数据库连接,然后我们就可以使用原生的 JDBC 语句来操作数据库了

那么我们怎么操作数据库呢?

SpringBoot中,不需要使用第三方第数据库操作框架,如MyBatis等,Spring本身对原生的JDBC做了轻量级的封装:JdbcTemplate

1. JDBCTemplate简介

JdbcTemplate是Spring对JDBC的封装,目的是使JDBC更加易于使用。

  • JdbcTemplate是Spring的一部分,处理了资源的建立和释放;帮助我们避免一些常见的错误,比如忘了总要关闭连接。

  • 它运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。

  • 数据库操作的所有 CRUD 方法都在 JdbcTemplate 中

  • Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,只需注入即可使用

  • JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 JdbcTemplateConfiguration

JdbcTemplate 主要提供以下几类方法:

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句;

2. CRUD测试

在主程序同级目录下新建一个包controller,其中新建JDBCController类,执行数据库相关操作

image-20201011182021808

首先导入web场景启动器,导入web模块正常运行所依赖的组件

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>
package com.zsr.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.RestController;
import java.util.List;
import java.util.Map;
@RestController
public class JDBCController { 

@Autowired
JdbcTemplate jdbcTemplate;
//查
@GetMapping("/query")
public List<Map<String, Object>> userList() { 

String sql = "select * from user";
List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
return users;
}
//增
@GetMapping("/add")
public String addUser() { 

String sql = "insert into springboot.user(id,name,pwd) values (4,'gpl','45678')";
jdbcTemplate.update(sql);//自动提交事务
return "添加成功";
}
//删
@GetMapping("/delete/{id}")
public String deleteUser(@PathVariable("id") int id) { 

String sql = "delete from springboot.user where id=?";
jdbcTemplate.update(sql, id);//自动提交事务
return "删除成功";
}
//改
@GetMapping("/change/{id}")
public String updateUser(@PathVariable("id") int id) { 

String sql = "update springboot.user set name=?,pwd=? where id=" + id;
Object[] objects = new Object[2];
objects[0] = "zml";
objects[1] = "1213353";
jdbcTemplate.update(sql, objects);//自动提交事务
return "修改成功";
}
}

然后我们启动主程序进行测试,

  1. 首先查询所有用户信息,访问localhost:8080/query,成功显示所有员工
    image-20201011175933907

  2. 然后增加一个4号用户,访问localhost:8080/add
    image-20201011180039769
    ​ 然后刷新user表,成功添加4号用户
    1

  3. 再修改4号用户,访问localhost:8080/change/4
    image-20201011180439589
    然后刷新user表,成功修改4号用户
    image-20201011180526215

  4. 最后删除4号用户,访问localhost:8080/delete/4
    image-20201011180603114
    然后刷新user表,成功删除4号用户
    image-20201011180620910


二、整合Druid数据源

本实验环境基于上述整合JDBC实验环境

1. Druid简介

Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。

Druid是一个关系型数据库连接池,它是阿里巴巴的一个开源项目。Druid支持所有JDBC兼容的数据库,包括Oracle、MySQL、Derby、PostgreSQL、SQL Server、H2等。Druid在监控、可扩展性、稳定性和性能方面具有明显的优势。通过Druid提供的监控功能,可以实时观察数据库连接池和SQL查询的工作情况。使用Druid连接池,在一定程度上可以提高数据库的访问性能。

  • Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。

  • Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天然继承监控功能

  • Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。

Github地址:https://github.com/alibaba/druid/


2. 部分基本配置参数

com.alibaba.druid.pool.DruidDataSource 基本配置参数如下:

配置 缺省值 说明
name 配置这个属性的意义在于:如果存在多个数据源,监控的时候可以通过名字来区分开来;如果没有配置,将会生成一个名字,格式是:“DataSource-” + System.identityHashCode(this)
jdbcUrl 连接数据库的url,不同数据库不一样
username 连接数据库的用户名
password 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter
driverClassName 根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应driverClassName(建议配置)
initialSize 0 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive 8 最大连接池数量
maxIdle 8 已经不再使用,配置了也没效果
minIdle 最小连接池数量
maxWait 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatements false 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
maxOpenPreparedStatements -1 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
testOnBorrow true 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdle false 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis 有两个含义: 1. Destroy线程会检测连接的间隔时间 2. testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun 不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis
connectionInitSqls 物理连接初始化的时候执行的sql
exceptionSorter 根据dbType自动识别 当数据库抛出一些不可恢复的异常时,抛弃连接
filters 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat、日志用的filter:log4j、防御sql注入的filter:wall
proxyFilters 类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

3. 使用Durid数据源

1. 导入依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.1</version>
</dependency>

2. 切换数据源

在springboot配置文件中通过spring.datasource.type指定数据源

spring:
datasource:
username: root
password: 200024
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource

启动上述测试类进行测试

image-20201011182414739
可以看到数据源切换成功


3. 设置数据源属性

我们在基础的配置属性之外,可以添加Druid数据源的专有配置属性

spring:
datasource:
username: root
password: 200024
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
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:监控统计
# log4j:日志记录(需要导入log4j依赖)
# wall:防御sql注入
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

其中,监控统计拦截器配置了log4j需要导入其依赖

<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>

4. 使添加属性生效

为了使上述配置的druid特有数据源属性生效,我们创建自己的DruidDataSource并绑定配置文件中的属性参数,添加到容器中,而不再使用SpringBoot自动生成的Druid数据源

在主程序同级目录下新建一个config包,在其中新建DruidConfig

package com.zsr.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
@Configuration
public class DruidConfig { 

@ConfigurationProperties(prefix = "spring.datasource") //将全局配置文件中前缀为spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
@Bean //将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
public DataSource druidDataSource() { 

return new DruidDataSource();
}
}

5. 配置Druid后台监控Servlet

Druid 数据源具有监控的功能,并内置提供了一个StatViewServlet用于展示Druid的监控信息,包括

  • 提供监控信息展示的html页面
  • 提供监控信息的JSON API

开启Druid的监控功能,可以在应用运行期间,通过监控提供的多维度数据来分析使用数据库的运行情况,从而可以调整程序设计,以达到优化数据库访问性能的目的

接下来定义一个后台监控器,在DruidConfig中新建一个方法statViewServlet()

  • 首先要创建一个servlet的bean:springboot中内置了servlet容器,我们要使用servlet,只需要用其提供的ServletRegistrationBean注册一个servlet注入到spring容器中即可,不再需要web.xml的配置

    ServletRegistrationBean<StatViewServlet> servlet = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
    

    ServletRegistrationBean的有参构造函数中:

    1. 第一个参数为传入的servlet:这里传入Druid内置的StatViewServlet

    2. 第二个参数可以设置映射的路径:这里我们使用/druid/*

      就是以前我们在web.xml中配置的servlet-mapping定义的请求路径

  • 然后我们就可以执行servlet的相关操作,可以看到很多方法
    image-20201014151656238
    这里设置一些初始化参数:

    loginUsername:StatViewServlet提供后台管理页面的登录用户名

    loginPassword:StatViewServlet提供后台管理页面的登录密码

    allow:设置允许访问的人

    这些参数可以在StatViewServlet的父类ResourceServlet中找到
    image-20201014152022507

  • 最后返回servlet对象即可

完整代码

//配置Druid监控管理后台的Servlet;
//注册到bean中
@Bean
public ServletRegistrationBean statViewServlet() { 

//创建一个servlet,并定义请求路径
ServletRegistrationBean<StatViewServlet> servlet = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
//初始化参数设置:后台登录的账号密码、允许访问者
HashMap<String, String> initParameters = new HashMap<>();
initParameters.put("loginUsername", "admin");//key名固定,这些参数可以在StatViewServlet的父类ResourceServlet中找到
initParameters.put("loginPassword", "123456");//key名固定,这些参数可以在StatViewServlet的父类ResourceServlet中找到
initParameters.put("allow", "localhost");//设置允许访问的人:这里表示只有本机可以访问(后面参数为空则所有人都可以访问)
//设置初始化参数
servlet.setInitParameters(initParameters);
//返回servlet
return servlet;
}

测试:配置完成后,重启主程序,访问localhost:8080/druid,会跳转到http://localhost:8080/druid/login.html页面,这就是Druid内置的展示后台管理监控的页面
image-20201011205346032
然后输入我们刚才设置的用户名和密码,点击Sign in进行登录
image-20201011205453941
进入到后台管理页面
image-20201011205522638
我们访问一下localhost:8080/query,查询所有用户;然后查看SQL监控,就可以看到我们刚刚执行的操作
image-20201011205825703
查看SQL防火墙也可以看到相关信息
image-20201011210027085


6. 配置Druid监控过滤器filter

同servlet一样,springboot中内置了filter容器,我们要使用filter,只需要用其提供的FilterRegistrationBean注册一个filter注入到spring容器中即可,不再需要web.xml的配置

同样在DruidConfig中新增一个方法webStatFilter()

  • 首先要创建一个filter的bean

    FilterRegistrationBean bean = new FilterRegistrationBean(new WebStatFilter());
    

    ServletRegistrationBean的有参构造函数中:

    传入的参数是filter:这里传入用于用于配置Web和Druid数据源之间的管理关联监控统计的WebStatFilter()

  • 然后我们就可以执行filter的相关操作,同样可以看到很多方法
    image-20201014153659762
    这里同样设置初始化参数:

    exclusions:表示需要排除一些不必要的url请求

    其他参数可以在WebStatFilter中看到
    image-20201014153913898

  • 最后返回filter即可

//配置Druid监控之web监控的filter
//注册到bean中
@Bean
public FilterRegistrationBean webStatFilter() { 

//创建一个filter
FilterRegistrationBean filter = new FilterRegistrationBean(new WebStatFilter());
//初始化参数设置
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");//exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
//设置初始化参数
filter.setInitParameters(initParams);
//添加过滤规则:/*表示过滤所有请求 filter.setUrlPatterns(Arrays.asList("/*")); //返回filter return filter; } 

更多的配置源码中很详细,实际开发中根据具体的需要进行相应的配置,这里只是举个例子~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163565.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • vue md5.js_VUE.js

    vue md5.js_VUE.js<template><div><mavonEditorv-model=”markdown”:codeStyle=”codeStyle”></mavonEditor><divv-html=”compiledMarkdown”></div></div></template><script>//编辑import{mavonEditor}from’.

  • nfv与云计算_云计算必学知识

    nfv与云计算_云计算必学知识云计算1.Saas软件即服务SaaS的实例:MicrosoftOfficeOnline(WordOnline,ExcelOnline等)服务,无需在本机安装,打开浏览器,注册账号,可以随时随地通过网络进行软件编辑,保存等,不需要用户去升级软件,维护软件等。平台即服务,把服务器平台作为一种对外提供的一种商业模式。系统对外提供接口服务,开发者可以利用这些接口进行开发业务或者应用,提供给用户使…

  • JS,CSS是前端,JAVA PHP ASP是后端,数据库是后端的处理对象,非代表前后底

    JS,CSS是前端,JAVA PHP ASP是后端,数据库是后端的处理对象,非代表前后底大海-mysql-oracle(529513481)  19:02:18象我这边,前台都是php,而php做数据分析是不太理想的,做中间件没人力,难办横瓜(601069289) 19:20:15 用C写中间件D,PHP再调用D横瓜(601069289) 19:20:31 用C写中间件D,PHP再调用D横瓜(601069289) 19:20:3…

  • 文件上传linux文件名乱码_java导出文件名中文乱码

    文件上传linux文件名乱码_java导出文件名中文乱码从网上下了一个zip文件,unzip解压后发现中文显示都是乱码,以前也遇到过打开Windows系统下目录文件名也是乱码的问题。这是什么原因呢?文件是在Windows下创建的,而Windows的文件名中文编码默认GBK,Linux中默认文件名编码为UTF-8,编码不一致导致了文件名乱码的问题,解决这个问题需要对文件名进行转码,这个工具就是convmv。SYNOPSIS:convmv…

  • FORM表单

    FORM简介我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否

  • 常用八大测试用例设计方法有哪些_测试用例编写方法

    常用八大测试用例设计方法有哪些_测试用例编写方法1、等价类划分(EquivalancePartitioning)测试的思想:将程序的输入域划分为若干个区域(等价类),并在每个等价类中选择一个具有代表性的元素生成测试用例。该方法是常用的黑盒(BlackboxTesting)测试用例(Testcase)设计方法。等价类划分可有两种不同的情况:有效等价类和无效等价类。有效等价类是指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合,它能检验程序是否可以实现规格说明中所规定的功能需求。无效等价类是指对程序的规格说明是不合理的或无意义的输入数据所

    2022年10月12日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号