前言
在现代 java 企业级开发中,spring boot 已成为构建微服务和 web 应用的主流框架。其“约定优于配置”的设计理念极大地简化了项目搭建与维护成本。而在实际开发过程中,数据库操作 是绝大多数应用的核心功能之一。本文将围绕 spring boot 2 版本(以 2.7.x 为主),深入讲解如何进行高效、稳定的数据库访问,涵盖多种主流技术栈,并结合实际案例,帮助开发者全面掌握 spring boot 中的数据持久化方案。
一、使用 spring data jpa 实现 orm 操作
1.1 什么是 jpa
jpa(java persistence api)是 java ee 中定义的一套持久化规范,它并不直接操作数据库,而是由具体的实现(如 hibernate、eclipselink)来完成底层工作。spring data jpa 是 spring 对 jpa 规范的进一步封装,提供了更简洁的 api 和自动化的 crud 支持。
适用场景:快速开发、中小型项目、注重实体建模而非 sql 控制的系统。
1.2 添加依赖并启用 jpa
首先,在 pom.xml 文件中引入必要的依赖:
<dependencies>
<!-- spring data jpa 起步依赖 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-jpa</artifactid>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupid>mysql</groupid>
<artifactid>mysql-connector-java</artifactid>
<scope>runtime</scope>
</dependency>
<!-- web 起步依赖(用于测试接口) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
</dependencies>
spring boot 会自动配置以下核心组件:
entitymanagerfactory:jpa 核心工厂,负责创建实体管理器。platformtransactionmanager:事务管理器,支持声明式事务。datasource:数据源对象。jparepositoriesautoconfiguration:自动扫描并注册 repository 接口。
1.3 配置数据库连接信息
在 application.yml 中配置 mysql 数据源及 jpa 行为:
spring:
datasource:
url: jdbc:mysql://localhost:3306/springboot_db?usessl=false&servertimezone=utc&characterencoding=utf8
username: root
password: yourpassword
driver-class-name: com.mysql.cj.jdbc.driver
jpa:
hibernate:
ddl-auto: update # 自动建表策略
show-sql: true # 控制台输出 sql
properties:
hibernate:
format_sql: true # 格式化 sql 输出
dialect: org.hibernate.dialect.mysql8dialect # 指定方言
open-in-view: false # 防止 n+1 查询问题
参数说明:
ddl-auto:
none:不做任何处理validate:验证表结构是否匹配update:更新表结构(推荐开发环境)create:每次启动都重建表(慎用)create-drop:启动时创建,关闭时删除
生产环境建议设置为 none,通过 flyway 或 liquibase 管理数据库版本。
1.4 定义实体类(entity)
创建一个用户实体类,映射到数据库表 user:
import javax.persistence.*;
@entity
@table(name = "user")
public class user {
@id
@generatedvalue(strategy = generationtype.identity)
private long id;
@column(name = "name", length = 50, nullable = false)
private string name;
@column(name = "age")
private integer age;
@column(name = "email", unique = true)
private string email;
// 构造方法
public user() {}
public user(string name, integer age, string email) {
this.name = name;
this.age = age;
this.email = email;
}
// getter 和 setter 方法省略...
}
1.5 创建 repository 接口
spring data jpa 的强大之处在于只需定义接口,无需编写实现类即可完成 crud 操作。
import org.springframework.data.jpa.repository.jparepository;
import org.springframework.stereotype.repository;
@repository
public interface userrepository extends jparepository<user, long> {
// 根据姓名查询(方法名解析)
list<user> findbyname(string name);
// 根据姓名和年龄查询
list<user> findbynameandage(string name, integer age);
// 模糊查询
list<user> findbynamecontaining(string keyword);
// 使用 @query 注解自定义 sql
@query("select u from user u where u.age > :age")
list<user> findbyagegreaterthan(@param("age") integer age);
}
方法名解析机制:spring data jpa 支持通过方法名自动生成查询语句,如 findbyxxxandyyy、findbyxxxorderbyyyydesc 等。
1.6 编写 service 层逻辑
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;
import org.springframework.transaction.annotation.transactional;
import java.util.list;
import java.util.optional;
@service
@transactional
public class userservice {
@autowired
private userrepository userrepository;
public list<user> findall() {
return userrepository.findall();
}
public user findbyid(long id) {
optional<user> user = userrepository.findbyid(id);
return user.orelse(null);
}
public user save(user user) {
return userrepository.save(user);
}
public void deletebyid(long id) {
userrepository.deletebyid(id);
}
public list<user> searchbyname(string name) {
return userrepository.findbynamecontaining(name);
}
}
1.7 控制器层暴露接口
import org.springframework.web.bind.annotation.*;
import java.util.list;
@restcontroller
@requestmapping("/api/users")
public class usercontroller {
@autowired
private userservice userservice;
@getmapping
public list<user> getall() {
return userservice.findall();
}
@getmapping("/{id}")
public user getbyid(@pathvariable long id) {
return userservice.findbyid(id);
}
@postmapping
public user create(@requestbody user user) {
return userservice.save(user);
}
@putmapping("/{id}")
public user update(@pathvariable long id, @requestbody user user) {
user.setid(id);
return userservice.save(user);
}
@deletemapping("/{id}")
public void delete(@pathvariable long id) {
userservice.deletebyid(id);
}
}
1.8 测试验证
启动应用后,可通过 postman 或 curl 测试:
curl -x post http://localhost:8080/api/users \
-h "content-type: application/json" \
-d '{"name":"张三","age":25,"email":"zhangsan@example.com"}'
查看控制台输出的 sql 是否正常执行。
二、集成 druid 数据源提升性能与监控能力
虽然 spring boot 默认使用 hikaricp 作为连接池,但在国内企业级项目中,druid 因其强大的监控功能和稳定性被广泛采用。
2.1 引入 druid 依赖
<dependency>
<groupid>com.alibaba</groupid>
<artifactid>druid-spring-boot-starter</artifactid>
<version>1.2.11</version>
</dependency>
2.2 配置 druid 数据源
修改 application.yml:
spring:
datasource:
type: com.alibaba.druid.pool.druiddatasource
druid:
# 基础连接属性
driver-class-name: com.mysql.cj.jdbc.driver
url: jdbc:mysql://localhost:3306/springboot_db?usessl=false&servertimezone=utc
username: root
password: yourpassword
# 连接池配置
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打开 pscache,并指定每个连接上 pscache 的大小
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的 filters
filters: stat,wall,log4j
# sql 防火墙和慢 sql 记录
connection-properties: druid.stat.mergesql=true;druid.stat.slowsqlmillis=5000
2.3 配置监控页面(statviewservlet)
创建配置类启用 druid 监控:
import com.alibaba.druid.spring.boot.autoconfigure.druiddatasourcebuilder;
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 {
@bean
@configurationproperties("spring.datasource.druid")
public datasource datasource() {
return druiddatasourcebuilder.create().build();
}
@bean
public servletregistrationbean<statviewservlet> statviewservlet() {
statviewservlet servlet = new statviewservlet();
servletregistrationbean<statviewservlet> bean = new servletregistrationbean<>(servlet, "/druid/*");
map<string, string> initparams = new hashmap<>();
initparams.put("loginusername", "admin");
initparams.put("loginpassword", "123456");
initparams.put("allow", ""); // 允许所有人访问
initparams.put("deny", "192.168.1.1"); // 拒绝特定 ip
bean.setinitparameters(initparams);
return bean;
}
@bean
public filterregistrationbean<webstatfilter> webstatfilter() {
webstatfilter filter = new webstatfilter();
filterregistrationbean<webstatfilter> bean = new filterregistrationbean<>(filter);
bean.seturlpatterns(arrays.aslist("/*"));
bean.addinitparameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return bean;
}
}
访问 http://localhost:8080/druid 即可进入监控页面,查看:
- sql 执行次数、耗时
- 连接池状态
- 慢 sql 日志
- web 请求统计
三、使用 mybatis 进行灵活 sql 控制
当业务逻辑复杂、需要精细控制 sql 时,mybatis 是更合适的选择。
3.1 添加依赖
<dependency>
<groupid>org.mybatis.spring.boot</groupid>
<artifactid>mybatis-spring-boot-starter</artifactid>
<version>2.3.1</version>
</dependency>
3.2 配置 mybatis
mybatis:
mapper-locations: classpath:mapping/*.xml
type-aliases-package: com.example.entity
configuration:
map-underscore-to-camel-case: true # 开启驼峰映射
log-impl: org.apache.ibatis.logging.stdout.stdoutimpl # 控制台打印 sql
3.3 编写 mapper 接口与 xml 映射文件
接口:
@mapper
public interface usermapper {
list<user> findall();
user findbyid(long id);
int insert(user user);
int update(user user);
int deletebyid(long id);
}
xml 文件(src/main/resources/mapping/usermapper.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.example.mapper.usermapper">
<resultmap id="baseresultmap" type="com.example.entity.user">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
</resultmap>
<select id="findall" resultmap="baseresultmap">
select * from user
</select>
<select id="findbyid" parametertype="long" resultmap="baseresultmap">
select * from user where id = #{id}
</select>
<insert id="insert" parametertype="com.example.entity.user" usegeneratedkeys="true" keyproperty="id">
insert into user(name, age, email) values (#{name}, #{age}, #{email})
</insert>
<update id="update" parametertype="com.example.entity.user">
update user set name=#{name}, age=#{age}, email=#{email} where id=#{id}
</update>
<delete id="deletebyid" parametertype="long">
delete from user where id = #{id}
</delete>
</mapper>
3.4 使用注解方式(可选)
对于简单 sql,可以直接使用注解:
@mapper
public interface usermapper {
@select("select * from user where id = #{id}")
user findbyid(@param("id") long id);
@insert("insert into user(name, age, email) values (#{name}, #{age}, #{email})")
@options(usegeneratedkeys = true, keyproperty = "id")
int insert(user user);
}
四、整合 mybatis-plus 提升开发效率
mybatis-plus 是 mybatis 的增强工具,提供了通用 crud、分页、代码生成等功能,极大提升开发效率。
4.1 添加依赖
<dependency>
<groupid>com.baomidou</groupid>
<artifactid>mybatis-plus-boot-starter</artifactid>
<version>3.5.3.1</version>
</dependency>
4.2 配置插件(分页支持)
@configuration
@mapperscan("com.example.mapper")
public class mybatisplusconfig {
@bean
public mybatisplusinterceptor mybatisplusinterceptor() {
mybatisplusinterceptor interceptor = new mybatisplusinterceptor();
// 添加分页插件
interceptor.addinnerinterceptor(new paginationinnerinterceptor(dbtype.mysql));
return interceptor;
}
}
4.3 定义实体与 mapper
@data
@tablename("user")
public class user {
@tableid(type = idtype.auto)
private long id;
private string name;
private integer age;
private string email;
}
@mapper
public interface usermapper extends basemapper<user> {
}
4.4 使用内置方法完成 crud
@service
public class userservice {
@autowired
private usermapper usermapper;
public list<user> listall() {
return usermapper.selectlist(null);
}
public ipage<user> page(int pagenum, int pagesize) {
page<user> page = new page<>(pagenum, pagesize);
return usermapper.selectpage(page, null);
}
public list<user> searchbyname(string name) {
querywrapper<user> wrapper = new querywrapper<>();
wrapper.like("name", name);
return usermapper.selectlist(wrapper);
}
}
4.5 条件构造器(querywrapper)
querywrapper<user> wrapper = new querywrapper<>();
wrapper.gt("age", 18)
.like("name", "王")
.orderbydesc("id");
list<user> users = usermapper.selectlist(wrapper);
五、其他数据库访问方式简述
| 方式 | 特点 |
|---|---|
| jdbctemplate | 轻量级,适合简单 sql,需手动映射结果 |
| spring data jdbc | 轻量 orm,比 jpa 简单,适合简单对象映射 |
| r2dbc | 响应式数据库连接,适用于 webflux 架构 |
六、总结与选型建议
| 技术 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| jpa | 快速开发,自动 crud | sql 控制弱,学习曲线陡 | 中小型项目、快速原型 |
| mybatis | sql 灵活,易于优化 | 需写 xml,维护成本高 | 复杂查询、遗留系统 |
| mybatis-plus | 开发效率极高,功能丰富 | 对新手有一定门槛 | 推荐首选,尤其互联网项目 |
| jdbctemplate | 轻量、直接 | 无 orm,编码繁琐 | 简单脚本、工具类 |
| druid | 监控能力强,稳定 | 配置较复杂 | 所有生产环境推荐集成 |
最终建议:
- 若追求开发效率与功能完整性,推荐 mybatis-plus + druid
- 若团队熟悉 jpa 且项目偏重领域模型,可选择 spring data jpa
- 若为高并发响应式系统,则考虑 r2dbc
通过本文的详细讲解,相信你已经掌握了 spring boot 2 中各种数据库操作方式的核心要点。在实际项目中,合理选择技术栈,结合业务需求,才能构建出高性能、易维护的应用系统。
以上就是springboot2中常见的数据库访问方法详解的详细内容,更多关于springboot数据库访问的资料请关注代码网其它相关文章!
发表评论