一、前言
在SpringCloud中,增删改查是基本操作,前端在响应用户操作后,将会把该响应通过API发送给后端,并调用后端对应功能对后端数据库进行增删改查的操作。而我们需要做的就是根据项目的业务逻辑和后端数据库表结构设计合理的查询事务,并能高效完成相应操作,本章节将会通过实际的案例来演示实现过程,但在了解实际操作过程前,我们需要了解MyBatis-Plus。
二、MyBatis-Plus
1.MyBatis-Plus是什么
简单来说,MyBatis-Plus是一个数据库查询组件,在Spring项目中我们可以通过实例化MyBatis-Plus中提供的相应对象,设置好需要查询的字段,通过调用相应的方法即可实现数据查询的功能,当然还有其他功能本片未提及,想要了解相应功能可以访问:MyBatis-Plus (baomidou.com)。
博主在接触Spring框架前开发过JSP项目,还记得当时JSP的一个页面需要查询数据库时需要在Java项目中导入JDBC包,并且不同数据库的包还不一样,当时博主就在MySQL和SQLServer之间反复横跳。此外在编写JDBC查询数据库时也是相当酸爽的一件事情,由于不同数据库JDBC查询方式不一样,因此编写查询代码时都会有细微差别。而且当查询需求越来越复杂时,JDBC编写就会更加一团糟。这里给大家感受一下JDBC查询和MyBatis-Plus查询的复杂度
JDBC:
import java.sql.*;
public class InfoProcess {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:MySQL://localhost:3306/Test";
String username = "root";
String password = "123456";
Connection conn = null;
Statement statement;
public InfoProcess(){}
public void dataBaseConnector(){
try {
Class.forName(driver);
conn = DriverManager.getConnection(url , username , password);
statement = conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean userJudge(String inputAccount , String inputPassword){
try {
String sqlSent = "select * from user where id = '" + inputAccount + "';";
ResultSet rs = statement.executeQuery(sqlSent);
while(rs.next()) {
if (rs.getString("password").equals(inputPassword)){
return true;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
}
MyBatis-Plus:
//注:数据库连接配置在项目中的application.yml设置
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Admin::getUsername , userName);
可以很明显看出MyBatis-Plus查询代码更简洁,开发更高效。
2.MyBatis-Plus查询原理
大家肯定疑惑,为什么MyBatis-Plus能大幅简化数据库的连接和查询过程呢?在MyBatis-Plus中一般我们会使用到LambdaQueryWrapper或QueryWrapper对象,以上述代码为例,在实例化LambdaQueryWrapper对象时我们需要声明查询的对象,这个对象是项目中已经封装好的数据对象,在这个对象的类中定义好的对象的属性,并且每个属性都和后端数据库相应对象表中的字段一一对应,这一步骤也是MyBatis-Plus的数据映射。当我们把查询条件设置完毕后,MyBatis-Plus会通过我们实例化的对象进行SQL执行语句的构建,最后将构建完毕的数据提交给数据库,让数据库的引擎来执行SQL执行语句,这样我们就可以查询到对应的结果。
三、SpringCloud中的增删改查
1.业务分析
在这个步骤我们需要明确查询对象的一些属性,即数据模型,并且需要去查看前端项目的API,了解该对象需要实现什么功能。这里以项目中用户查询功能为例。
用户对象的数据模型:
/**
* <p>
* 用户
* </p>
*
* @author qy
* @since 2019-11-08
*/
@Data
@ApiModel(description = "用户")
@TableName("admin")
public class Admin extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户名")
@TableField("username")
private String username;
@ApiModelProperty(value = "密码")
@TableField("password")
private String password;
@ApiModelProperty(value = "昵称")
@TableField("name")
private String name;
@ApiModelProperty(value = "手机")
@TableField("phone")
private String phone;
@ApiModelProperty(value = "仓库id")
@TableField("ware_id")
private Long wareId;
@ApiModelProperty(value = "角色名称")
@TableField(exist = false)
private String roleName;
}
前端API接口:
const api_name = '/admin/acl/user'
/*
登陆
*/
export function login({ username, password }) {
return request({
url: '/admin/acl/index/login',
method: 'post',
data: { username, password }
})
}
/*
获取用户信息(根据token)
*/
export function getInfo() {
return request({
url: '/admin/acl/index/info',
method: 'get'
})
}
/*
登出
*/
export function logout() {
return request({
url: '/admin/acl/index/logout',
method: 'post'
})
}
/*
获取当前用户的菜单权限列表
*/
export function getMenu() {
return request('/admin/acl/index/menu')
}
/*
获取后台用户分页列表(带搜索)
*/
export function getPageList(page, limit, searchObj) {
return request({
url: `${api_name}/${page}/${limit}`,
method: 'get',
params: searchObj
})
}
/*
根据ID获取某个后台用户
*/
export function getById(id) {
return request({
url: `${api_name}/get/${id}`,
method: 'get'
})
}
/*
保存一个新的后台用户
*/
export function add(user) {
return request({
url: `${api_name}/save`,
method: 'post',
data: user
})
}
/*
更新一个后台用户
*/
export function update(user) {
return request({
url: `${api_name}/update`,
method: 'put',
data: user
})
}
/*
获取某个用户的所有角色
*/
export function getRoles(adminId) {
return request({
url: `${api_name}/toAssign/${adminId}`,
method: 'get'
})
}
/*
给某个用户分配角色
roleId的结构: 字符串, 'rId1,rId2,rId3'
*/
export function assignRoles(adminId, roleId) {
return request({
url: `${api_name}/doAssign`,
method: 'post',
params: {
adminId,
roleId
}
})
}
/*
删除某个用户
*/
export function removeById(id) {
return request({
url: `${api_name}/remove/${id}`,
method: 'delete'
})
}
/*
批量删除多个用户
ids的结构: ids是包含n个id的数组
*/
export function removeUsers(ids) {
return request({
url: `${api_name}/batchRemove`,
method: 'delete',
data: ids
})
}
2.创建Controller
Controller是后端相应前端的部分,它会根据前端API的路径相应前端的操作。以获取后台用户分页列表为例,首先查看前端API
/*
获取后台用户分页列表(带搜索)
*/
export function getPageList(page, limit, searchObj) {
return request({
url: `${api_name}/${page}/${limit}`,
method: 'get',
params: searchObj
})
}
在其中我们需要获取的信息有:
请求参数:page, limit, searchObj
请求地址:${page}/${limit} (此处为正则表达式匹配)
请求方式:get
得到信息后可以开始编写Controller.
1.创建一个Controller并添加RestController,这样做就可以让SpringBoot管理Controller组件,并设置整个功能组的请求地址RequestMapping
@RestController
@RequestMapping("/admin/acl/user")
public class AdminController {
}
2. 设置请求地址和请求方式
由于两个参数是通过正则表达式匹配,因此需要使用@PathVariable,并且导入实体查询类。
@GetMapping("{current}/{limit}")
public Result list (@PathVariable Long current , @PathVariable Long limit , AdminQueryVo adminQueryVo) {
}
3.创建分页
@GetMapping("{current}/{limit}")
public Result list (@PathVariable Long current , @PathVariable Long limit , AdminQueryVo adminQueryVo) {
Page<Admin> adminPage = new Page<>(current , limit);
}
4.创建相应的数据查询组件,在这个数据查询组件中包含Mapper,Service,SerVvceImpl。通过Mapper调用Service,并在SerVvceImpl中实现查询功能即可
Mapper:
public interface AdminMapper extends BaseMapper<Admin> {
}
Service:
在Service中需要创建数据查询的接口,在查询接口中需要输入分页信息和查询对象。
public interface AdminService extends IService<Admin> {
//用户列表
IPage<Admin> selectPageUser(Page<Admin> pageParam , AdminQueryVo adminQueryVo);
}
ServiceImpl:
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper , Admin> implements AdminService {
@Override
public IPage<Admin> selectPageUser(Page<Admin> pageParam, AdminQueryVo adminQueryVo) {
//获取前端用户名和密码
String userName = adminQueryVo.getUsername();
String name = adminQueryVo.getName();
//实例化
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
//数据等值查询
if (!StringUtils.isEmpty(userName)) {
wrapper.eq(Admin::getUsername , userName);
}
if (!StringUtils.isEmpty(name)) {
wrapper.eq(Admin::getName , name);
}
//封装到分页器中
IPage<Admin> adminPage = baseMapper.selectPage(pageParam , wrapper);
return adminPage;
}
}
四、总结
总体来说,数据的增删改查是SpringBoot中的基本操作,但也是项目中最重要的过程。目前博主也在持续学习,博客持续更新中...