跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Javajava

SpringBoot 整合 Spring Data JDBC

Spring Data JDBC 是 Spring 提供的轻量级持久化方案,无需 Hibernate 等 ORM 框架。它通过约定优于配置实现对象与数据库表的映射,支持@Table、@Id 等注解定义实体结构。开发者可通过继承 CrudRepository 接口获得基础 CRUD 能力,利用方法名关键字查询或@Query 注解编写自定义 SQL。相比 Spring Data JPA,它更简单且无复杂生命周期管理,适合简单场景。文章演示了 User 实体定义、DAO 接口设计、自定义查询实现及测试类编写,包含完整的 Maven 依赖配置与数据库连接设置。

zhang发布于 2025/2/23更新于 2026/4/231 浏览
SpringBoot 整合 Spring Data JDBC

SpringBoot 整合 Spring Data JDBC

Spring Data JDBC 是 Spring 提供的轻量级持久化方案,无需 Hibernate 等 ORM 框架。它通过约定优于配置实现对象与数据库表的映射,支持@Table、@Id 等注解定义实体结构。开发者可通过继承 CrudRepository 接口获得基础 CRUD 能力,利用方法名关键字查询或@Query 注解编写自定义 SQL。相比 Spring Data JPA,它更简单且无复杂生命周期管理,适合简单场景。

Spring Data JDBC 功能

  • DAO 接口只需继承 CrudRepository 或 PagingAndSortingRepository,Spring Data JDBC 能为 DAO 组件生成实现类。
  • 支持方法名关键字查询。
  • 支持用@Query 定义查询语句。
  • 支持添加自定义的查询方法(通过额外的父接口及实现类)。
  • 一般不支持样本查询和 Specification 查询。

Spring Data JDBC 映射规则

默认采用同名映射:

  • User 对象对应 user 表。
  • id 列自动映射到对象的 id 属性。

常用注解:

  • @Table:映射自定义表名(非 JPA 注解)。
  • @Column:映射自定义列名(非 JPA 注解)。
  • @Id:修饰标识属性(非 JPA 注解)。
  • @PersistenceConstructor:修饰主构造器,指定用于创建对象的构造器。

编程步骤

  1. 定义映射类,为 Java 类添加@Table、@Column、@Id 和 @PersistenceConstructor。
  2. 让 DAO 接口继承 CrudRepository 或 PagingAndSortingRepository。
  3. 在 DAO 接口中定义方法名关键字查询、@Query 查询、完全自定义查询。

代码演示

User 类
package cn.ljh.app.domain;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;

@Data
@Table("user_inf")
public class User {

    @Column(value = "user_id")
    @Id
    private Integer id;
    private String name;
    private String password;
    private int age;

    @PersistenceConstructor
    public User() {}

    public User(Integer id, String name, String password, int age) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}
UserDao 接口
package cn.ljh.app.dao;

import cn.ljh.app.domain.User;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface UserDao extends CrudRepository<User,Integer>, CustomUserDao {
    // 根据名字模糊查询
    List<User> findByNameLike(String namePattern);
    // 根据年龄大小进行范围查询
    List<User> findByAgeGreaterThan(int startAge);
    List<User> findByAgeLessThan(int age);
    // 根据年龄区间进行范围查询
    List<User> findByAgeBetween(int startAge, int endAge);

    // 根据密码模糊查询
    @Query("select * from user_inf where password like :passwordPattern")
    List<User> findBySql(String passwordPattern);

    // 根据年龄范围修改名字
    @Query("update user_inf set name = :name where age between :startAge and :endAge")
    @Modifying
    int updateNameByAge(String name, int startAge, int endAge);
}
CustomUserDao 接口
package cn.ljh.app.dao;

import cn.ljh.app.domain.User;

import java.util.List;

public interface CustomUserDao {
    // 通过名字进行模糊查询,使用 dataSource
    List<User> customQueryUsingConnection(String namePattern);
    // 通过名字进行模糊查询,使用 jdbcTemplate
    List<User> customQueryUsingTemplate(String namePattern);
}
CustomUserDaoImpl 实现类
package cn.ljh.app.dao.impl;

import cn.ljh.app.dao.CustomUserDao;
import cn.ljh.app.domain.User;
import lombok.SneakyThrows;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.sql.Array;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class CustomUserDaoImpl implements CustomUserDao {
    private DataSource dataSource;
    private JdbcTemplate jdbcTemplate;

    public CustomUserDaoImpl(DataSource dataSource, JdbcTemplate jdbcTemplate) {
        this.dataSource = dataSource;
        this.jdbcTemplate = jdbcTemplate;
    }

    @SneakyThrows
    @Override
    public List<User> customQueryUsingConnection(String namePattern) {
        Connection connection = this.dataSource.getConnection();
        PreparedStatement pstmt = connection.prepareStatement("select * from user_inf where name like ?");
        pstmt.setString(1, namePattern);
        ResultSet rs = pstmt.executeQuery();
        List<User> userList = new ArrayList<>();
        while (rs.next()) {
            userList.add(new User(
                    rs.getInt("user_id"),
                    rs.getString("name"),
                    rs.getString("password"),
                    rs.getInt("age")
            ));
        }
        return userList;
    }

    @Override
    public List<User> customQueryUsingTemplate(String namePattern) {
        List<User> userList = this.jdbcTemplate.query(
                "select user_id as id,name ,password,age from user_inf where name like ?",
                new BeanPropertyRowMapper<>(User.class),
                namePattern
        );
        return userList;
    }
}
UserDaoTest 测试类
package cn.ljh.app;

