SpringBoot教程(十) | SpringBoot集成JdbcTemplate

1,546 阅读6分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。

1. JdbcTemplate概述

经过了前面的几篇文章,我们几乎讲解完毕了SpringBoot中前端控制器中的一些操作,体验到SpringBoot为我们使用框架所带来的便捷。前面文章中的所有案例,总共只引入了一个 web-starter, 配置也很少。从今天开始,我们来开始研究一下,SpringBoot如何完成数据的持久化操作。

一般持久化的操作都是有一些专门来做持久化的框架来完成的,比如原始一些的JDBC, 老牌劲旅JPA(hibernate), 还有现在用的比较或的mybatis和MybatisPlus, 而SpringBoot中我们也是先要选择要使用的持久层框架,然后使用SpringBoot进行集成。而集成的步骤由于SpringBoot的自动化配置功能而大大简化。

今天我们先来搞个简单点的,先来个JdbcTemplate, 这个是Spring基于Jdbc而封装的一个持久层框架,致力于轻量、便捷地操作数据库。他的操作很简单,但是不如mybatis和jpa功能全面,但是比原生jdbc强点,说实话,实战中用的也比较少。

2. 集成步骤

2.1 引入依赖

<!-- jdbcTemplate -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
 
<!-- MySQL连接 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

2.2 配置数据库连接

在SpringBoot的配置文件中,配置数据库的连接,这是所有要操作数据库都必须要进行的配置。主要包含使用的驱动类,数据库的连接地址,用户名密码等。

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot_learning
    username: root
    password: root

我在自己的本地数据库里创建一个名字叫springboot_learning的数据库用于测试。

然后我们创建一张user表。

CREATE TABLE `springboot_learning`.`t_user`  (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(40) NULL COMMENT '姓名',
  `age` int(20) NULL COMMENT '年龄',
  `address` varchar(100) NULL COMMENT '地址',
  `create_time` datetime(0) NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
);

2.3开发实体和DAO

创建一个entity文件夹,然后创建一个实体类User

@Data
public class User {

    private Integer id;

    private String name;

    private Integer age;

    private String address;

    private Date createTime;

    private Date updateTime;

}

开发UserDao 包含常用的增删改查接口

UserDao接口

/**
 * @interface: UserDao
 * @description:
 * @author: sh.Liu
 * @date: 2022-01-14 16:37
 */
public interface UserDao {
    /**
     * 根据id查询
     * @param id
     * @return
     */
    User getUserById(Integer id);

    /**
     * 查询所有用户
     * @return
     */
    List<User> listUser();

    /**
     * 保存用户
     * @param user
     * @return
     */
    int save(User user);

    /**
     * 更新用户
     * @param id
     * @param user
     * @return
     */
    int update(Integer id, User user);

    /**
     * 删除用户
     * @param id
     * @return
     */
    int delete(Integer id);


}

UserDaoImpl 实现:在类中注入 JdbcTemplate 接口,这个是spring为我们提供的,用来操作数据库的核心对象。这个类上也要加上 @Repository 注解,用于标识这个类是用来处理数据库操作的。可以被Spring扫描到。

UserDaoImpl代码如下:

package com.lsqingfeng.springboot.dao.jdbcTemplate.impl;

import com.lsqingfeng.springboot.dao.jdbcTemplate.UserDao;
import com.lsqingfeng.springboot.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

/**
 * @className: UserDaoImpl
 * @description:
 * @author: sh.Liu
 * @date: 2022-01-14 16:40
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public User getUserById(Integer id) {
        User user  = jdbcTemplate.queryForObject("select * from t_user where id = ?", new BeanPropertyRowMapper<User>(User.class), id);
        return user;
    }

    @Override
    public List<User> listUser() {
        List<User> users = jdbcTemplate.query("select * from t_user", new BeanPropertyRowMapper<User>(User.class));
        return users;
    }

    @Override
    public int save(User user) {
        return jdbcTemplate.update("insert into t_user(name, age, address, create_time, update_time) values(?, ?, ?,?,?)",
                user.getName(),user.getAge(), user.getAddress(),new Date(),new Date());
    }

    @Override
    public int update(Integer id, User user) {
        return jdbcTemplate.update("UPDATE t_user SET name = ? , age = ? ,address = ? ,update_time = ? WHERE id=?",
                user.getName(), user.getAge(), user.getAddress(), new Date(), id);
    }

    @Override
    public int delete(Integer id) {
        return jdbcTemplate.update("DELETE from tb_user where id = ? ",id);
    }
}

我们包装一个Service层,目前主流的项目接口也都是Controller-Service-Dao这样的逻辑。

2.4 Service层开发

创建一个service包,加一个UserService接口。service层中一般用来处理业务逻辑,一般把有事务的代码放到这一层,一般是根据业务模块进行划分,名字可以不与实体名或者表名开发,他里边一般是对多个Dao层操作的封装。想要彻底搞懂Service层也能需要更多项目的历练。这里以演示为主,也没有特别复杂的业务,我们就直接起名UserService.里面就直接把Dao层中的方法全部拿过来。

UserService

/**
 * @interface: UserService
 * @description:
 * @author: sh.Liu
 * @date: 2022-01-17 13:56
 */
