跳到主要内容
Spring Boot 数据访问与数据库集成 | 极客日志
Java java
Spring Boot 数据访问与数据库集成 掌握 Spring Boot 数据访问核心技术与数据库集成方案。内容涵盖 MySQL、H2 及 MyBatis 的依赖配置与连接设置,详解 JPA 实体映射、Repository 接口设计及 MyBatis XML 映射编写。重点解析@Transactional 事务管理机制,提供从 Controller 到 Service 的完整分层架构示例。通过实战对比不同持久层方案,帮助开发者在实际项目中选择合适的技术栈,确保数据一致性与系统可维护性。
DebugKing 发布于 2026/3/27 0 浏览Spring Boot 数据访问与数据库集成
在现代 Java 开发中,高效、安全地管理数据持久化是构建企业级应用的核心。Spring Boot 通过自动配置和简化依赖管理,让开发者能更专注于业务逻辑而非基础设施。本文将深入探讨如何在 Spring Boot 项目中集成主流数据库及 ORM 框架,涵盖 MySQL、H2、MyBatis 以及 JPA 的实战配置与事务管理。
一、数据访问概述
Spring Boot 的数据访问能力主要依托于其强大的生态组件。常见的实现方式包括基于 JDBC 模板的 JdbcTemplate、面向对象的 JPA(通常配合 Hibernate)、以及灵活高效的 MyBatis。这些组件共同支持增删改查(CRUD)、事务控制及数据持久化操作。
二、Spring Boot 与 MySQL 集成
MySQL 是最常用的关系型数据库之一。在 Spring Boot 中集成 MySQL 通常采用 Spring Data JPA 方案,它能显著减少样板代码。
1. 依赖配置
首先需要在 pom.xml 中添加 Web、Data 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 >
< > mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test
groupId
</groupId >
<artifactId >
</artifactId >
<scope >
</scope >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<scope >
</scope >
</dependency >
</dependencies >
2. 配置文件 在 application.properties 中配置连接信息。注意时区设置以避免时间戳问题:
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
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
3. 实体与仓库 定义实体类映射数据库表,并创建 Repository 接口继承 JpaRepository 以获取基础 CRUD 方法:
import javax.persistence.*;
import java.util.List;
@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 +
'}' ;
}
}
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. 控制器与服务 编写 RESTful 接口暴露服务,并在 Service 层处理业务逻辑:
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;
}
}
三、Spring Boot 与 H2 集成 H2 内存数据库非常适合开发和单元测试阶段,无需安装额外软件即可快速验证功能。
1. 依赖与配置 将 MySQL 依赖替换为 H2 依赖,并调整连接 URL:
<dependency >
<groupId > com.h2database</groupId >
<artifactId > h2</artifactId >
<scope > runtime</scope >
</dependency >
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
其余实体类和 Repository 代码与 MySQL 集成保持一致,只需确保数据库 DDL 策略兼容即可。
四、Spring Boot 与 MyBatis 集成 对于需要精细控制 SQL 或处理复杂查询的场景,MyBatis 是更好的选择。
1. 依赖配置 添加 MyBatis Starter 和 MySQL 驱动:
<dependency >
<groupId > org.mybatis.spring.boot</groupId >
<artifactId > mybatis-spring-boot-starter</artifactId >
<version > 2.3.0</version >
</dependency >
2. 配置文件 mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.demo.entity
3. Mapper 接口与 XML MyBatis 需要显式编写 SQL 语句。接口使用 @Mapper 注解标记:
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 文件 (src/main/resources/mapper/ProductMapper.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.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;
import java.util.List;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void addProduct (Product product) {
productRepository.save(product);
}
@Transactional
public void updateProduct (Product product) {
productRepository.save(product);
}
@Transactional
public void deleteProduct (Long id) {
productRepository.deleteById(id);
}
@Transactional(readOnly = true)
public List<Product> getAllProducts () {
return productRepository.findAll();
}
}
注意 :读写分离的事务建议设置 readOnly = true 以提升性能;若方法抛出运行时异常,默认会回滚事务。
六、完整应用场景示例 结合上述组件,我们可以构建一个完整的商品管理系统。以下是一个整合了 Controller、Service、Entity 及启动类的完整结构示例:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.persistence.*;
import java.util.List;
@SpringBootApplication
public class ProductApplication {
public static void main (String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
@Entity
@Table(name = "product")
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;
}
}
@Repository
interface ProductRepository extends JpaRepository <Product, Long> {
List<Product> findBySalesGreaterThan (int sales) ;
}
@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();
}
}
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/")
public List<Product> getAllProducts () {
return productService.getAllProducts();
}
@PostMapping("/")
public void addProduct (@RequestBody Product product) {
productService.addProduct(product);
}
@GetMapping("/top-selling")
public List<Product> getTopSellingProducts (@RequestParam int topN) {
return productService.getAllProducts().stream()
.sorted((p1, p2) -> p2.getSales() - p1.getSales())
.limit(topN)
.toList();
}
}
运行后访问 http://localhost:8080/api/products/top-selling?topN=3 即可查看销量最高的商品列表。这种分层架构不仅清晰易维护,还能有效隔离业务逻辑与数据访问细节。
结语 Spring Boot 提供了丰富的数据访问方案。对于大多数 CRUD 场景,Spring Data JPA 是首选,它能极大提升开发效率;而在涉及复杂查询或遗留系统对接时,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