马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目次
1. 使用 MyBatis 拦截器实现字段主动填充
2. 使用 MyBatis-Plus 实现字段主动填充
1. 使用 MyBatis 拦截器实现字段主动填充
实现步调
- 创建拦截器 实现 MyBatis 的 Interceptor 接口,通过拦截 MyBatis 实行的 SQL 操作来主动填充公共字段
- @Intercepts({
- @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
- })
- public class CommonFieldInterceptor implements Interceptor {
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- if (invocation.getArgs().length > 1) {
- Object parameter = invocation.getArgs()[1];
- if (parameter instanceof BaseEntity) {
- BaseEntity entity = (BaseEntity) parameter;
- if (isInsertOperation(invocation)) {
- entity.setCreateTime(new Date());
- entity.setUpdateTime(new Date());
- } else if (isUpdateOperation(invocation)) {
- entity.setUpdateTime(new Date());
- }
- }
- }
- return invocation.proceed();
- }
- private boolean isInsertOperation(Invocation invocation) {
- String methodName = ((MappedStatement) invocation.getArgs()[0]).getId();
- return methodName.contains("insert");
- }
- private boolean isUpdateOperation(Invocation invocation) {
- String methodName = ((MappedStatement) invocation.getArgs()[0]).getId();
- return methodName.contains("update");
- }
- @Override
- public Object plugin(Object target) {
- return Plugin.wrap(target, this);
- }
- @Override
- public void setProperties(Properties properties) {
- // 可选:设置属性
- }
- }
复制代码 - 定义基础实体类 创建一个基础实体类 BaseEntity,包含需要主动填充的公共字段,全部需要主动填充的实体类都应继承该类
- public class BaseEntity {
- private Date createTime;
- private Date updateTime;
- // getters and setters
- public Date getCreateTime() {
- return createTime;
- }
- public void setCreateTime(Date createTime) {
- this.createTime = createTime;
- }
- public Date getUpdateTime() {
- return updateTime;
- }
- public void setUpdateTime(Date updateTime) {
- this.updateTime = updateTime;
- }
- }
复制代码 - 配置拦截器 在 MyBatis 配置文件中注册拦截器
- <plugins>
- <plugin interceptor="com.example.mybatis.interceptor.CommonFieldInterceptor"/>
- </plugins>
复制代码 - 使用示例 创建一个继承 BaseEntity 的实体类,并在 Mapper 中使用该实体类举行数据库操作
- public class User extends BaseEntity {
- private Long id;
- private String name;
- // getters and setters
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
复制代码- @Mapper
- public interface UserMapper {
- @Insert("INSERT INTO user (name, create_time, update_time) VALUES (#{name}, #{createTime}, #{updateTime})")
- void insert(User user);
- @Update("UPDATE user SET name = #{name}, update_time = #{updateTime} WHERE id = #{id}")
- void update(User user);
- }
复制代码 2. 使用 MyBatis-Plus 实现字段主动填充
实现步调
- 定义实体类 在实体类中,使用 @TableField 注解来标记需要主动填充的字段,并指定填充策略
- @Data
- @TableName("user")
- public class User {
- @TableId(type = IdType.AUTO)
- private Integer id;
- private String username;
- @TableField(fill = FieldFill.INSERT)
- private LocalDateTime createdAt; // 创建时自动填充
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private LocalDateTime updatedAt; // 创建和更新时自动填充
- }
复制代码 - 实现 MetaObjectHandler 创建一个类实现 MetaObjectHandler 接口,并重写 insertFill 和 updateFill 方法,定义插入和更新时的填充逻辑。
- @Component
- public class MyMetaObjectHandler implements MetaObjectHandler {
- @Override
- public void insertFill(MetaObject metaObject) {
- this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);
- this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
- }
- @Override
- public void updateFill(MetaObject metaObject) {
- this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
- }
- }
复制代码 - 配置主动填充处理器 确保 MyMetaObjectHandler 类被 Spring 管理,可以通过 @Component 或 @Bean 注解来实现。
- 使用示例 创建一个继承自 BaseMapper 的 Mapper 接口
- @Mapper
- public interface UserMapper extends BaseMapper<User> {
- }
复制代码 测试代码
- @Component
- public class MyTestRunner implements CommandLineRunner {
- @Autowired
- private UserMapper userMapper;
- @Override
- public void run(String... args) throws Exception {
- // 测试插入时自动填充
- User user = new User();
- user.setUsername("John Doe");
- userMapper.insert(user);
- System.out.println("Inserted user: " + user);
- // 测试更新时自动填充
- user.setUsername("Jane Doe");
- userMapper.updateById(user);
- System.out.println("Updated user: " + user);
- }
- }
复制代码 两种方式的对比
- MyBatis 拦截器方式
- 优点:灵活性高,可以自定义复杂的填充逻辑,适用于复杂的业务场景。
- 缺点:实现相对复杂,需要编写较多代码,且需要手动添加注解。
- MyBatis-Plus 方式
- 优点:使用简单,代码量少,开箱即用,与 MyBatis-Plus 无缝集成。
- 缺点:填充逻辑相对固定,扩展性较差。
选择建议
- 假如需要实现简单的主动填充功能,如创建时间和更新时间的主动填充,推荐使用 MyBatis-Plus 方式。
- 假如有复杂的业务逻辑,需要自定义填充逻辑,推荐使用 MyBatis 拦截器方式。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |