SpringBoot整合JdbcTemplate快速开发数据访问层

 更新时间:2026年04月03日 09:29:23   作者:希望永不加班  
文章介绍了SpringBoot中使用JdbcTemplate操作数据库的优势、使用场景、引入依赖、配置方式、常用方法、封装Service层和Controller接口等内容,并提供了简单的示例代码,最后总结了JdbcTemplate与MyBatis的选择原则和注意事项,需要的朋友可以参考下

很多人一提到 SpringBoot 操作数据库,就只想到 MyBatis、JPA,其实在很多简单业务、小工具项目、后台管理模块里,根本没必要上重型框架。JdbcTemplate 才是轻量、简单、开箱即用的神器,没有复杂配置、没有 XML、没有各种插件,几行代码就能完成增删改查,非常适合快速开发。

一、JdbcTemplate 适合什么场景?

  • 单表简单业务,不想写 MyBatis XML/注解
  • 微服务内部小模块、轻量接口
  • 快速原型开发、临时数据处理
  • 对 SQL 可控,但又不想引入复杂 ORM

优点:

  • 极轻量,无额外依赖
  • 直接写原生 SQL,灵活直观
  • 性能接近原生 JDBC,无损耗
  • Spring 自带,自动整合事务

二、引入依赖

只需要 web + jdbc + mysql 驱动即可:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

三、application.yml 配置

和 MyBatis 数据源配置完全一样:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

不需要任何额外配置,启动项目自动装配 JdbcTemplate

四、建表 SQL

CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

五、实体类 User

package com.demo.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
    private Long id;
    private String username;
    private Integer age;
    private String email;
    private LocalDateTime createTime;
}

六、直接使用 JdbcTemplate(最简洁方式)

JdbcTemplate 常用方法:

  • update():增、删、改
  • queryForObject():查询单个对象
  • query():查询列表
  • batchUpdate():批量操作

1. 新增

@Autowired
private JdbcTemplate jdbcTemplate;
public int addUser(User user) {
    String sql = "insert into user(username, age, email) values(?, ?, ?)";
    return jdbcTemplate.update(
            sql,
            user.getUsername(),
            user.getAge(),
            user.getEmail()
    );
}

2. 删除

public int deleteById(Long id) {
    String sql = "delete from user where id=?";
    return jdbcTemplate.update(sql, id);
}

3. 修改

public int updateUser(User user) {
    String sql = "update user set username=?, age=?, email=? where id=?";
    return jdbcTemplate.update(
            sql,
            user.getUsername(),
            user.getAge(),
            user.getEmail(),
            user.getId()
    );
}

4. 根据 ID 查询单个对象

public User findById(Long id) {
    String sql = "select * from user where id=?";
    return jdbcTemplate.queryForObject(
            sql,
            new BeanPropertyRowMapper<>(User.class),
            id
    );
}

5. 查询列表

public List<User> findAll() {
    String sql = "select * from user";
    return jdbcTemplate.query(
            sql,
            new BeanPropertyRowMapper<>(User.class)
    );
}

6. 带条件查询

public List<User> findByAge(Integer age) {
    String sql = "select * from user where age=?";
    return jdbcTemplate.query(
            sql,
            new BeanPropertyRowMapper<>(User.class),
            age
    );
}

7. 统计数量

public Long count() {
    String sql = "select count(*) from user";
    return jdbcTemplate.queryForObject(sql, Long.class);
}

8. 批量插入

public void batchAdd(List<User> userList) {
    String sql = "insert into user(username, age, email) values(?,?,?)";
    jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            User user = userList.get(i);
            ps.setString(1, user.getUsername());
            ps.setInt(2, user.getAge());
            ps.setString(3, user.getEmail());
        }
        @Override
        public int getBatchSize() {
            return userList.size();
        }
    });
}

七、封装成标准 Service 层

@Service
public class UserService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    // 新增
    @Transactional(rollbackFor = Exception.class)
    public boolean add(User user) {
        String sql = "insert into user(username,age,email) values(?,?,?)";
        return jdbcTemplate.update(sql, user.getUsername(), user.getAge(), user.getEmail()) > 0;
    }
    // 删除
    @Transactional
    public boolean delete(Long id) {
        String sql = "delete from user where id=?";
        return jdbcTemplate.update(sql, id) > 0;
    }
    // 修改
    @Transactional
    public boolean update(User user) {
        String sql = "update user set username=?,age=?,email=? where id=?";
        return jdbcTemplate.update(sql,
                user.getUsername(),
                user.getAge(),
                user.getEmail(),
                user.getId()) > 0;
    }
    // 根据ID查询
    public User findById(Long id) {
        String sql = "select * from user where id=?";
        try {
            return jdbcTemplate.queryForObject(
                    sql,
                    new BeanPropertyRowMapper<>(User.class),
                    id);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }
    // 查询全部
    public List<User> list() {
        String sql = "select * from user";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
    }
}

注意:
queryForObject 查询不到会抛异常,必须 try-catch 处理。

