任务描述
任务要求
使用IDEA开发工具构建一个项目多模块工程。study-springboot-chapter05学习关于Springboot集成JDBC知识点
- 基于study-springboot工程,新建一个Maven空项目,坐标groupId(com.cbitedu)、artifactId(study-springboot-chapter05)
- 继承study-springboot工程依赖
- 详细学习Spring JDBC ,提供了 JdbcTemplate 工具类。
任务收获
- 如何集成第三方持久化技术Spring JDBC
- 如何引入MySQL数据库依赖
- Spring Boot中整合Spring JDBC完成关系型数据库的增删改查操作
- 学会使用JUnit完成单元测试
- 掌握Spring JDBC在项目中的应用
任务准备
环境要求
- JDK1.8+
- MySQL8.0.27+
- Maven 3.6.1+
- IDEA/VSCode
数据库准备
创建数据库platform,并创建用户表和初始化用户表数据。
/*
Navicat Premium Data Transfer
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : platform
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- Table structure for t_sys_userinfo
DROP TABLE IF EXISTS t_sys_userinfo;
CREATE TABLE t_sys_userinfo (
user_id varchar(32) NOT NULL,
username varchar(50) NOT NULL COMMENT '用户名',
password varchar(100) DEFAULT NULL COMMENT '密码',
salt varchar(20) DEFAULT NULL COMMENT '盐',
email varchar(100) DEFAULT NULL COMMENT '邮箱',
mobile varchar(100) DEFAULT NULL COMMENT '手机号',
status tinyint DEFAULT NULL COMMENT '状态 0:禁用 1:正常',
create_user_id varchar(32) NULL DEFAULT NULL COMMENT '创建者ID',
create_time varchar(32) DEFAULT NULL COMMENT '创建时间',
userimg varchar(255) DEFAULT NULL COMMENT '用户头像',
zip varchar(10) DEFAULT NULL COMMENT '邮政编码',
sort_num int DEFAULT NULL COMMENT '排序号',
user_type varchar(10) DEFAULT NULL COMMENT '用户类型',
post_id varchar(32) DEFAULT NULL COMMENT '所属岗位',
sex varchar(4) DEFAULT NULL COMMENT '性别',
USER_REALNAME varchar(50) DEFAULT NULL COMMENT '真实姓名',
user_theme varchar(255) DEFAULT NULL COMMENT '用户选择皮肤',
user_card varchar(18) DEFAULT NULL COMMENT '身份证号码',
birthday varchar(20) DEFAULT NULL COMMENT '出生年月',
native_place varchar(255) DEFAULT NULL COMMENT '家庭住址',
nation varchar(255) DEFAULT NULL COMMENT '民族',
update_user_id varchar(32) DEFAULT NULL COMMENT '创建者ID',
update_time varchar(32) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (user_id) USING BTREE,
UNIQUE INDEX username(username ASC) USING BTREE
) COMMENT = '系统用户' ROW_FORMAT = Dynamic;
-- Records of t_sys_userinfo
INSERT INTO t_sys_userinfo VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'cc@bluefairy.com', '18929423839', 1, '1', '2016-11-11 11:11:11', NULL, NULL, NULL, NULL, NULL, NULL, '系统管理员', 'green', NULL, NULL, NULL, NULL, NULL, NULL);
SET FOREIGN_KEY_CHECKS = 1;
工程目录要求
新建一个空的Maven项目:study-springboot-chapter05
任务实施
学习在Spring Boot中最基本的数据访问工具:JdbcTemplate。
首先,为了连接数据库需要引入jdbc支持,在pom.xml中引入如下配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
以MySQL数据库为例,先引入MySQL连接的依赖包,在pom.xml中加入:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
在src/main/resources/application.yml中配置数据源信息
`#服务配置
server:
port: 81
#设置日志相关打印sql 语句
logging:
level:
top.lrshuai.plus.springbootmybatisplus.test.mapper.ShipmentMapper: debug
关闭运行日志图标(banner)
spring:
datasource:
url: jdbc:mysql://localhost:3306/platform?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver` </pre>
注意:因为Spring Boot 2.1.x默认使用了MySQL 8.0的驱动,所以这里采用com.mysql.cj.jdbc.Driver,而不是老的com.mysql.jdbc.Driver。
使用JdbcTemplate操作数据库
Spring的JdbcTemplate是自动配置的,你可以直接使用@Autowired或构造函数(推荐)来注入到你自己的bean中来使用。
下面就来一起完成一个增删改查的例子:
1、准备数据库platform和表t_sys_userinfo
2、编写领域对象Domain Object
根据数据库中创建的t_sys_userinfo表,创建领域对象:com.cbitedu.springboot.entity.UserDO
package com.cbitedu.springboot.entity;
import java.io.Serializable;
public class UserDO implements Serializable {
/**
- 创建人
*/
private String createUserId;
@Override
public String toString() {
return "TsysUserinfo{" +
"createUserId='" + createUserId + ''' +
", createTime='" + createTime + ''' +
", updateUserId='" + updateUserId + ''' +
", updateTime='" + updateTime + ''' +
", userId='" + userId + ''' +
", username='" + username + ''' +
", password='" + password + ''' +
", salt='" + salt + ''' +
", email='" + email + ''' +
", mobile='" + mobile + ''' +
", status='" + status + ''' +
", orgId='" + orgId + ''' +
", userRealname='" + userRealname + ''' +
", orgnames='" + orgnames + ''' +
", userimg='" + userimg + ''' +
", zip='" + zip + ''' +
", sortNum=" + sortNum +
", userType='" + userType + ''' +
", sex='" + sex + ''' +
", userTheme='" + userTheme + ''' +
", userCard='" + userCard + ''' +
", birthday='" + birthday + ''' +
", nativePlace='" + nativePlace + ''' +
", nation='" + nation + ''' +
'}';
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
/**
- 创建时间
/
private String createTime;
/* - 修改人
/
private String updateUserId;
/* - 修改时间
/
private String updateTime;
/* - 用户ID
/
private String userId;
/* - 用户名
*/
private String username;
/**
- 密码
*/
private String password;
/**
- 盐
*/
private String salt;
/**
- 邮箱
*/
private String email;
/**
- 手机号
*/
private String mobile;
/**
- 状态 0:禁用 1:正常
*/
private String status;
/**
- 所属机构
*/
private String orgId;
/**
- 用户真实姓名
*/
private String userRealname;
/**
- 所属机构
*/
private String orgnames;
/**
- 用户头像
/
private String userimg;
/* - 邮政编码
/
private String zip;
/* - 排序号
/
private Integer sortNum;
/* - 用户类型
/
private String userType;
/* - 性别
*/
private String sex;
private String userTheme;
public String getCreateUserId() {
return createUserId;
}
public void setCreateUserId(String createUserId) {
this.createUserId = createUserId;
}
public String getUpdateUserId() {
return updateUserId;
}
public void setUpdateUserId(String updateUserId) {
this.updateUserId = updateUserId;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getOrgId() {
return orgId;
}
public void setOrgId(String orgId) {
this.orgId = orgId;
}
public String getUserRealname() {
return userRealname;
}
public void setUserRealname(String userRealname) {
this.userRealname = userRealname;
}
public String getOrgnames() {
return orgnames;
}
public void setOrgnames(String orgnames) {
this.orgnames = orgnames;
}
public String getUserimg() {
return userimg;
}
public void setUserimg(String userimg) {
this.userimg = userimg;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public Integer getSortNum() {
return sortNum;
}
public void setSortNum(Integer sortNum) {
this.sortNum = sortNum;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getUserTheme() {
return userTheme;
}
public void setUserTheme(String userTheme) {
this.userTheme = userTheme;
}
public String getUserCard() {
return userCard;
}
public void setUserCard(String userCard) {
this.userCard = userCard;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getNativePlace() {
return nativePlace;
}
public void setNativePlace(String nativePlace) {
this.nativePlace = nativePlace;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
/**
- 身份证号码 db_column: user_card
/
private String userCard;
/* - 出生年月 db_column: birthday
/
private String birthday;
/* - 家庭住址 db_column: native_place
/
private String nativePlace;
/* - 民族 db_column: nation
*/
private String nation;
}
3、编写数据访问接口服务和服务实现类com.cbitedu.springboot.entity.IUserService
定义包含有插入、删除、查询的抽象接口IUserService
package com.cbitedu.springboot.service;
import com.cbitedu.springboot.entity.UserDO;
import org.springframework.stereotype.Repository;
import java.util.List;
public interface IUserService {
int insertUser(UserDO userDO);
/**
- 根据name查询用户
- @param name
- @return
*/
List<UserDO> getByName(String name);
/**
- 根据name删除用户
- @param name
*/
int deleteByName(String name);
/**
- 获取用户总量
*/
int getAllUsers();
/**
- 删除所有用户
*/
int deleteAllUsers();
}
4、通过JdbcTemplate实现UserService中定义的数据访问操作:UserServiceImpl
package com.cbitedu.springboot.service;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.cbitedu.springboot.entity.*;
import java.util.List;
@Service
public class UserServiceImpl implements IUserService {
private final JdbcTemplate jdbcTemplate;
UserServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int insertUser(UserDO userDO) {
return jdbcTemplate.update("insert into t_sys_userinfo(user_id, username,password) values(?, ?,?)",userDO.getUserId(),userDO.getUsername(), userDO.getPassword());
}
@Override
public List<UserDO> getByName(String name) {
List<UserDO> users = jdbcTemplate.query("select username, password from t_sys_userinfo where username = ?", (resultSet, i) -> {
UserDO user = new UserDO();
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}, name);
return users;
}
@Override
public int deleteByName(String name) {
return jdbcTemplate.update("delete from t_sys_userinfo where username = ?", name);
}
@Override
public int getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from t_sys_userinfo", Integer.class);
}
@Override
public int deleteAllUsers() {
return jdbcTemplate.update("delete from t_sys_userinfo");
}
}
5、编写单元测试用例
创建对UserService的单元测试用例SpringJDBCTemplateTest,通过创建、删除和查询来验证数据库操作的正确性
package com.cbitedu.springboot.web;
import com.cbitedu.springboot.service.IUserService;
import com.cbitedu.springboot.entity.UserDO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringJDBCTemplateTest {
@Test
public void contextLoads() {
}
private static final Logger logger = LoggerFactory.getLogger(SpringJDBCTemplateTest.class);
@Autowired
IUserService userService;
/**
- 测试新增用户信息
*/
@Test
public void testInsert() {
UserDO tsysUserinfo = new UserDO();
tsysUserinfo.setUserId(UUID.randomUUID().toString().replace("-", ""));
tsysUserinfo.setUsername("Mybati44889");
tsysUserinfo.setPassword("88888");
userService.insertUser(tsysUserinfo);
}
/**
- 根据用户名称查询用户详细信息
*/
@Test
public void testGetName() {
userService.getByName("Mybati44889");
logger.info("查询出来的用户基本信息"+userService.getByName("Mybati44889"));
}
}
小结:不想写mybatis的映射文件,对Hibernate也不熟,但对SQL语句比较熟练,建议使用Spring JDBC框架来解决数据存储和访问
- JdbcTemplate是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分。JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。
- JdbcTemplate的作用:它就是用于和数据库交互的,实现对表的CRUD操作。
- execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
- update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;
- batchUpdate方法用于执行批处理相关语句;
- query方法及queryForXXX方法:用于执行查询相关语句;
- call方法:用于执行存储过程、函数相关语句。
- BeanPropertyRowMapper可以将数据库字段的值向对象映射,满足驼峰标识也可以自动映射。如:数据库create_time字段映射到createTime属性。
实验实训
-
JdbcTemplate如何调用存储过程
编写存储过程sp_getUserinfo通过用户名称查询用户的详细信息