005 Spring Boot 使用 JdbcTemplate 操作数据库

这篇我们再深入学习 Spring Boot 如何来操作数据库。

本篇,我们使用 JdbcTemplate 方式来作为 Spring Boot 连接 数据库(MySQL)的工具。

创建数据库表

  • 创建库:

    create database app_test;
  • 创建 user 表:

    create table `jdz_user`
    (
    `uid` int unsigned not null auto_increment,
    `name` varchar(64) not null default '',
    `age` tinyint not null default 0,
    `addr` varchar(128) not null default '',
    primary key (`uid`),
    unique (`name`)
    )engine = innodb default charset = utf8;

添加依赖

<!--导入JDBC的场景启动器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

<!--导入数据库驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

增加配置文件

新建文件: app/src/main/resources/application.properties

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/app_test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=

# 空闲时,最少的连接池数量
spring.datasource.hikari.minimum-idle=5

注:

  1. spring.datasource.url 中,characterEncoding 是规定编码方式,最好加上,否则可能出现中文乱码情况
  2. spring.datasource.hikari.minimum-idle 为 HikariPool 数据库连接池最小的与mysql连接数

代码编写

创建实体类

创建与数据表对应的实体类:

package com.jdz.entity;

public class User {
    private Integer uid;
    private String name;
    private Integer age;
    private String addr;
}

创建 DAO

1. 创建 IUserDAO 接口

package com.jdz.dao;

import com.jdz.entity.User;

import java.util.List;

public interface IUserDAO {

    public boolean doCreate(User user);

    public User findByUid(Integer uid);

    public List<User> findAll();
}

2. 创建具体的 DAO 实现

创建 DAO 具体的实现类,并在这层进行数据库操作

package com.jdz.dao.impl;

import com.jdz.dao.IUserDAO;
import com.jdz.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

@Repository
public class UserDAOImpl implements IUserDAO {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public boolean doCreate(User user) {
        return jdbcTemplate.update("insert into `jdz_user`(`name`, `age`, `addr`) values (?, ?, ?)", user.getName(), user.getAge(), user.getAddr()) > 0;
    }

    @Override
    public boolean doDel(Integer uid) {
        return jdbcTemplate.update("DELETE from `jdz_user` where uid=?", uid) > 0;
    }

    @Override
    public User findByUid(Integer uid) {
        try {
            return jdbcTemplate.queryForObject("select * from `jdz_user` where uid=?", new RowMapper<User>() {
                @Override
                public User mapRow(ResultSet rs, int rowNum) throws SQLException {
                    User user = new User();
                    user.setUid(rs.getInt(1));
                    user.setName(rs.getString(2));
                    user.setAge(rs.getInt(3));
                    user.setAddr(rs.getString(4));
                    return user;
                }
            }, uid);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    @Override
    public List<User> findAll() {
        return jdbcTemplate.query("SELECT * FROM `jdz_user`", new BeanPropertyRowMapper<User>(User.class));
    }
}

有几点要注意

  1. jdbcTemplate 使用 @Autowired 注解

    @Autowired
    private JdbcTemplate jdbcTemplate;
  2. UserDAOImpl 类使用 @Repository 注解

    @Repository
    public class UserDAOImpl implements IUserDAO {}
  3. 在使用 jdbcTemplate.queryForObject,当查询结果为空时,会报异常,所以使用 try{}catch(){} 进行异常捕获(当然也可以用其他方式替代)

3. 创建 Service

package com.jdz.service;

import com.jdz.dao.impl.UserDAOImpl;
import com.jdz.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserDAOImpl userDAO;

    public boolean createUser(User user) {
        return userDAO.doCreate(user);
    }

    public boolean delUser(Integer uid) {
        return userDAO.doDel(uid);
    }

    public User getUser(Integer uid) {
        return userDAO.findByUid(uid);
    }

    public List<User> getAll() {
        return userDAO.findAll();
    }
}

有几点要注意

  1. userDAO 使用 @Autowired 注解
  2. UserService 类使用 @Service 注解

4. 创建 controller

package com.jdz.controllers;

import com.jdz.entity.User;
import com.jdz.service.UserService;
import com.jdz.util.ErrType;
import com.jdz.util.RtData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @RequestMapping("/user/add")
    public RtData<User> addUser(User user) {
        if(user.getName() == null || user.getAge() == null || user.getAddr() == null) {
            return rtJson(ErrType.ERR_PARAMS);
        }
        userService.createUser(user);
        return rtJson(user);
    }

    @RequestMapping("/user/info")
    public RtData<User> info(Integer uid) {
        return rtJson(userService.getUser(uid));
    }

    @RequestMapping("/user/del")
    public RtData<Boolean> delUser(Integer uid) {
        return rtJson(userService.delUser(uid));
    }

    @RequestMapping("/user/list")
    public RtData<List<User>> userList() {
        return rtJson(userService.getAll());
    }
}

有几点要注意

  1. userService 使用 @Autowired 注解
  2. 关于 JdbcTemplate 的理解

启动服务后,浏览器访问相应的路由,即可操作数据库中的数据。

这里比较难理解的是,@Autowired 注解,以及相应的字段的初始化过程。(在 spring 启动时,通过 @Autowired ,由 spring 进行初始化)

源码:https://github.com/xiongxianhe/springboot/tree/master/005%20Spring%20Boot%20%E4%BD%BF%E7%94%A8%20JdbcTemplate%20%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93/javaapp

发表评论