业务场景: 当一个实体有被N个接口跟新或添加.
此时有需求, 当更新或新增该实体对象时, 需要执行一段业务逻辑解决方案1 : 找到所有操作该实体的接口, 在所有接口中调用该逻辑. 此方案费力且容易漏掉接口
解决方案2 : 使用 MybatisMetaObjectHandler
一下是项目实例
sql
CREATE TABLE `product` (`id` int NOT NULL AUTO_INCREMENT,`name_zh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`name_zh_pinyin` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci```
POM
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.17.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- Hutool Core --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.13</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version><scope>runtime</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-math3</artifactId><version>3.6.1</version> <!-- 请检查是否有更新的版本 --></dependency></dependencies>
实体类
package com.example.demo.handle;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;@Data
public class Product {@TableId(value = "id", type = IdType.AUTO)Integer id;@TableField(value = "name_zh")String nameZh;@TableField(value = "name_zh_pinyin",fill = FieldFill.INSERT_UPDATE)String nameZhPinyin;
}
mapper
package com.example.demo.handle;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface ProductMapper extends BaseMapper<Product> {}
MybatisMetaObjectHandler
package com.example.demo.handle;import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class MybatisMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {if (metaObject.getValue("nameZh") == null) {return;}String pingYin = metaObject.getValue("nameZh").toString();pingYin = PinyinUtil.getPinyin(pingYin);// 新增自动执行 实体类字段名称this.setFieldValByName("nameZhPinyin", pingYin, metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {if (metaObject.getValue("nameZh") == null) {return;}// 更新自动执行String pingYin = metaObject.getValue("nameZh").toString();pingYin = PinyinUtil.getPinyin(pingYin);this.setFieldValByName("nameZhPinyin", PinyinUtil.getPinyin(pingYin), metaObject);}}
测试类
package com.example.demo;import com.example.demo.handle.Product;
import com.example.demo.handle.ProductMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class DemoApplicationTests {@AutowiredProductMapper productMapper;@Testvoid contextLoads() {System.out.println("-------------------自动添加拼音----------------------");Product product2 = new Product();product2.setNameZh("李四");productMapper.insert(product2);productMapper.selectList(null).forEach(System.out::println);}}
输出结果
-------------------自动添加拼音----------------------
2024-10-09 16:44:37.878 INFO 40880 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2024-10-09 16:44:38.445 INFO 40880 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
Product(id=10, nameZh=李四, nameZhPinyin=li si)
结论
可以看出, 新增数据时并未添 set nameZhPinyin 字段
但是从查询结果可以看出, 的确 nameZhPinyin 被更新到数据表中
从上面的案例中也许并未提现该接口的作用, 当有 100个更新时,就避免了很多重复性的操作
MetaObjectHandler 是 MyBatis-Plus 提供的一个接口,用于在插入或更新数据时自动填充某些字段,比如创建时间、更新时间、创建人、更新人等。通过实现这个接口,你可以自定义这些字段的填充逻辑。