八、Controller 接口

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping("/add")
    public Result add(@RequestBody User user) {
        userService.add(user);
        return Result.success("添加成功");
    }
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Long id) {
        userService.delete(id);
        return Result.success("删除成功");
    }
    @PutMapping("/update")
    public Result update(@RequestBody User user) {
        userService.update(user);
        return Result.success("修改成功");
    }
    @GetMapping("/{id}")
    public Result findById(@PathVariable Long id) {
        return Result.success(userService.findById(id));
    }
    @GetMapping("/list")
    public Result list() {
        return Result.success(userService.list());
    }
}

九、JdbcTemplate 事务支持

直接使用 @Transactional 即可,和 MyBatis 完全一致:

@Transactional(rollbackFor = Exception.class)
public void testTransaction() {
    // 两次修改,要么都成功,要么都回滚
    jdbcTemplate.update("update user set age=20 where id=1");
    int i = 1 / 0; // 模拟异常
    jdbcTemplate.update("update user set age=30 where id=2");
}

十、JdbcTemplate 与 MyBatis 如何选择?

  • 简单单表、快速开发 → JdbcTemplate
  • 复杂查询、多表关联、动态SQL → MyBatis
  • 企业后台管理系统 → MyBatis 更易维护
  • 小接口、轻量服务 → JdbcTemplate 更清爽

十一、注意事项

1. 查询不到数据报错
queryForObject 无数据会抛异常,需要捕获 EmptyResultDataAccessException

2. 类型不匹配
数据库日期、数字类型要与实体类对应

3. SQL 注入风险
必须使用 ? 占位符,不要字符串拼接

4. 批量操作性能
大量数据建议分批插入,避免一次过大

十二、总结

SpringBoot 整合 JdbcTemplate 可以说是最简单的数据层方案
只需要引入 spring-boot-starter-jdbc,自动装配,直接写 SQL 就能完成所有操作。

没有配置、没有 XML、没有学习成本,非常适合小项目、快速开发场景,也是 Spring 生态最原生的数据访问方式。

以上就是SpringBoot整合JdbcTemplate快速开发数据访问层的详细内容,更多关于SpringBoot JdbcTemplate数据访问层的资料请关注脚本之家其它相关文章!

相关文章

  • 解决springdataJPA对原生sql支持的问题

    解决springdataJPA对原生sql支持的问题

    这篇文章主要介绍了解决springdataJPA对原生sql支持的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot中的CompletableFuture类详解

    SpringBoot中的CompletableFuture类详解

    这篇文章主要介绍了SpringBoot中的CompletableFuture类详解,在 Java8中,引入了CompletableFuture类,它提供了一种简单而强大的方式来执行异步任务,今天我们就来详细解读一下这个类,需要的朋友可以参考下
    2023-07-07
  • 在IntelliJ IDEA中配置Git过程

    在IntelliJ IDEA中配置Git过程

    本文介绍了在IntelliJ IDEA中配置Git的全过程,包括安装Git、在IDEA中配置Git路径以及在项目中启用Git,具体步骤分为三步:安装Git,配置IDEA中的Git路径,并在项目中启用Git,最后,还介绍了基本操作与进阶配置,如提交代码、推送/拉取代码、设置Git用户名等
    2026-04-04
  • ElasticSearch添加索引代码实例解析

    ElasticSearch添加索引代码实例解析

    这篇文章主要介绍了ElasticSearch添加索引代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • springboot2启动时执行,初始化(或定时任务)servletContext问题

    springboot2启动时执行,初始化(或定时任务)servletContext问题

    这篇文章主要介绍了springboot2启动时执行,初始化(或定时任务)servletContext问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • SpringAop中AspectJ框架的切入点表达式

    SpringAop中AspectJ框架的切入点表达式

    这篇文章主要介绍了SpringAop中AspectJ框架的切入点表达式,AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持,@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面,需要的朋友可以参考下
    2023-08-08
  • MyBatis游标Cursor的正确使用和百万数据传输的内存测试

    MyBatis游标Cursor的正确使用和百万数据传输的内存测试

    这篇文章主要介绍了MyBatis游标Cursor的正确使用和百万数据传输的内存测试,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java中Synchronized锁的使用和原理详解

    Java中Synchronized锁的使用和原理详解

    这篇文章主要介绍了Java中Synchronized锁的使用和原理详解,synchronized是 Java 内置的关键字,它提供了一种独占的加锁方式,synchronized的获取和释放锁由JVM实现,用户不需要显示的释放锁,非常方便,需要的朋友可以参考下
    2023-07-07
  • Maven 自动化构建的实现示例

    Maven 自动化构建的实现示例

    本文主要介绍了Maven 自动化构建的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-05-05
  • 解决springboot整合cxf-jaxrs中json转换的问题

    解决springboot整合cxf-jaxrs中json转换的问题

    这篇文章主要介绍了解决springboot整合cxf-jaxrs中json转换的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07

最新评论