1.简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
2.入门
源码:https://github.com/zhongyushi-git/mybatis-plus-demo.git
2.1数据库准备
使用mysql数据库创建数据,执行脚本在根目录下的sql目录下
2.2环境搭建
1)新建一个SpringBoot的项目,导入需要的坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--mysql数据库依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> </dependency>
2)yml配置
#数据源配置 spring: datasource: #使用阿里巴巴的druid type: com.alibaba.druid.pool.DruidDataSource #配置数据库的路径和用户名密码 url: jdbc:mysql://127.0.0.1:3306/mybatisplus?useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true username: root password: zys123456
2.3引入mybatis-plus开发
1)导入依赖
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
2)创建实体类
@Data public class User { private Long id; private String name; private Integer age; private String email; }
3)创建dao继承BaseMapper
package com.zys.mybatisplusdemo.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.zys.mybatisplusdemo.entity.User; public interface UserDao extends BaseMapper<User> { }
4)在启动类上加mapper扫描
@SpringBootApplication @MapperScan("com.zys.mybatisplusdemo.dao") public class MybatisPlusDemoApplication { public static void main(String[] args) { SpringApplication.run(MybatisPlusDemoApplication.class, args); } }
5)创建controller
@RestController @RequestMapping("/users") public class UserController { @Autowired private UserDao userDao; @GetMapping("/list") public List<User> userList(){ List<User> users = userDao.selectList(null); return users; } }
为了演示方便,这里省略了service的部分而直接调用了dao层,具体见源码。
如果添加了mapper.xml,那么需要配置xml的位置,否则会出现无法绑定。
mybatis-plus.mapperLocations=classpath*:mapper/*.xml
6)测试
启动项目,访问http://localhost:8080/users/list即可看到所有的数据。
3.常用注解
3.1@TableName
其用来将实体对象与数据库表名进行对应。当实体名与数据库表名不一致时使用。
3.2@TableId
其是主键注解,指明是主键,默认把id作为主键。属性type用来指定类型:
1)IdType.AUTO是自动增长;
2)IdType.ASSIGN_UUID是String类型的uuid
3)IdType.INPUT是根据用户的输入作为主键
3.3@TableField
其是表的其他字段注解。属性exist用来指明是否是数据库的字段,值为false时不映射数据库表字段。详细的介绍见后续章节,这里的说明已供使用。
3.4注解开发
1)首先将数据库中表名改为t_user,然后实体User加上注解@TableName
@Data @TableName(value = "t_user") public class User { ...... }
启动项目,访问http://localhost:8080/users/list可以正常返回数据。
2)将数据库中表t_user的字段id改为t_id,然后修改实体User的属性id并设置自动增长
@Data @TableName(value = "t_user") public class User { //指定自动增长 @TableId(value = "t_id",type = IdType.AUTO) private Long id; ...... }
3)将数据表t_user的字段name改为t_name,然后修改实体User的属性name
@TableField(value = "t_name") private String name;
4)在实体User上添加一个属性,设置不作为数据库的字段
//不映射数据库表字段 @TableField(exist = false) private String aaa;
启动项目,同上进行访问,数据正常返回。在实际开发过程中,可根据需求使用注解。
4.条件构造器
方法 | 说明 | 示例 |
eq | 等于 |
|
allEq | 全等于 | eq("name", "老王") --->name = '老王' |
ne | 不等于 | ne("name", "老王") --->name <> '老王' |
gt | 大于 | gt("age", 18) --->age > 18 |
ge | 大于等于 | ge("age", 18) --->age >= 18 |
lt | 小于 | lt("age", 18) --->age < 18 |
le | 小于等于 | le("age", 18) --->age <= 18 |
between | BETWEEN 值1 AND 值2 | between("age", 18, 30) --->age between 18 and 30 |
notBetween | NOT BETWEEN 值1 AND 值2 | notBetween("age", 18, 30) --->age not between 18 and 30 |
like | LIKE '%值%' |
|
notLike | NOT LIKE '%值%' | notLike("name", "王") --->name not like '%王%' |
likeLeft | LIKE '%值' | likeLeft("name", "王") --->name like '%王' |
likeRight | LIKE '值%' | likeRight("name", "王") --->name like '王%' |
isNull | 字段为null | isNull("name") --->name is null |
isNotNull | 字段不为null | isNotNull("name") --->name is not null |
in | 同数据库in | in("age",{1,2,3}) --->age in (1,2,3) |
notIn | 同数据库not in | notIn("age",{1,2,3}) --->age not in (1,2,3) |
inSql | 相当于子查询和in |
|
notInSql | 相当于子查询和not in |
|
groupBy | 同数据库group by | groupBy("id", "name") --->group by id,name |
orderBy/orderByDesc | 同数据库order by 字段/order by 字段 desc | orderBy("id") --->order by id ASC |
having | 同数据库having | having("sum(age) > 10") --->having sum(age) > 10 |
or/and | 同数据库or/and | 略 |
netsted | 正常嵌套 不带 AND 或者 OR |
|
apply | 字符串拼接 |
|
last | 拼接在最后,谨慎使用 | last("limit 1")---> limit 1 |
exists/notExists | 拼接sql | exists("select id from table where age = 1") --->exists (select id from table where age = 1) |
select | 指定要查询的字段 |
|
set | 全局修改 | set("name", "") --->数据库字段值变为空字符串 |
5.CRUD操作
只进行简单的介绍,具体需求请自行开发,都是在这个基础上进行的。需要说明的是,下面的增加和修改操作,只会根据对象中存在不为null的属性来操作数据,当数据为null时不会改变数据库中的数据。
5.1添加insert
@PostMapping("/") public String save(User user){ int count = userDao.insert(user); if(count!=0){ return "添加成功"; }else{ return "添加失败"; } }
5.2删除delete
根据主键删除
@DeleteMapping("/{id}") public String delete(@PathVariable("id")long id){ int count = userDao.deleteById(id); if(count!=0){ return "删除成功"; }else{ return "删除失败"; } }
5.3修改update
根据id进行修改
@PutMapping("/") public String update(User user){ int count = userDao.updateById(user); if(count!=0){ return "修改成功"; }else{ return "修改失败"; } }
5.4简单查询
5.4.1selectList
在入门时,controller中设置的查询条件是null,实际上里面需要传递一个QueryWrapper<T>类型的对象,调用dao的selectList(),此对象中才有上面的那些方法。
1)查询年龄大于等于24的信息
@GetMapping("/list")
public List<User> userList(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//设置查询条件
queryWrapper.ge("age",24);//查询年龄大于等于24的信息
List<User> users = userDao.selectList(queryWrapper);
return users;
}
2)查询名字中含有‘o’的信息
queryWrapper.like("name","o");
5.4.2selectById
根据主键查询
@GetMapping("/{id}")
public User selectById(@PathVariable("id")long id){
return userDao.selectById(id);
}
5.4.3selectCount
查询符合条件的条数,一般和selectList结合使用。
@GetMapping("/list")
public Map<String,Object> userList(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//设置查询条件
queryWrapper.like("name","o");
List<User> users = userDao.selectList(queryWrapper);
Integer integer = userDao.selectCount(queryWrapper);
Map<String,Object> map=new HashMap<>();
map.put("data",users);
map.put("total",integer);
return map;
}
5.5分页查询
5.5.1分页插件配置
新建一个类配置其分页
package com.zys.mybatisplusdemo.config; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** * @Aauthor yushizhong * @Date 2020/5/17 16:19 * @Dec MybatisPlus分页配置 */ @EnableTransactionManagement @Configuration @MapperScan("com.zys.mybatisplusdemo.dao") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); return paginationInterceptor; } }
5.5.2单表分页查询
@GetMapping("/list") public IPage<User> userList(Integer curr,Integer limit){ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //设置分页,默认值是1,10 IPage<User> page=new Page<>(curr,limit); IPage<User> user = userDao.selectPage(page, queryWrapper); return user; }
5.5.3单表自定义分页查询
有时使用默认的分页查询无法实现需要的功能时,可以自定义分页查询。
先分析一下其自带的分页的方法,打开源码,看到接口中的selectPage方法:
<E extends com.baomidou.mybatisplus.core.metadata.IPage<T>> E selectPage(E page,
@org.apache.ibatis.annotations.Param("ew") com.baomidou.mybatisplus.core.conditions.Wrapper<T> queryWrapper);
那么自定义也就是模仿其写法,步骤如下:
1)在dao的接口中定义方法
IPage<User> selectPageList(IPage<User> page, @Param(Constants.WRAPPER) QueryWrapper<User> queryWrapper);
对第二个参数queryWrapper使用了@Param注解起别名,其名称使用的是常量的值(实际值是ew),常量的定义也是由官方定义好的,截图如下:
2)在xml中编写sql
<select id="selectPageList" resultType="com.zys.mybatisplusdemo.entity.User"> select * from user ${ew.customSqlSegment} </select>
那么后面的条件就直接使用"${ew.customSqlSegment}"进行代替了,它会根据设置的条件去查询。
5.5.4多表自定义分页查询
多表分页和单表的分页原来是一样的道理。现假设有两个表,t_student(学生表)和t_clazz(班级表)
1)先创建两个表
CREATE TABLE `clazz` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL COMMENT '班级名称', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL COMMENT '学生姓名', `clazzId` int(11) DEFAULT NULL COMMENT '班级id', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; insert into clazz values(1,'计算机1班'),(2,'计算机2班'),(3,'计算机3班'); insert into student values(null,'赵敏',1),(null,'张明',3),(null,'李慧',3),(null,'赵美美',2),(null,'张峰',2),(null,'孙强',2);
2)创建学生实体类
@Data @TableName(value = "user") public class Student { @TableId(value = "id",type = IdType.AUTO) private Long id; @TableField(value = "name") private String name; @TableField(value = "clazzId") private Integer clazzId; @TableField(exist = false) private String clazzName; }
3)创建controller接口
@GetMapping("/list") public JSONObject getList(Integer curr, Integer limit) { QueryWrapper<Student> queryWrapper = new QueryWrapper<>(); queryWrapper.like("t1.name", "张"); IPage<Student> page = new Page<>(curr, limit); IPage<Student> stu = studentDao.selectPageList(page, queryWrapper); JSONObject jsonObject = new JSONObject(); jsonObject.put("data", stu.getRecords()); jsonObject.put("total", stu.getTotal()); return jsonObject; }
4)在dao接口定义方法
IPage<Student> selectPageList(IPage<Student> page, @Param(Constants.WRAPPER) QueryWrapper<Student> queryWrapper);
5)在xml编写sql
<select id="selectPageList" resultType="com.zys.mybatisplusdemo.entity.Student"> select t1.*,t2.name "clazzName" from student t1 left join clazz t2 on t1.clazzId = t2.id ${ew.customSqlSegment} </select>
6)调用此接口,数据可以正常查询。执行日志如下:
当然,对于多表查询,如果使用默认的条件查询不能满足要求,可以把QueryMapper换成Mmap,那么在xml中使用对应的参数查询即可。 不过这种方式有些麻烦,但是可以实现更为复杂的需求
dao接口的方法:
IPage<Student> selectPageList2(IPage<Student> page, @Param(Constants.WRAPPER)Map<String, Object> map);
xml的sql:
<select id="selectPageList2" resultType="com.zys.mybatisplusdemo.entity.Student"> select t1.*, t2.name "clazzName" from student t1 left join clazz t2 on t1.clazzId = t2.id <where> <if test="ew.name != null and ew.name != ''"> and t1.name like concat('%',#{ew.name},'%') </if> </where> </select>
需要注意的是,在if标签中也需要带ew,否则会报错。
6.代码生成器
代码生成器自动生成包及需要的类名,节省开发的时间。前提是数据库中表已经建好,原因是它根据数据库表进行创建的。
首先导入依赖
<!--mybatis-plus代码生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency>
创建生成器类,然后执行main方法
package com.zys.mybatisplusdemo.config; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.util.ArrayList; import java.util.List; /** * @Aauthor yushizhong * @Date 2020/5/17 16:45 * @Dec 代码生成器 */ public class CodeGenerator { public static void main(String[] args) { // 代码生成器 AutoGenerator map = new AutoGenerator(); // 全局配置 GlobalConfig globalConfig = new GlobalConfig(); //配置生成文件的输出目录 globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java"); //设置开发人员名称 globalConfig.setAuthor("yushizhong"); //是否打开输出目录 globalConfig.setOpen(false); //mapper 命名方式 globalConfig.setMapperName("%sDao"); //service 命名方式 globalConfig.setServiceName("%sService"); map.setGlobalConfig(globalConfig); //数据源配置 DataSourceConfig dataSourceConfig = new DataSourceConfig(); //数据库的路径 dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=CTT"); //数据库驱动名称 dataSourceConfig.setDriverName("com.mysql.jdbc.Driver"); //数据库的登录用户名 dataSourceConfig.setUsername("root"); //数据库的登录密码 dataSourceConfig.setPassword("123456"); map.setDataSource(dataSourceConfig); // 包配置 PackageConfig pc = new PackageConfig(); //设置父包名 pc.setParent("com.zys.mybatisplusdemo"); pc.setMapper("dao"); map.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { } }; String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { //设置xml的输出路径 return System.getProperty("user.dir") + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); cfg.setFileOutConfigList(focList); map.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); //在代码总不生成xml templateConfig.setXml(null); map.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); //数据库表映射到实体的命名策略:把下划线变成大写 strategy.setNaming(NamingStrategy.underline_to_camel); //数据库表字段映射到实体的命名策略:把下划线变成大写 strategy.setColumnNaming(NamingStrategy.underline_to_camel); //是否使用lombok strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); // 写于父类中的公共字段 strategy.setSuperEntityColumns("id"); strategy.setControllerMappingHyphenStyle(true); //表前缀 strategy.setTablePrefix(pc.getModuleName() + "_"); map.setStrategy(strategy); //执行 map.execute(); } }
7.实现缓存
对于有些查询比较频繁的数据,可以放到缓存中,这里就以redis为例。mybatis-plus的缓存和mybatis的缓存实现原理类似,也有区别,mybatis的缓存实现请参考https://www.cnblogs.com/zys2019/p/11447169.html#_label7
7.1实战演练
1)导入redis的依赖,配置redis数据库参数(见源码)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2)在配置文件中开启缓存
mybatis-plus: configuration: #开启缓存 cache-enabled: true
如果不开启,那么缓存就不会生效。
3)获取spring创建的工厂
package com.zys.mybatisplusdemo.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Configuration; /** * @author zhongyushi * @date 2020/9/16 0016 * @dec 获取spring创建的工厂 */ @Configuration public class ApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; //把非spring创建好的工厂赋值给applicationContext,applicationContext在这个应用中是唯一的 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } //此创建好工厂后再获取对象 public static Object getBean(String beanName){ return applicationContext.getBean(beanName); } }
4)创建redis缓存配置类,实现Cache,重写方法
package com.zys.mybatisplusdemo.config; import com.zys.mybatisplusdemo.util.ApplicationContextUtil; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.cache.Cache; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author zhongyushi * @date 2020/9/28 0028 * @dec MybatisPlus缓存配置,使用redis作为缓存服务器 */ @Slf4j public class MybatisPlusCache implements Cache { // 读写锁 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); //这里使用了redis缓存,使用springboot自动注入 private RedisTemplate<String, Object> redisTemplate; private String id; //是mybatis必须要求的,必写。此id是xml中的namespace的值 public MybatisPlusCache(final String id) { if (id == null) { throw new IllegalArgumentException("未获取到缓存实例id"); } this.id = id; } //返回cache的唯一名称 @Override public String getId() { return this.id; } //缓存存值 @Override public void putObject(Object key, Object value) { //id是namespace的值,key是方法名,value是查询的结果 getRedisTemplate().opsForHash().put(id, key.toString(), value); } //缓存取值 @Override public Object getObject(Object key) { return getRedisTemplate().opsForHash().get(id, key.toString()); } //mybatis保留方法 @Override public Object removeObject(Object key) { return null; } //清空缓存,在增删改时会自动调用 @Override public void clear() { getRedisTemplate().delete(id); } @Override public int getSize() { return getRedisTemplate().opsForHash().size(id).intValue(); } @Override public ReadWriteLock getReadWriteLock() { return this.readWriteLock; } //获取RedisTemplate,不能通过注入的方式,原因是此类是由mybatis实例化的 private RedisTemplate getRedisTemplate() { //从上下文中获取redisTemplate RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate"); //设置key是string类型的序列 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置hashKey是string类型的序列 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); return redisTemplate; } }
在这个类中,分别重写了缓存设置、获取和删除的方法,把数据放到redis中。但是在此类中无法直接注入RedisTemplate,此类是由mybatis实例化的,不是由工厂实例化的。但是可以通过applicationContext来获取。
4)开启缓存
在UserDao接口上添加注解,指定缓存的配置类
@CacheNamespace(implementation= MybatisPlusCache.class,eviction=MybatisPlusCache.class) public interface UserDao extends BaseMapper<User> { ... }
5)测试。启动项目,第一次访问http://localhost:8080/users/list,查看控制台,会发现打印了sql的执行日志,多次访问此路径,它就从redis中获取数据了,同时可以在redis中看到此缓存信息。
对于增删改操作,都会清空缓存。因此作为缓存的数据一般是频繁查询,很少修改的信息。
7.2注意事项
通过对比mybatis的缓存可以发现,这里指定缓存的配置类是在dao接口上用注解配置的,而mybatis是在xml中配置的。实际上,也可以在xml中配置,但是二者不可兼得。
1)在dao接口中配置,那么只能缓存使用mybatis-plus查询出来的数据。也就是说,在xml中编写的查询语句所查询的结果是不会存入缓存的。
2)在xml中配置,那么只能缓存xml中编写的查询语句所查询的结果,使用mybatis-plus查询出来的数据是不会存入缓存的。
xml中配置如下:
<cache type="com.zys.mybatisplusdemo.config.MybatisPlusCache"/>
说明:使用mybatis-plus查询出来的数据指的是不编写sql,直接调用其内部已经编写好的查询方法。
8.@TableField注解详细说明
8.1说明
属性名 | 描述 |
value | 映射数据库的字段名 |
update | 预处理set进行自定义注入(结合fill) |
condition | 预处理where进行自定义条件查询(不常用) |
exist | 是否映射数据库的字段(默认是true,值为false则不映射) |
fill | 字段填充,需结合FieldFill使用 |
对于value和exist在前面已经介绍,在此不再赘述。
8.2 update-修改时操作
1)注入当前的时间
假如在每次更新数据时都需要把时间改成当前操作的时间,那么可以对其进行配置为数据库的时间:
@TableField(value = "update_time", update = "now()",fill = FieldFill.UPDATE) private Date updateTime;
需要结合fill使用,将其设置为更新时更新数据。设置后需调用mybatisplus自带的修改方法update(),否则不生效
输入的SQL如下:
UPDATE 表 SET update_time=now() WHERE 条件
2)修改变量的值
在每次修改时需要记录修改次数时,可以使用下面的方式。
@TableField(value = "count",update = "%s+1", fill = FieldFill.UPDATE) private Integer count;
其中"%s"是填充的字段,在这里是count,输出的SQL如下:
UPDATE 表 SET count=count+1 WHERE 条件
不过需要注意的是,在使用时,count在数据库中必须有值,为空时不会修改其值。
8.3 fill与FieldFill
对数据进行自动填充操作。上一小节结合update属性进行了说明。本小节不结合update属性进行添加或修改。
若需要在添加时插入添加时间,修改时同步修改时间。可对对象的字段进行设置,使用fill:
@TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime; @TableField(value = "update_time", fill = FieldFill.UPDATE) private Date updateTime;
还需要添加一个配置类实现MetaObjectHandler接口,重写两个方法
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.context.annotation.Configuration; import java.util.Date; @Configuration public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime", new Date(), metaObject); } }
可以看出在配置类中对方法重写时,指定了字段名和时间,从而实现自定义插入时间。其他的公共字段也可以使用这种方式。
这种方式显而易见有很大的局限性,对时间的两个字段进行了限定,那么对象的这两个字段就固定了。可根据实际需求选择是否使用这种方式。