mybatis-plus是基于mybatis基础上的增强的持久层框架,也是目前Java项目开发的主流框架。本文介绍在SpringBoot中集成mybtais-plus的方法以及使用mybatis-plus开发增删改查模块。
一、引入mybatis-plus
在openjweb-core工程中引入mybatis-plus依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.5.2</version>
<scope>compile</scope>
</dependency>
在openjweb-sys的application.properties中增加mybatis-plus的配置:
mybatis-plus.mapper-locations=classpath*:**/mapper/mapping/*.xml
上面的配置指定mybatis-plus各种映射xml文件路径在mapper/mapping目录下。
接下来,在openjweb-sys工程的SpringBoot Application增加mapper扫描路径:
package org.openjweb.sys;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"org.openjweb"})
@MapperScan(value = {"org.openjweb.b2c.mapper","org.openjweb.core.mapper"})
public class OpenjwebSysApplication {
public static void main(String[] args) {
SpringApplication.run(OpenjwebSysApplication.class, args);
}
}
注意增加@MapperScan注解,用于扫描各模块的*Mapper.xml文件。
二、 配置一个分页、乐观锁拦截器
乐观锁拦截器用于处理实体类带@Version注解,当实体类的某个字段带@Version注解的时候,修改记录值的时候,乐观锁字段会自动加一。另外拦截器里还指定一个分页拦截器,用于处理mybatis-plus的分页(拦截器程序加到org.openjweb.core.config目录下):
package org.openjweb.core.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//如果配置多个插件,切记分页最后添加
//增加乐观锁拦截器,对应实体类的乐观锁字段可加@Version注解
log.info("开始增加乐观锁拦截器......................");
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//建议单一数据库类型的均设置 dbType
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
return interceptor;
}
}
三、创建数据库表
以电商系统的区域表b2c_area为例,下面是b2c_area表的结构和示例数据:
CREATE TABLE `b2c_area` (
`row_id` varchar(40) NOT NULL,
`sort_no` bigint(20) DEFAULT NULL,
`create_dt` varchar(23) DEFAULT NULL,
`update_dt` varchar(23) DEFAULT NULL,
`create_uid` varchar(32) DEFAULT NULL,
`update_uid` varchar(32) DEFAULT NULL,
`data_flg` varchar(6) DEFAULT NULL,
`obj_name` varchar(40) DEFAULT NULL,
`master_row_id` varchar(40) DEFAULT NULL,
`flow_trans_id` varchar(40) DEFAULT NULL,
`tree_code` varchar(255) DEFAULT NULL,
`record_version` bigint(20) NOT NULL,
`flow_status` varchar(16) DEFAULT NULL,
`area_name` varchar(100) DEFAULT NULL,
`com_id` varchar(40) DEFAULT NULL,
`header_name` varchar(60) DEFAULT NULL,
`area_code` varchar(40) NOT NULL,
`header_login_id` varchar(40) DEFAULT NULL,
`logo_path` varchar(100) DEFAULT NULL,
PRIMARY KEY (`row_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `b2c_area` VALUES ('22391594cb9146219943357c9c072c32', null, '2016-01-08 10:09:28', '2016-01-08 10:09:28', 'admin', 'admin', null, null, null, '1452218968212001020', '001004', '0', null, '南部大区', 'C0001', null, '001004', null, null);
INSERT INTO `b2c_area` VALUES ('3f5fa12464754db2846d835731f4aab0', null, '2016-10-21 16:40:07', '2016-10-21 16:40:07', 'admin', 'admin', null, null, null, '1477039207412001044', '004001', '0', null, '北京', '1413042849626000959', null, '004001', null, null);
INSERT INTO `b2c_area` VALUES ('4d33cce8ce63467cb67f49e55fa74b3b', null, '2016-10-21 16:40:20', '2016-10-21 16:40:20', 'admin', 'admin', null, null, null, '1477039220047001045', '004001001', '0', null, '东城', '1413042849626000959', null, '004001001', null, null);
INSERT INTO `b2c_area` VALUES ('5262c687c02840fb9628d06cf78e44fd', null, '2016-10-21 16:40:29', '2016-10-21 16:40:29', 'admin', 'admin', null, null, null, '1477039229538001046', '005', '0', null, '南方大区', '1413042849626000959', null, '005', null, null);
INSERT INTO `b2c_area` VALUES ('5dce6bc17f104ca6b56d1fb035f08e50', null, '2016-01-08 10:09:39', '2016-01-08 10:09:39', 'admin', 'admin', null, null, null, '1452218979665001021', '001005', '0', null, '北部大区', 'C0001', null, '001005', null, null);
INSERT INTO `b2c_area` VALUES ('6e52918bd77241518e34f2df8fb109bc', null, '2016-01-08 10:00:52', '2016-01-12 18:20:34', 'admin', 'admin', null, null, null, '1452218452615001016', '001', '4', null, '中国', 'C0001', null, '001', null, null);
INSERT INTO `b2c_area` VALUES ('6e57faa77ace4beabddd7234a2c9e5b4', null, '2016-01-12 15:13:42', '2016-01-12 15:13:42', 'admin', 'admin', null, null, null, '1452582822645002994', '002', '0', null, '美国', 'C0001', null, '002', null, null);
INSERT INTO `b2c_area` VALUES ('71e747f78c974804a8dbecac9358a994', null, '2016-10-20 17:06:42', '2016-10-20 17:06:42', 'admin', 'admin', null, null, null, '1476954402747001044', '003', '0', null, '111', '1111', null, '111', null, null);
INSERT INTO `b2c_area` VALUES ('9584de41936246b8a091ac47877e79c7', null, '2016-01-08 10:01:30', '2016-01-12 18:22:38', 'admin', 'admin', 'N', null, null, '1452218490511001017', '001001', '5', '00', '北京大区', 'C0001', null, '001001', null, null);
INSERT INTO `b2c_area` VALUES ('9aad7aacb33f4a02b6d6c96f36e271a0', null, '2016-01-08 10:01:43', '2016-01-08 10:05:54', 'admin', 'admin', null, null, null, '1452218503519001018', '001002', '3', null, '东部大区', 'C0001', null, '001002', null, null);
INSERT INTO `b2c_area` VALUES ('9bdd148bcb7d4bb2bad8509278aa7e20', null, '2016-01-16 08:53:22', '2016-01-16 08:53:22', 'admin', 'admin', null, null, null, '1452905602220001023', '001006', '0', null, '中部大区', 'C0001', null, '001006', null, null);
INSERT INTO `b2c_area` VALUES ('a458530726f84808b043b396ac8402e5', null, '2016-01-08 10:09:15', '2016-01-08 10:09:15', 'admin', 'admin', null, null, null, '1452218955262001019', '001003', '0', null, '西部大区', 'C0001', null, '001003', null, null);
INSERT INTO `b2c_area` VALUES ('d8314ad7352c4f31b9a431706f11be87', null, '2016-10-20 17:06:52', '2016-10-21 16:39:57', 'admin', 'admin', null, null, null, '1476954412353001045', '004', '3', '00', '北方大区', '1413042849626000959', null, '004', null, '/images/b2cArea/dc684e6b62ee4c7d9e3278fe279337e4.jpg');
四、电商模块(openjweb-b2b2c)增加openjweb-core的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.openjweb</groupId>
<artifactId>openjweb-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
五、电商模块中增加实体类、参数类、结果类
实体类:保存数据使用。
参数类:传递参数使用。
结果类:返回查询结果,如果结果集和表结构不是一一对应的,可自定义结果类。
在电商模块的org.openjweb.b2c.entity下创建实体类:
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("b2c_area")
public class B2cArea implements Serializable {
//销售地区实体类
// Fields
//@Id ---这个删除的时候没反应
@TableId(type = IdType.ASSIGN_UUID)
private String rowId;
private Long sortNo;
@TableField(fill = FieldFill.INSERT)
private String createDt;
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateDt;
@TableField(fill = FieldFill.INSERT)
private String createUid;
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateUid;
private String dataFlg;
private String objName;
private String masterRowId;
private String flowTransId;
private String treeCode;
@Version
private Long recordVersion = 0L;//因为是非空,所以试着给一个初始值
private String flowStatus;
private String areaName;
private String comId;
private String headerName;
private String areaCode;
private String headerLoginId;
private String logoPath;
}
注意在上面的代码中使用了ID生成方式、FieldFill.INSERT 用于插入时自动设置创建日期和创建人,FieldFill.INSERT_UPDATE 用于插入或修改时自动设置修改日期和修改人。这个后面会做详细介绍。
接下来在org.openjweb.b2c.module.params下创建一个参数类,参数类主要用于API接口方法中从前端接收参数、API向Service方法中传递参数等,下面是代码:
package org.openjweb.b2c.module.params;
import lombok.Data;
import org.openjweb.b2c.entity.B2cArea;
@Data
public class B2cAreaParam extends B2cArea {
private Integer page=1; //当前页
private Integer pageSize=10;//每页行数
public B2cAreaParam() {
page = 1;
pageSize = 10;
}
}
在参数类中除了继承B2cArea,另外增加了当前页面、每页行数。
接下来再增加一个结果类:
package org.openjweb.b2c.module.result;
import lombok.Data;
import java.io.Serializable;
@Data
public class B2cAreaResult implements Serializable {
private String comId;
private String rowId;
private String areaName;
}
B2cAreaResult也可以从B2cArea继承并添加其他字段,本例为了演示,此类仅定义了3个字段用于演示。
六、Mapper.xml、Mapper类、Service类、API接口类
接下来我们需要开发针对B2cArea的Mapper映射xml文件,B2cAreaMapper.xml,在前面我们指定了Mapper.xml存放路径为mapper/mapping, 所以我们在org.openjweb.b2c.mapper.mapping下创建一个B2cAreaMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.openjweb.b2c.mapper.B2cAreaMapper">
<select id="selectPageWithCondition" resultType="org.openjweb.b2c.entity.B2cArea" >
select * from b2c_area where 1=1
<where>
<if test="param.comId !=null and param.comId!=''">
and com_id = #{param.comId}
</if>
</where>
</select>
<select id="selectPageWithCondition2" resultType="org.openjweb.b2c.module.result.B2cAreaResult" >
select * from b2c_area where 1=1
<where>
<if test="param.comId !=null and param.comId!=''">
and com_id = #{param.comId}
</if>
</where>
</select>
</mapper>
注意上面的XML中,org.openjweb.b2c.mapper.B2cAreaMapper是对应的同名的B2cAreaMapper类,此类的代码如下:
package org.openjweb.b2c.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.openjweb.b2c.entity.B2cArea;
import org.openjweb.b2c.module.params.B2cAreaParam;
import org.openjweb.b2c.module.result.B2cAreaResult;
@Mapper
public interface B2cAreaMapper extends BaseMapper<B2cArea> {
IPage<B2cArea> selectPageWithCondition(Page<?> page, @Param("param") B2cAreaParam condition);
IPage<B2cAreaResult> selectPageWithCondition2(Page<?> page, @Param("param") B2cAreaParam condition);
@Select("SELECT * FROM b2c_area WHERE row_id = #{rowId}")
B2cArea selectByRowId(@Param("rowId") String rowId);
}
另外xml中,<select id="xx"> id引号中的是B2cAreaMapper类的方法名。resultType是返回值的类型,在此示例中,一个返回B2cArea,一个返回B2cAreaResult。另外B2cAreaMapper中,@Param 可以传递对象类型的变量,在xml中通过param.字段名引用。@Param("param")引号中的param在xml中通过#{param.comId}引用。selectByRowId方法演示了直接在注解里使用select语句的方式。
接下来再开发service类B2cAreaService.java:
package org.openjweb.b2c.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.openjweb.b2c.entity.B2cArea;
import org.openjweb.b2c.mapper.B2cAreaMapper;
import org.openjweb.b2c.module.params.B2cAreaParam;
import org.openjweb.b2c.module.result.B2cAreaResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
@Configuration
@EnableAsync
@Service
public class B2cAreaService extends ServiceImpl<B2cAreaMapper, B2cArea> {
@Autowired
private B2cAreaMapper b2cAreaMapper;
public IPage<B2cArea> list(B2cAreaParam param) {
//http://localhost:8001/api/b2c/area?comId=C0001
Page<B2cArea> page = new Page<>(param.getPage(), param.getPageSize());
return b2cAreaMapper.selectPageWithCondition(page,param);
}
public IPage<B2cAreaResult> list2(B2cAreaParam param) {
//http://localhost:8001/api/b2c/area?comId=C0001
Page<B2cAreaResult> page = new Page<>(param.getPage(), param.getPageSize());
return b2cAreaMapper.selectPageWithCondition2(page,param);
}
public B2cArea getObject(String rowId){
QueryWrapper<B2cArea> wrapper = new QueryWrapper<B2cArea>();
wrapper.eq("row_id",rowId);
B2cArea ent = this.b2cAreaMapper.selectOne(wrapper);
//另外一种查询方式
B2cArea ent1 = this.b2cAreaMapper.selectByRowId(rowId);
if(ent1!=null){
//输出区域名称
System.out.println(ent1.getAreaName());
}
return ent;
}
public void del(String selectedIds) throws Exception {
String[] ids = null;
int delCount = 0;
if(selectedIds!=null&&selectedIds.trim().length()>0){
ids = selectedIds.split(",");
//System.out.println(ids.length);
List<String> parmList = Arrays.asList(ids);
delCount = this.b2cAreaMapper.deleteBatchIds(parmList);
}
if(delCount==0){
throw new Exception ("删除失败!");
}
}
}
在service 类中,selectPageWithCondition和selectPageWithCondition2是自定义的方法,具体sql在B2cAreaMapper.xml中定义了。另外代码里的this.b2cAreaMapper.selectOne、deleteBatchIds是BaseMapper中封装的方法。Mybatis-plus的BaseMapper还封装了很多别的方法,具体可参考mybatis-plus官方网站:MyBatis-Plus 🚀 为简化开发而生MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。https://baomidou.com/
另外注意extends ServicieImpl后面两个类,一个是Mapper,一个是实体类。
接下来再开发一个接口类B2cAreaApi.java:
package org.openjweb.b2c.api;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.openjweb.b2c.entity.B2cArea;
import org.openjweb.b2c.module.params.B2cAreaParam;
import org.openjweb.b2c.service.B2cAreaService;
import org.openjweb.common.response.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/b2c/b2carea/")
@Slf4j
public class B2cAreaApi {
//http://localhost:8001/api/b2c/b2carea/edit?rowId=22391594cb9146219943357c9c072c32
@Autowired
B2cAreaService b2cAreaService;
@RequestMapping("/edit")
public ResponseResult edit(B2cAreaParam param){
B2cArea ent = this.b2cAreaService.getObject(param.getRowId());
return ResponseResult.okResult(ent);
}
/**
* 根据页面上选择的ID批量删除
* @param selectedIds
* @return
*/
@RequestMapping("/del")
public ResponseResult del( String selectedIds){
//http://localhost:8001/api/b2c/b2carea/del?selectedIds=12,133
try{
this.b2cAreaService.del(selectedIds);
return ResponseResult.okResult(0,"删除成功!");
}
catch(Exception ex){
ex.printStackTrace();
return ResponseResult.errorResult(-1,"删除失败!");
}
}
@RequestMapping("/save")
public ResponseResult save( B2cAreaParam param){
try {
log.info("新增记录调用开始..........");
//http://localhost:8001/api/b2c/b2carea/save?areaCode=8888888&areaName=9999&recordVersion=0
//没配乐观锁插件的时候,record_version必须手工赋值
//http://localhost:8001/api/b2c/b2carea/save?areaCode=8888888&areaName=121212
//param.setCreateDt(StringUtil.getCurrentDateTime());
//param.setUpdateDt(StringUtil.getCurrentDateTime());
//param.setCreateUid("system");
//param.setUpdateUid("system");
this.b2cAreaService.save(param);
log.info("新增记录调用结束..........");
return ResponseResult.okResult(0,"新增成功!");
}
catch(Exception ex){
ex.printStackTrace();
return ResponseResult.errorResult(-1,"新增失败!");
}
}
//http://localhost:8001/api/b2c/b2carea/save2?rowId=22391594cb9146219943357c9c072c32&token=admin111
@RequestMapping("/save2")
public ResponseResult save2( B2cAreaParam param){
try {
String rowId = param.getRowId();
log.info("根据rowId查询实体开始..........");
B2cArea ent = this.b2cAreaService.getObject(rowId);
log.info("根据rowId查询实体结束,开始保存..........");
if(ent!=null) {
log.info("修改名字.....");
ent.setAreaName("南部大区22223333");
ent.setUpdateUid(null);//得重置下才自动填充
ent.setUpdateDt(null);得重置下才自动填充 2024-02-05 11:28:40
}
else{
log.info("没找到实体类.....");
}
this.b2cAreaService.updateById(ent);
log.info("保存完毕..........");
}
catch(Exception ex){
ex.printStackTrace();
return ResponseResult.errorResult(-1,"新增失败!");
}
return ResponseResult.okResult(0,"success");
}
@RequestMapping("/save3")
public ResponseResult save3( B2cAreaParam param){
//http://localhost:8001/api/b2c/b2carea/save3?rowId=a458530726f84808b043b396ac8402e5&areaCode=new1&areaName=newname2&recordVersion=5
try {
this.b2cAreaService.updateById(param);
}
catch(Exception ex){
ex.printStackTrace();
return ResponseResult.errorResult(-1,"修改失败!");
}
return ResponseResult.okResult(0,"success");
}
@RequestMapping("/area")
public ResponseResult testArea( B2cAreaParam param){
IPage<B2cArea> page = this.b2cAreaService.list(param);
return ResponseResult.okResult(page.getRecords());
}
}
上面的API接口演示了增删改查的例子。其中查询API的链接为:
http://localhost:8001/api/b2c/b2carea/edit?rowId=22391594cb9146219943357c9c072c32
界面返回:
其他链接在代码中有,大家可自行测试。
六、实体类注解
实体类注解有自动填充、乐观锁等注解,需要配置一个mybatis的MetaObjectHandler,在org.openjweb.core.mybatisplus.handler下创建一个MyNetaObjectHandler类:
package org.openjweb.core.mybatisplus.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
String dt = String.valueOf(System.currentTimeMillis());
this.strictInsertFill(metaObject, "createDt", String.class, dt);
this.strictInsertFill(metaObject, "updateDt", String.class, dt);
//设置创建人
String userId = getCreateUid();
// 根据实际字段名填充
log.info("插入填充............,:"+userId);
this.strictInsertFill(metaObject, "createUid", String.class, userId);
this.strictInsertFill(metaObject, "updateUid", String.class, userId);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateDt", String.class, String.valueOf(System.currentTimeMillis()));
String userId = getCreateUid();
log.info(userId);
this.strictUpdateFill(metaObject, "updateUid", String.class, userId );
}
private String getCreateUid() {
// 这里获取当前登录用户的逻辑,根据实际情况实现
//怎样才能在这里获取到用户信息
//怎样在MyMetaObjectHandler获取当前用户
//怎样在MyMetaObjectHandler获取认证token
//采用下面的方式获取request,然后从request的header中获取token
String token = "";
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
token = request.getHeader("token");
if(StringUtils.isEmpty(token)){
token = request.getParameter("token");
}
// 你可以在这里使用request对象
}
//log.info("token::::");
//log.info(token);
return "abao2222";
}
}
在实体类注解中:
@TableId(type=IdType.ASSIGN_UUID) 是指定主键字段为32为UUID;
@TableId(type=IdType.ASSIGN_ID) 是指定主键字段为LONG型随机数字;
@Version 是乐观锁的注解,上文中有乐观锁对应的拦截器。如果乐观锁字段是非空字段,可指定一个默认值: private Long recordVersion = 0L;
FieldFill.INSERT 是插入设置默认值,FieldFill.INSERT_UPDATE是插入和修改都要设置默认值。在上面的程序代码中,插入触发默认值设置,设置创建日期和修改日期:
this.strictInsertFill(metaObject, "createDt", String.class, dt);
this.strictInsertFill(metaObject, "updateDt", String.class, dt);
插入设置创建人和修改人:
this.strictInsertFill(metaObject, "createUid", String.class, userId);
this.strictInsertFill(metaObject, "updateUid", String.class, userId);
另外创建人和修改人可在getCreateUid()中从request中的获取,一般不管是SpringSecurity还是JWT还是Shrio都可以从request中解析到当前登录用户。具体需要在后面整合了登录框架后再完善这个地方。
下面演示插入新记录后,检查创建人、创建日期、修改人、修改日期、row_id主键字段是否有值。修改记录看record_version是否自动加1。
http://localhost:8001/api/b2c/b2carea/save?areaCode=ABCD&areaName=beifangdaqu
查询数据库中新增了记录。
再检查下修改记录时是否record_version自动加1(B2cAreaApi的save2方法是根据row_id修改记录的方法),上面示例返回的row_id的值是ae7930e3f0708a523c4bd40fc7a53e9d:
http://localhost:8001/api/b2c/b2carea/save2?rowId=ae7930e3f0708a523c4bd40fc7a53e9d
执行后再查询数据库,record_version由原来的0变为1,area_name的值也修改成功:
七、总结
本文介绍了基于Mybatis-plus开发增删改查功能的完整示例,其中包括mybatis-plus分页的实现方式,以及使用注解实现字段的默认值填充。相信本文对刚上手学习mybatis-plus的朋友会有所帮助。另外因为基于mybatis或mybatis-plus需要开发的相关类比较多,除了必须的API和Service,还需要mapper类、Mapper.xml、实体类、参数类、结果类等,比JdbcTemplate()的开发方式可以说复杂不少,所以在实际项目开发时,最好再开发一个代码生成器,这样可以大幅度提高开发效率。
本文的示例代码可从 github下载,下载地址:
https://github.com/openjweb/cloud/tree/masterhttps://github.com/openjweb/cloud/tree/master