封面画师:adsuger 封面ID:76752964
1. 整合 JDBC
1.1 SpringData
-
对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理
-
Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目
-
Sping Data 官网:点击查看
1.1 整合 JDBC
- 创建 SpringBoot 项目,并导入对应的模块

- 项目建好后,会自动导入相关的启动器;
- 编写 yaml 配置文件链接数据库:
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///sboot?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
- 到此,我们就已经完成了基本配置,其他的配置 SpringBoot 会帮我们自动配置。
1.2 数据源
-
我们连接好数据库后,可以进行测试。测试后发现,我们可以发现 SpringBoot 默认给我们配置的数据源是 class com.zaxxer.hikari.HikariDataSource
-
我们可以进行全局搜索,找到数据源的所有配置都在 DataSourceAutoConfiguration 文件。这里导入的类都在 DataSourceConfiguration 配置类下,可以看出 Spring Boot 2.2.4 默认使用 HikariDataSource 数据源
-
小道消息:HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0、DBCP、Tomcat jdbc 等连接池更加优秀;
-
自定义数据源类型:使用 spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。
1.3 JDBCTemplate
-
有了数据源,我们就可以拿到数据库连接,然后使用原生的 JDBC 语句来操作数据库。
-
即使不使用第三方第数据库操作框架,如 MyBatis 等,Spring 本身也对原生的 JDBC 做了轻量级的封装,即 JdbcTemplate。数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。xxxxTemplate 相当于 SpringBoot 给我们配置好的模板 bean,拿来即用。
-
当然,Spring Boot 默认已经配置好了 JdbcTemplate,程序员只需注入就可以使用。
-
JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 JdbcTemplateConfiguration 类。
JdbcTemplate 主要提供以下几类方法:
execute方法:可以用于执行任何 SQL 语句,一般用于执行 DDL 语句update方法及batchUpdate方法:update 方法用于执行新增、修改、删除等语句;batchUpdate 方法用于执行批处理相关语句query方法及queryForxxx方法:用于执行查询相关语句call方法:用于执行存储过程、函数相关语句
代码测试:
@RestController
public class JDBCController {
@Autowired
JdbcTemplate jdbcTemplate;
//查询数据库的所有信息
@GetMapping("/userList")
public List<Map<String, Object>> userList() {
String sql = "select * from account";
List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
return list_maps;
}
@GetMapping("/addUser")
public String addUser() {
String sql = "insert into account(name,money,password) values ('小明',12,'15987')";
jdbcTemplate.update(sql);
return "update-ok";
}
@GetMapping("/updateUser/{id}")
public String updateUser(@PathVariable("id") int id) {
String sql = "update account set name=?,money=? where id=" + id;
//封装
Object[] objects = new Object[2];
objects[0] = "eeee";
objects[1] = 98;
jdbcTemplate.update(sql, objects);
return "update-ok";
}
@GetMapping("/deleteUser/{id}")
public String deleteUser(@PathVariable("id") int id) {
String sql = "delete from account where id = ?";
jdbcTemplate.update(sql, id);
return "delete-ok!";
}
}
2. 整合 Druid
2.1 Druid 简介
Java 程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。
Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。
Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。
Druid 已经在阿里巴巴部署了超过 600 个应用,经过一年多生产环境大规模部署的严苛考验。
Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,本节来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。
Github 地址:Druid
com.alibaba.druid.pool.DruidDataSource 基本配置参数如下:

