目录
- 前言
- 一、使用 Spring Data JPA 实现 ORM 操作
- 1.1 什么是 JPA
- 1.2 添加依赖并启用 JPA
- 1.3 配置数据库连接信息
- 1.4 定义实体类(Entity)
- 1.5 创建 Repository 接口
- 1.6 编写 Service 层逻辑
- 1.7 控制器层暴露接口
- 1.8 测试验证
- 二、集成 Druid 数据源提升性能与监控能力
- 2.1 引入 Druid 依赖
- 2.2 配置 Druid 数据源
- 2.3 配置监控页面(StatViewServlet)
- 三、使用 MyBATis 进行灵活 SQL 控制
- 3.1 添加依赖
- 3.2 配置 MyBatis
- 3.3 编写 Mapper 接口与 XML 映射文件
- 3.4 使用注解方式(可选)
- 四、整合 MyBatis-Plus 提升开发效率
- 4.1 添加依赖
- 4.2 配置插件(分页支持)
- 4.3 定义实体与 Mapper
- 4.4 使用内置方法完成 CRUD
- 4.5 条件构造器(QueryWrapper)
- 五、其他数据库访问方式简述
- 六、总结与选型建议
前言
在现代 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"thFHWMFyQM, 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 php 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 UserMa编程客栈pper { @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&ljst;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数据库访问的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论