import cn.ljh.app.dao.UserDao;
import cn.ljh.app.domain.User;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UserDaoTest {
    @Autowired
    private UserDao userDao;

    @ParameterizedTest
    @CsvSource({"aa,xxx,2", "bb,xxx,3"})
    public void testSave(String name, String password, int age) {
        User user = userDao.save(new User(null, name, password, age));
        System.err.println(user);
    }

    @ParameterizedTest
    @CsvSource({"13,aaa,xxxx,22"})
    public void testUpdate(Integer id, String name, String password, int age) {
        User user = userDao.save(new User(id, name, password, age));
        System.err.println(user);
    }

    @ParameterizedTest
    @ValueSource(ints = {14})
    public void testDelete(Integer id) {
        userDao.deleteById(id);
    }

    @ParameterizedTest
    @ValueSource(ints = {1})
    public void testFindById(Integer id) {
        Optional<User> user = userDao.findById(id);
    }

    @ParameterizedTest
    @ValueSource(strings = {"孙%", "%精"})
    public void testFindByNameLike(String namePattern) {
        List<User> users = userDao.findByNameLike(namePattern);
        users.forEach(System.err::println);
    }

    @ParameterizedTest
    @ValueSource(ints = {500, 10})
    public void testFindByAgeGreaterThan(int startAge) {
        List<User> users = userDao.findByAgeGreaterThan(startAge);
        users.forEach(System.err::println);
    }

    @ParameterizedTest
    @ValueSource(ints = {20})
    public void testFindByAgeLessThan(int age) {
        List<User> users = userDao.findByAgeLessThan(age);
        users.forEach(System.err::println);
    }

    @ParameterizedTest
    @CsvSource({"15,20", "500,1000"})
    public void testFindByAgeBetween(int startAge, int endAge) {
        List<User> users = userDao.findByAgeBetween(startAge, endAge);
        users.forEach(System.err::println);
    }

    @ParameterizedTest
    @ValueSource(strings = {"niu%", "%3"})
    public void testFindBySql(String passwordPattern) {
        List<User> users = userDao.findBySql(passwordPattern);
        users.forEach(System.err::println);
    }

    @ParameterizedTest
    @CsvSource({"牛魔王 aa,800,1000"})
    @Transactional
    @Rollback(false)
    public void testUpdateNameByAge(String name, int startAge, int endAge) {
        int i = userDao.updateNameByAge(name, startAge, endAge);
    }

    @ParameterizedTest
    @ValueSource(strings = {"孙%"})
    public void testCustomQueryUsingConnection(String namePattern) {
        List<User> users = userDao.customQueryUsingConnection(namePattern);
        users.forEach(System.err::println);
    }

    @ParameterizedTest
    @ValueSource(strings = {"孙%"})
    public void testCustomQueryUsingTemplate(String namePattern) {
        List<User> users = userDao.customQueryUsingTemplate(namePattern);
        users.forEach(System.err::println);
    }
}
application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>
    <groupId>cn.ljh</groupId>
    <artifactId>Spring_Data_JDBC</artifactId>
    <version>1.0.0</version>
    <name>Spring_Data_JDBC</name>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

目录

  1. SpringBoot 整合 Spring Data JDBC
  2. Spring Data JDBC 功能
  3. Spring Data JDBC 映射规则
  4. 编程步骤
  5. 代码演示
  6. User 类
  7. UserDao 接口
  8. CustomUserDao 接口
  9. CustomUserDaoImpl 实现类
  10. UserDaoTest 测试类
  11. application.properties
  12. pom.xml
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • Linux LVM 磁盘管理工具详解:物理卷、卷组与逻辑卷操作
  • 软件设计各个模块分析
  • 交换瓶子问题 Java 最小交换次数解法
  • Java Cookie 技术原理与应用
  • CopyOnWriteArrayList 源码解析
  • Python 学习后如何找工作及就业方向分析
  • Windows 环境下如何将本地代码推送到 Git 远程仓库
  • Vue 中使用 Less 样式预处理
  • 大语言模型框架-Megatron-LM 源码分析
  • CSS 子元素选择器
  • Webpack Loader 一览表
  • ThinkPHP 5.1 环境安装与配置指南
  • Ubuntu SSH 服务安装与配置详解
  • 云原生容器技术入门:Docker 与 K8s 基本原理及用途
  • CSS 常用标签与属性详解
  • WebLogic MIB 与 AdventNet MIB Browser 工具使用指南
  • Python 数据结构与算法:搜索算法
  • Java hashCode 方法的作用与重写规范
  • EOS 单向 N 对 1 关联配置与查询机制
  • CentOS 升级 GCC 至 10.1.0 源码编译指南

相关免费在线工具

  • 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