2.2 添加数据源至项目
-
添加 Druid 数据源依赖:
<!-- druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.21</version> </dependency> -
由于 SpringBoot 默认数据源为 Hikari,因此我们需要将其切换成 Druid:
spring: datasource: username: root password: 123456 url: jdbc:mysql:///ssm?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver # 切换数据源 type: com.alibaba.druid.pool.DruidDataSource -
编写测试类,启动项目,检查数据源是否切换成功:
@SpringBootTest class Springboot03DataApplicationTests { @Autowired DataSource dataSource; @Test void contextLoads() throws SQLException { //查看默认数据源 com.zaxxer.hikari.HikariDataSource System.out.println(dataSource.getClass()); //获得数据库连接 Connection connection = dataSource.getConnection(); System.out.println(connection); //close connection.close(); } }控制台显示:
class com.alibaba.druid.pool.DruidDataSource com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1f53481b表示切换成功!😎
-
在配置文件中设置 Druid 的一些参数:
spring: datasource: username: root password: 123456 url: jdbc:mysql:///ssm?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8&useSSL=false 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:日志记录、wall:防御sql注入 #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority #则导入 log4j 依赖即可,Maven 地址: https://mvnrepository.com/artifact/log4j/log4j 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.17</version> </dependency> -
我们设置的参数暂时不会生效,没有对应的 Starter 来绑定这些参数,因此需要我们自己为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中。编写一个配置类即可:
@Configuration public class DruidConfig { /* 将自定义的 Druid数据源添加到容器中 将全局配置文件中前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中 */ @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druidDataSource() { return new DruidDataSource(); } }
2.3 数据监控
我们配置好 Druid 数据源后,发现与默认的数据源并没有什么区别,难道 Druid 仅此而已?
Druid 的最重要特性就是可以进行数据监控,并且提供了一个 Web 界面方便用户查看,我们需要在配置类中设置以进行数据监控:
DruidConfig.java:
//后台监控
// SpringBoot内置Servlet容器,没有web.xml,替代方法:druidDataSource,相当于web.xml
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
//后台登录密码配置
HashMap<String, String> initParameters = new HashMap<>();
//配置 put()第一个参数固定
initParameters.put("loginUsername", "admin"); //登录key都是固定的
initParameters.put("loginPassword", "123456");
//后台访问权限 参数为空,谁都能访问
initParameters.put("allow", "");
//initParams.put("allow", "localhost"):表示只有本机可以访问
//访问禁止人员 initParameters.put("用户名","IP地址");
bean.setInitParameters(initParameters);
return bean;
}
编写好代码后,我们可以启动项目,访问:http://localhost:8080/druid/login.html

然后我们输入在配置类中编写的登录用户名和密码进入后台监控页面:

我们可以上方导航栏切换不同的功能。
我们进行的所有操作都会被 Druid 进行监控,但是有一些请求我们不想被监控,我们可以在配置类中设置一个 Druid 监控过滤器:
DruidConfig.java:
//filter
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
//过滤请求
Map<String, String> initParameters = new HashMap<>();
//不进行监视统计的文件
initParameters.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParameters);
// "/*" 表示过滤所有请求, 例如:bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
3. 整合 MyBatis
在 Maven 仓库中选择 MyBatis 需要的依赖:
<!-- mybatis-spring-boot-starter 整合-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
从带入的依赖我们可以看出,MyBatis 的 Starter 名为 xxx-spring-boot-starter,表示这并不是 SpringBoot 官方的 Starter,是第三方的 Starter。
为了便于开发,我们一并导入了 lombok,记得在 IDEA 中添加 lombok 插件,否则代码无法运行!
在配置文件在配置数据库连接信息:
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///ssm?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
#整合Mybatis
mybatis:
type-aliases-package: com.yang.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
编写 pojo:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
private int id;
private String name;
private String password;
private float money;
public Account(String name, String password, float money) {
this.name = name;
this.password = password;
this.money = money;
}
}
编写 mapper(CRUD 全套搞起 💪):
//表明这是一个mybatis的mapper类:Dao
// 除了这种方式,我们还可以在主启动类上添加注解@MapperScan(...)。
@Mapper
@Repository
public interface AccountMapper {
List<Account> queryAccountList();
Account queryAccountById(int id);
int addAccount(Account account);
int updateAccount(Account account);
int deleteAccount(int id);
}
小知识:接口中的变量 int age = 18; 默认表示为 public static final int age = 18,即:接口中的变量表示常量!
maven 配置资源过滤问题:
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
编写到这,我们应该编写 MyBatis 的映射文件。在以前,我们会在 mapper 下创建映射文件,现在,建议 在 resources 目录下创建映射文件,但是这样我们就无法同时使用注解与配置文件。
在 resources 目录下创建目录:mybatis/mapper,然后创建映射文件:AccountMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yang.mapper.AccountMapper">
<!-- 我们在配置文件中设置了别名,所以对于pojo不用使用全类名 -->
<select id="queryAccountList" resultType="Account">
select * from account
</select>
<select id="queryAccountById" resultType="Account">
select * from account where id = #{id}
</select>
<insert id="addAccount" parameterType="Account">
insert into account (name,money,password) values (#{name},#{money},#{password})
</insert>
<update id="updateAccount" parameterType="Account">
update account set name = #{name},money=#{money} where id = #{id}
</update>
<delete id="deleteAccount" parameterType="int">
delete from account where id =#{id};
</delete>
</mapper>
编写 Controller 准备测试:
@RestController
public class AccountController {
@Autowired
private AccountMapper accountMapper;
@GetMapping("/queryAccountList")
public List<Account> queryAccountList(){
List<Account> accounts = accountMapper.queryAccountList();
for (Account account:accounts){
System.out.println(account);
}
return accounts;
}
@GetMapping("/queryAccountById/{id}")
public Account queryAccountById(@PathVariable("id") int id){
Account account = accountMapper.queryAccountById(id);
System.out.println(account);
return account;
}
@GetMapping("/addAccount")
public String addAccount(){
accountMapper.addAccount(new Account("小安","123456",1000));
return "addAccount-ok";
}
@GetMapping("/updateAccount")
public String updateAccount(){
Account account = new Account();
account.setId(14);
account.setName("小暗");
account.setMoney(999);
accountMapper.updateAccount(account);
return "updateAccount-ok";
}
@GetMapping("/deleteAccount/{id}")
public String deleteAccount(@PathVariable("id") int id){
accountMapper.deleteAccount(id);
return "deleteAccount-ok";
}
}
数据库字段与实体类属性名不一致
由于大多数数据库设置不区分大小写,因此常采用下划线命名,比如:phone_code。而在 Java 中,一般使用驼峰式命名,如:phoneCode。
MyBatis 还提供 了 一个全局属性 mapUnderscoreToCamelCase,通过配置这个属性为 true 可以自动将以下画线方式命名的数据库列映射到 Java 实体类的驼峰式命名属性中。这个属性 默认 为 false ,如果想要使用该功能,需要在 MyBatis 的配置文件 中增加如下配置:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
由于这里是 SpringBoot 项目,因此需要在配置文件 application.yaml 添加这样的配置:
mybatis:
configuration:
map-underscore-to-camel-case: true