首页 > 编程笔记

JdbcTemplate连接数据库

SQL 数据库主要指关系型数据库。Spring 框架为 MySQL 数据库提供了广泛的技术支持,从封装了 JDBC 操作的 JdbcTemplate,到支持 ORM 技术的 Hibernate 等。Spring Data 是 Spring 的一个子项目,它提供了 Repository 接口,可以通过函数名直接完成 SQL 语句的查询。本文主要讲解 JdbcTemplate。

Java 的 javax.sql.DataSource 接口提供了处理数据库连接的标准方法,通过配置一个连接池提供数据库连接,Spring Boot 可以完成一些自动配置。首选HikariCP 连接池,也可使用 Tomcat 连接池,如果这两个连接池都不可用,则使用 DBCP2。当然,开发者也可以自定义连接池,如采用阿里巴巴的 Druid  等。

Spring Boot 提供了自动配置,因此开发者只需在配置文件中添加数据库的配置信息即可。Spring Boot 提供了多种类型的连接池,如spring.datasource.hikari.*、spring.datasource.tomcat.* 和 spring.datasource.dbcp2.* 等。

注意:如果不指定 spring.datasource.url 属性,则 Spring Boot 会自动配置内嵌的数据库。

一个简单的 DataSoruce 配置如下:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true

原生的 JDBC 操作数据库需要自己创建连接,使用完之后还需要手动关闭。Spring 框架为了提高开发效率,对 JDBC 进行了封装,即提供了 JdbcTemplate类。

JdbcTempale模板类

JdbcTemplate 是一个模板类,提供了操作数据库的基本方法,如插入、更新、删除及查询等操作,同时还封装了一些固定操作,如连接的创建与关闭。JdbcTemplate 类提供了回调接口的方式,用于实现一些可变操作,如 ConnectionCallback 可以返回一个连接,StatementCallback 可以返回一个Statement,还可以在回调接口做一些映射关系的逻辑处理。

JdbcTemplate 模板类提供了以下几种类型的方法:

示例

下面通过一个简单的示例展示 JdbcTemplate 的操作。

(1)定义一张 user 表,结构如下:

CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_name` varchar(128) NOT NULL COMMENT '用户昵称',
  `login_name` varchar(128) NOT NULL COMMENT '登录账户',
  `user_head_img` varchar(256) DEFAULT NULL COMMENT '用户头像',
  `last_login_time` int(11) DEFAULT NULL COMMENT '上次登录时间'
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(2)使用 JdbcTemplate 需要依赖 spring-boot-starter-jdbc mysql-connector-java 包。配置文件 application.yml 如下:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&character
Encoding=UTF8&characterSetResults=UTF8&serverTimezone=UTC
    username: root
    password: test1111
    driver-class-name: com.mysql.cj.jdbc.Driver

(3)定义实体类 User,代码如下:
//声明实体类User
public class User {
    private Integer userId;  //用户ID
    private String userName;  //用户名
    private String loginName;  //登录名
    private Integer lastLoginTime; //登录时间
    private String userHeadImg; //用户头像
    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName == null ? null : userName.trim();
    }
    public String getLoginName() {
        return loginName;
    }
    public void setLoginName(String loginName) {
        this.loginName = loginName == null ? null : loginName.trim();
    }
    public Integer getLastLoginTime() {
        return lastLoginTime;
    }
    public void setLastLoginTime(Integer lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }
    public String getUserHeadImg() {
        return userHeadImg;
    }
    public void setUserHeadImg(String userHeadImg) {
        this.userHeadImg = userHeadImg == null ? null : userHeadImg.
    }
}
(4)定义 Dao 层的类UserDao,在其中使用 JdbcTemplate 操作 MySQL 数据库,代码如下:
//声明UserDao
@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;  //JdbcTemplate注入

    public String add(User user) {
        //insert语句
        String sql = "insert into user(user_name, login_name, last_login_time, user_head_img) value (?, ?, ?, ?)";
        try {
            jdbcTemplate.update(sql, user.getUserName(), user.getLoginName(), user.getLastLoginTime(), user.getUserHeadImg());
            return "1";
        } catch (DataAccessException e) {
            e.printStackTrace();
            return "0";
        }
    }

    public User findOne(Integer userId) {
        //查询语句
        String sql = "select * from user where user_id = " + userId;
        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
        return userList.get(0);
    }

    public String update(User user) {
        //更新语句
        String sql = "update user set user_name = ?, login_name = ? where user_id = ?";
        try {
            jdbcTemplate.update(sql, user.getUserName(), user.getLoginName(), user.getUserId());
            return "1";
        } catch (DataAccessException e) {
            return "0";
        }
    }

    public String delete(Integer userId) {
        //删除语句
        String sql = "delete from user where user_id = ?";
        try {
            jdbcTemplate.update(sql, userId);
            return "1";
        } catch (DataAccessException e) {
            return "0";
        }
    }

    public List<User> findAll() {
        //查询多条语句
        String sql = "select * from user";
        List<User> query = jdbcTemplate.query(sql, new BeanProperty RowMapper < > (User.class));
        return query;
    }
}
(5)定义 Service 层的类 UserService,代码如下:
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    //添加方法
    public String add(User user){
        return userDao.add(user);
    }
    //查询方法
   public User findOne(Integer userId){
        return userDao.findOne(userId);
    }
    //更新方法
    public String update(User user){
        return userDao.update(user);
    }
    //删除操作
    public String delete(Integer userId){
        return userDao.delete(userId);
    }
    //查询列表方法
    public List<User> findAll(){
        return userDao.findAll();
    }
}
(6)定义 Controller 层的类 HiController,代码如下:
@RestController
@RequestMapping("/hi")
public class HiController {
    @Autowired
    private UserService userService;
    //新增用户接口
    @PostMapping("/add")
    public String add(@RequestBody User user){
        return userService.add(user);
    }
    //查询用户接口
    @GetMapping("/findOne")
    public User findOne(Integer userId){
        return userService.findOne(userId);
    }
    //更新用户接口
    @PostMapping("/update")
    public String update(@RequestBody User user){
        return userService.update(user);
    }
    //删除用户接口
    @DeleteMapping("/delete")
    public String delete(Integer userId){
        return userService.delete(userId);
    }
    //查询多条用户信息接口
    @GetMapping("/findAll")
    public List<User> findAll(){
        return userService.findAll();
    }
}
(7)启动服务,使用 Postman 以 POST 方式访问 http://localhost:8080/hi/add 接口,在请求 Body 中增加如下信息:
{
  "userName":"编程帮",
  "loginName":"www.weixueyuan.net",
  "lastLoginTime":"1599032640",
  "userHeadImg":"https://image.xxx.com/xxx.jpg"
}
(8)访问 http://localhost:8080/hi/findAll 接口,即可查看刚才插入的用户信息。同样,访问 http://localhost:8080/hi/update 接口可以更新用户信息,访问 http://localhost:8080/ hi/delete?userId=130 接口可以删除用户信息。

优秀文章