public interface UserService {
    /**
     * 根据id查询
     * @param id
     * @return
     */
    User getUserById(Integer id);

    /**
     * 查询所有用户
     * @return
     */
    List<User> listUser();

    /**
     * 保存用户
     * @param user
     * @return
     */
    int save(User user);

    /**
     * 更新用户
     * @param id
     * @param user
     * @return
     */
    int update(Integer id, User user);

    /**
     * 删除用户
     * @param id
     * @return
     */
    int delete(Integer id);


}

实现类中,直接注入Dao ,通过调用Dao实现相同功能。

/**
 * @className: UserServiceImpl
 * @description:
 * @author: sh.Liu
 * @date: 2022-01-17 13:56
 */
@Service
public class UserServiceImpl implements UserService {

    // 这是构造方法注入,相当于 @autowired
    private final UserDao userDao;

    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public User getUserById(Integer id) {
        return userDao.getUserById(id);
    }

    @Override
    public List<User> listUser() {
        return userDao.listUser();
    }

    @Override
    public int save(User user) {
        return userDao.save(user);
    }

    @Override
    public int update(Integer id, User user) {
        return userDao.update(id, user);
    }

    @Override
    public int delete(Integer id) {
        return userDao.delete(id);
    }
}

2.5 开发Controller进行测试

Dao和Service都已经准备好了,接下来我们就开发一个Controller来进行测试,看看是否可以成功的操作数据库。

package com.lsqingfeng.springboot.controller;

import com.lsqingfeng.springboot.base.Result;
import com.lsqingfeng.springboot.entity.User;
import com.lsqingfeng.springboot.exception.BizException;
import com.lsqingfeng.springboot.service.UserService;
import org.springframework.web.bind.annotation.*;

/**
 * @className: JdbcController
 * @description:
 * @author: sh.Liu
 * @date: 2022-01-17 13:58
 */
@RestController
@RequestMapping("jdbc")
public class JdbcController {

    /**
     * 这是构造方法注入,相当于 @autowired
     */
    private final UserService userService;

    public JdbcController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("save")
    public Result save(@RequestBody User user){
        userService.save(user);
        return Result.success();
    }

    @PostMapping("update")
    public Result update(@RequestBody User user){
        if (user.getId() == null) {
            throw new BizException("更新操作id不能为空");
        }
        userService.update(user.getId(), user);
        return Result.success();
    }

    @GetMapping("get/{id}")
    public Result getById(@PathVariable Integer id){
        return Result.success(userService.getUserById(id));
    }

    @GetMapping("list")
    public Result list(){
        return Result.success(userService.listUser());
    }

    @GetMapping("delete/{id}")
    public Result delete(@PathVariable Integer id){
        userService.delete(id);
        return Result.success();
    }
}

我们使用postMan进行测试。注意别忘了传header, 因为咱们的拦截器里要求必须传header

image.png

返回成功,查看数据库中数据:

image.png

数据保存成功。

我们再试试getById方法

image.png

其他的方法就不在演示了。

3. 总结

关于Spring所提供的JdbcTemplate的用法就是这些,Spring集成JdbcTemplate的方法也是比较简单的,整体就是先引入依赖,在配置数据库的连接,然后使用jdbcTemplate这个类就可以了,JdbcTemplate 类中就已经封装了大部分对于数据库的操作。简单是简单,但是这个框架在企业级项目中应用是比较少的,一般用于对于操作数据库的要求不高的项目,因为他就是对jdbc的简单封装,所有的sql都是写入到代码中,维护性差,看起来也比较乱。后边我们会继续介绍比较主流的DAO层框架Mybatis和JPA的用法。希望本篇文章对大家有所帮助。

另: 配套项目代码已托管中gitCode: gitcode.net/lsqingfeng/…

所有文章也会在微信公众号首发更新,欢迎关注: 一缕82年的清风