mybatis 自动填充字段 MybatisMetaObjectHandler

业务场景: 当一个实体有被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 {

    @Override
    public 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);
    }

    @Override
    public 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 {

    @Autowired
    ProductMapper productMapper;

    @Test
    void 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 提供的一个接口,用于在插入或更新数据时自动填充某些字段,比如创建时间、更新时间、创建人、更新人等。通过实现这个接口,你可以自定义这些字段的填充逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值