跳到主要内容
Spring Boot 数据访问与数据库集成实战 | 极客日志
Java java
Spring Boot 数据访问与数据库集成实战 综述由AI生成 Spring Boot 通过 Starter 机制大幅简化了数据库集成流程。本文涵盖 MySQL、H2、MyBatis 及 JPA 的接入配置,详解实体映射、Repository 接口设计及事务注解的使用。结合实战代码示例,展示如何快速构建增删改查功能并处理常见数据持久化问题,帮助开发者高效完成企业级应用的数据层开发。
神经兮兮 发布于 2026/3/24 更新于 2026/5/13 8 浏览Spring Boot 数据访问与数据库集成
在 Spring Boot 开发中,数据持久化是核心环节。通过 Starter 机制,我们可以快速接入各种数据库和 ORM 框架,无需繁琐的配置。本文将深入探讨 MySQL、H2、MyBatis 及 JPA 的集成方式,并结合事务管理和实际场景,帮助你构建稳健的数据层。
数据访问概述
Spring Boot 提供了多种数据访问方案,常见的包括:
JdbcTemplate :适合轻量级 JDBC 操作。
JPA (Hibernate) :对象关系映射标准,支持自动 SQL 生成。
MyBatis :灵活控制 SQL,适合复杂查询。
Hibernate :底层 ORM 实现,通常配合 JPA 使用。
这些组件都能通过 spring-boot-starter 依赖快速引入,并在 application.properties 中统一配置。
集成 MySQL
MySQL 是最常用的生产环境数据库。集成步骤相对固定,主要涉及依赖添加、配置连接及实体映射。
1. 添加依赖
在 pom.xml 中加入 Web、JPA 和 MySQL 驱动依赖:
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-data-jpa</artifactId >
</dependency >
<dependency >
<groupId > mysql</ >
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test
groupId
<artifactId >
</artifactId >
<scope >
</scope >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<scope >
</scope >
</dependency >
</dependencies >
2. 配置文件 在 application.properties 中指定数据源和 JPA 行为:
# 服务器端口
server.port=8080
# 数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
# JPA 配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
3. 实体与 Repository 定义 Product 实体类,使用 JPA 注解映射表结构:
import javax.persistence.*;
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String productId;
private String productName;
private double price;
private int sales;
public Product () {}
public Product (String productId, String productName, double price, int sales) {
this .productId = productId;
this .productName = productName;
this .price = price;
this .sales = sales;
}
@Override
public String toString () {
return "Product{" +
"id=" + id +
", productId='" + productId + '\'' +
", productName='" + productName + '\'' +
", price=" + price +
", sales=" + sales +
'}' ;
}
}
创建 Repository 接口继承 JpaRepository,即可自动获得基础 CRUD 能力:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductRepository extends JpaRepository <Product, Long> {
List<Product> findBySalesGreaterThan (int sales) ;
}
4. 控制器与测试 结合 @RestController 暴露 API,并编写单元测试验证逻辑:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductRepository productRepository;
@GetMapping("/")
public List<Product> getAllProducts () {
return productRepository.findAll();
}
@PostMapping("/")
public Product addProduct (@RequestBody Product product) {
return productRepository.save(product);
}
@GetMapping("/top-selling")
public List<Product> getTopSellingProducts (@RequestParam int topN) {
List<Product> products = productRepository.findBySalesGreaterThan(0 );
products.sort((p1, p2) -> p2.getSales() - p1.getSales());
if (products.size() > topN) {
return products.subList(0 , topN);
}
return products;
}
}
集成 H2 数据库 H2 内存数据库非常适合开发和测试阶段,启动快且无需安装。配置上只需替换数据源 URL 和驱动类名。
# H2 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# 开启 H2 控制台方便调试
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
其余代码结构与 MySQL 集成基本一致,这使得我们可以在不同环境中复用同一套数据访问逻辑。
集成 MyBatis 当需要更精细地控制 SQL 语句时,MyBatis 是更好的选择。它通过 XML 或注解映射 SQL 与 Java 对象。
1. 依赖与配置 <dependency >
<groupId > org.mybatis.spring.boot</groupId >
<artifactId > mybatis-spring-boot-starter</artifactId >
<version > 2.3.0</version >
</dependency >
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.demo.entity
2. Mapper 接口与 XML 定义 Mapper 接口,并在 XML 文件中编写具体 SQL:
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ProductMapper {
List<Product> findAll () ;
int insert (Product product) ;
List<Product> findBySalesGreaterThan (int sales) ;
}
<?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.demo.mapper.ProductMapper" >
<resultMap id ="ProductResultMap" type ="com.example.demo.entity.Product" >
<id property ="id" column ="id" />
<result property ="productId" column ="product_id" />
<result property ="productName" column ="product_name" />
<result property ="price" column ="price" />
<result property ="sales" column ="sales" />
</resultMap >
<select id ="findAll" resultMap ="ProductResultMap" >
SELECT * FROM product
</select >
<insert id ="insert" parameterType ="com.example.demo.entity.Product" >
INSERT INTO product (product_id, product_name, price, sales) VALUES (#{productId}, #{productName}, #{price}, #{sales})
</insert >
<select id ="findBySalesGreaterThan" parameterType ="int" resultMap ="ProductResultMap" >
SELECT * FROM product WHERE sales > #{sales}
</select >
</mapper >
事务管理 在数据访问层,保证数据的一致性至关重要。Spring Boot 通过 @Transactional 注解轻松实现声明式事务。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void addProduct (Product product) {
productRepository.save(product);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts () {
return productRepository.findAll();
}
}
注意:@Transactional 默认只在运行时异常(RuntimeException)发生时回滚,检查型异常不会触发回滚。只读查询建议加上 readOnly = true 以提升性能。
实际应用场景 综合上述技术点,我们可以构建一个完整的商品管理系统。从初始化数据到 API 响应,流程如下:
启动初始化 :在应用启动时预置测试数据。
业务服务层 :封装事务逻辑,确保增删改操作的原子性。
控制器层 :接收 HTTP 请求,返回 JSON 格式数据。
[
{ "id" : 4 , "productId" : "P004" , "productName" : "手表" , "price" : 500.0 , "sales" : 200 } ,
{ "id" : 5 , "productId" : "P005" , "productName" : "耳机" , "price" : 300.0 , "sales" : 150 } ,
{ "id" : 1 , "productId" : "P001" , "productName" : "手机" , "price" : 1500.0 , "sales" : 120 }
]
总结 Spring Boot 极大地降低了数据库集成的门槛。无论是追求开发效率的 JPA,还是强调 SQL 控制的 MyBatis,都能通过简单的配置快速落地。在实际项目中,根据业务复杂度选择合适的方案,并规范事务管理,是构建高质量后端服务的关键。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online