MyBatis-Plus 实体类实现动态表名

项目中使用了 MyBatis-Plus 简化开发,在项目中,对数据库表的操作,可以通过在数据表实体类中添加@TableName("table_name") 来指定该实体所对应的表,如下:

@TableName("user")
@Data
public class User implements Serializable {

   private static final long serialVersionUID = 4462743168115185463L;

   
}

在业务中有这么个需求,在User表添加的时候,同时要对另一张表today_user进行添加 ,user 表和 today_user 表的表结构是一样的,只是一张是总表,一张是当日表。由于总表数据量过大,才加了today_user 这张表方便某个业务查询,以上是业务背景。

由于使用了@TableName("user") 注解,指定了表名,想要插入到 today_user 无法使用User这个实体类,最low的办法就是以下:

// 新建一个TodayUser类,和一个todayUserService 
List<User> dataList = new ArrayList<>(metaData.size());
List<TodayUser> todayDataList = new ArrayList<>(metaData.size());
for (String[] data : metaData) {
    User user = new LoginRole(data);
    // 再存一份到今日用户表里
    TodayUser todayUser = new TodayUser(data);
    dataList.add(user);
    todayDataList.add(todayUser);
}
userService.saveBatch(dataList);
todayUserService.saveBatch(todayDataList);

这样做确实可以实现需求,但是就是太low了,明明只要修改表名就可以,却还要新增一个实体对象、service接口、service实现类以及mapper。

查看,其实MyBatis-Plus官网是提供了方法实现的

直接上代码:
在实体类添加属性:

@Data
@TableName("user")
public class User implements Serializable {

    private static final long serialVersionUID = -4462743168115185463L;

    /**
     * 用于区分存到总表还是今日表
     */
    @TableField(exist = false)
    private String tableName = "user";
}

业务代码:


List<User> dataList = new ArrayList<>(metaData.size());
for (String[] data : metaData) {
    User user = new LoginRole(data);
    dataList.add(user);
}
userService.saveBatch(dataList);
// 遍历List,设置实体类的tableName属性
dataList.forEach(p -> p.setTableName("today_user"));
userService.saveBatch(dataList);
/**
 * 动态表名处理器
 */
@Configuration
public class DynamicTableNameHandler {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
        dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {{
            put("user", (metaObject, sql, tableName) -> {
                String dynamicTableName = getDynamicTableName(metaObject);
                if(dynamicTableName!=null){
                    return dynamicTableName;
                }else{
                    return tableName;
                }
            });
        }});
        paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
        return paginationInterceptor;
    }


    /**
     * 获取元数据里的动态表名
     * @param metaObject 元数据对象
     * @return 表名
     */
    private String getDynamicTableName(MetaObject metaObject){
        Object originalObject = metaObject.getOriginalObject();
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(originalObject));
        JSONObject boundSql = jsonObject.getJSONObject("boundSql");
        JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
        return String.valueOf(parameterObject.get(Dynamic_Table_Name));
    }
}
  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值