经过了前面的几篇文章,我们几乎讲解完毕了SpringBoot中前端控制器中的一些操作,体验到SpringBoot为我们使用框架所带来的便捷。前面文章中的所有案例,总共只引入了一个 web-starter, 配置也很少。从今天开始,我们来开始研究一下,SpringBoot如何完成数据的持久化操作。
一般持久化的操作都是有一些专门来做持久化的框架来完成的,比如原始一些的JDBC, 老牌劲旅JPA(hibernate), 还有现在用的比较或的mybatis和MybatisPlus, 而SpringBoot中我们也是先要选择要使用的持久层框架,然后使用SpringBoot进行集成。而集成的步骤由于SpringBoot的自动化配置功能而大大简化。
今天我们先来搞个简单点的,先来个JdbcTemplate, 这个是Spring基于Jdbc而封装的一个持久层框架,致力于轻量、便捷地操作数据库。他的操作很简单,但是不如mybatis和jpa功能全面,但是比原生jdbc强点,说实话,实战中用的也比较少。
xml复制代码
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
在SpringBoot的配置文件中,配置数据库的连接,这是所有要操作数据库都必须要进行的配置。主要包含使用的驱动类,数据库的连接地址,用户名密码等。
yml复制代码spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot_learning
username: root
password: root
我在自己的本地数据库里创建一个名字叫springboot_learning的数据库用于测试。
然后我们创建一张user表。
sql复制代码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`)
);
创建一个entity文件夹,然后创建一个实体类User
java复制代码@Data
public class User {
private Integer id;
private String name;
private Integer age;
private String address;
private Date createTime;
private Date updateTime;
}
开发UserDao 包含常用的增删改查接口
UserDao接口
java复制代码/**
* @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代码如下:
java复制代码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这样的逻辑。
创建一个service包,加一个UserService接口。service层中一般用来处理业务逻辑,一般把有事务的代码放到这一层,一般是根据业务模块进行划分,名字可以不与实体名或者表名开发,他里边一般是对多个Dao层操作的封装。想要彻底搞懂Service层也能需要更多项目的历练。这里以演示为主,也没有特别复杂的业务,我们就直接起名UserService.里面就直接把Dao层中的方法全部拿过来。
UserService
java复制代码/**
* @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实现相同功能。
java复制代码/**
* @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);
}
}
Dao和Service都已经准备好了,接下来我们就开发一个Controller来进行测试,看看是否可以成功的操作数据库。
java复制代码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
返回成功,查看数据库中数据:
数据保存成功。
我们再试试getById方法
其他的方法就不在演示了。
关于Spring所提供的JdbcTemplate的用法就是这些,Spring集成JdbcTemplate的方法也是比较简单的,整体就是先引入依赖,在配置数据库的连接,然后使用jdbcTemplate这个类就可以了,JdbcTemplate 类中就已经封装了大部分对于数据库的操作。简单是简单,但是这个框架在企业级项目中应用是比较少的,一般用于对于操作数据库的要求不高的项目,因为他就是对jdbc的简单封装,所有的sql都是写入到代码中,维护性差,看起来也比较乱。后边我们会继续介绍比较主流的DAO层框架Mybatis和JPA的用法。希望本篇文章对大家有所帮助。
另: 配套项目代码已托管中gitCode: gitcode.net/lsqingfeng/…