java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot JdbcTemplate数据访问层

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

作者:希望永不加班

文章介绍了SpringBoot中使用JdbcTemplate操作数据库的优势、使用场景、引入依赖、配置方式、常用方法、封装Service层和Controller接口等内容,并提供了简单的示例代码,最后总结了JdbcTemplate与MyBatis的选择原则和注意事项,需要的朋友可以参考下

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

一、JdbcTemplate 适合什么场景?

优点:

二、引入依赖

只需要 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 常用方法:

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 如何选择?

十一、注意事项

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

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

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

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

十二、总结

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

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

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

您可能感兴趣的文章:
阅读全文