Mybatis-Plus 动态表名3.4.3.4,3.4,3.1.2

简介: Mybatis-Plus 动态表名3.4.3.4,3.4,3.1.2
  • 近日公司需要新框架需要兼容旧代码,旧代码用的mybatis手写的动态表名 ,大概是实体类定义一个table字段 然后将table的值传到映射文件中,${table} 这种方式, 研究了一下mp发现可以直接用拦截器替换表名就有了以下代码

1. 3.4.3.4 (最新版)动态表名实现

1.配置类 (官方方式)

@Configuration
@MapperScan("com.cars.ysdd.clts.domain.clts.dao")
public class MybatisPlusConfig {

    static List<String> tableList(){
        List<String> tables = new ArrayList<>();
        tables.add("user");
        return tables;
    }

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
            // 获取参数方法
            /*Map<String, Object> paramMap = RequestDataHelper.getRequestData();
            paramMap.forEach((k, v) -> System.err.println(k + "----" + v));

            System.err.println("表名:"+tableName);
            System.err.println("sql:"+sql);
            String year = "_2018";
            int random = new Random().nextInt(10);
            if (random % 2 == 1) {
                year = "_2019";
            }*/
            String newTable = null;
            for (String table : tableList()) {
                newTable = RequestDataHelper.getRequestData(table);
                if (table.equals(tableName) && newTable!=null){
                    tableName = newTable;
                    break;
                }
            }
            return tableName;
//            return tableName + year;
        });
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        // 3.4.3.2 作废该方式
        // dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
        return interceptor;
    }
}

2.请求参数传递辅助类

package com.baomidou.mybatisplus.samples.dytablename.config;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import java.util.Map;

/**
 * 请求参数传递辅助类
 */
public class RequestDataHelper {
    /**
     * 请求参数存取
     */
    private static final ThreadLocal<Map<String, Object>> REQUEST_DATA = new ThreadLocal<>();

    /**
     * 设置请求参数
     *
     * @param requestData 请求参数 MAP 对象
     */
    public static void setRequestData(Map<String, Object> requestData) {
        REQUEST_DATA.set(requestData);
    }

    /**
     * 获取请求参数
     *
     * @param param 请求参数
     * @return 请求参数 MAP 对象
     */
    public static <T> T getRequestData(String param) {
        Map<String, Object> dataMap = getRequestData();
        if (CollectionUtils.isNotEmpty(dataMap)) {
            return (T) dataMap.get(param);
        }
        return null;
    }

    /**
     * 获取请求参数
     *
     * @return 请求参数 MAP 对象
     */
    public static Map<String, Object> getRequestData() {
        return REQUEST_DATA.get();
    }
}

3.使用

@SpringBootTest
class DynamicTableNameTest {
    @Resource
    private UserMapper userMapper;

    @Test
    void test() {
        
        RequestDataHelper.setRequestData(new HashMap<String, Object>() {{
            put("user", "user_2018");
        }});


        // 自己去观察打印 SQL 目前随机访问 user_2018  user_2019 表
        for (int i = 0; i < 6; i++) {
            User user = userMapper.selectById(1);
            System.err.println(user.getName());
        }
    }
}

2. 3.4.1版

1. 配置类

  • 这里的RequestDataHelper 用的是上文的3.4.3.4中的
@Configuration
@MapperScan("com.cars.ysdd.clts.domain.clts.dao")
public class DynamicTableNameHandler {

    static List<String> tableList() {
        List<String> tables = new ArrayList<>();
        tables.add("CR_CZJM");
        return tables;
    }

    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor paginationInterceptor = new MybatisPlusInterceptor();
        // DynamicTableNameParser 表名解析器,动态解析表名,ITableNameHandler 表名处理。
        DynamicTableNameInnerInterceptor dynamicTableNameParser = new DynamicTableNameInnerInterceptor();
        dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, TableNameHandler>(2) {{
            //metaObject 元对象 ;sql 执行的SQL ;tableName 表名
            //这里put的key就是需要替换的原始表名,也就是实体类的表名
            //这里的tableName就是我们定义的动态表名变量,
            for (String table : tableList()) {
                put(table, (sql, tableName) -> {
                    // 获取传入参数 tableName,tableName的值就是替换后的表名
                    return RequestDataHelper.getRequestData(table) == null ? tableName : RequestDataHelper.getRequestData(table);
                });
            }
        }});
        paginationInterceptor.addInnerInterceptor(dynamicTableNameParser);
        return paginationInterceptor;
    }
}

2. 使用

/**
     * @param crCzjmDO 实体类
     * @return 执行条数
     */
    @Override
    public int insert(CrCzjmDO crCzjmDO) {
        RequestDataHelper.setRequestData(new HashMap<String, Object>(){{
            put("CR_CZJM","TJFX.CR_CZJM");
        }});
        return crCzjmMapper.insertSelective(crCzjmDO);
    }

3. 3.4 以下版本 (3.1.2 版为例)

1.配置类

@Configuration
public class DynamicTableNameHandler {


    /**
     * 适用于相同表结构 不同表名
     */

    //实体类对应的表名字段
    public static final String DYNAMIC_TABLE_NAME = "tableName";

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // DynamicTableNameParser 表名解析器,动态解析表名,ITableNameHandler 表名处理。
        DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
        dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {{
            //metaObject 元对象 ;sql 执行的SQL ;tableName 表名
            //这里put的key就是需要替换的原始表名,也就是实体类的表名
            //这里的tableName就是我们定义的动态表名变量,
            put("payment", (metaObject, sql, tableName) -> {
                // 获取传入参数 tableName,tableName的值就是替换后的表名
                Object param = getParamValue(DYNAMIC_TABLE_NAME, metaObject);
                if(param == null){
                    return tableName;//不带tableName参数就返回原表名
                }else {
                    return param.toString();//带tableName参数就返回新表名
                }
            });
            /*put("payment", (metaObject, sql, tableName) -> {
                // 获取传入参数 tableName,tableName的值就是替换后的表名
                Object param = getParamValue(DYNAMIC_TABLE_NAME, metaObject);
                if(param == null){
                    return tableName;//不带tableName参数就返回原表名
                }else {
                    return param.toString();//带tableName参数就返回新表名
                }
            });*/
        }});
        paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
        return paginationInterceptor;
    }

    /**
     * 获取动态表tableName参数的值
     */
    private Object getParamValue(String title, MetaObject metaObject){
        //获取参数
        Object originalObject = metaObject.getOriginalObject();
        JSONObject originalObjectJSON = JSON.parseObject(JSON.toJSONString(originalObject));
        JSONObject boundSql = originalObjectJSON.getJSONObject("boundSql");
        try {
            JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
            return parameterObject.get(title);
        }catch (Exception e) {
            return null;
        }
    }
}

2. 实体类示例

  • 定义一个与上边配置类中DYNAMIC_TABLE_NAME 的值对应名称的字段(非数据库
@Data
public class Payment implements Serializable {

    private static final long serialVersionUID = 1L;

    private String serial;

    @TableField(exist = false)
    private String tableName;
}

3. 使用

  • 直接setTableName即可
    @Override
    public List<Payment> selectByTable(String table) {
        Payment payment = new Payment();
        payment.setTableName(table);
        return paymentMapper.select(payment);
    }
  • 以上内容有错误欢迎指出~
相关文章
|
4月前
|
SQL Java 数据库连接
mybatis动态SQL常用语法总结
MyBatis 使用 OGNL 表达式语言处理动态SQL,如 `if` 标签进行条件判断,`choose`、`when`、`otherwise` 实现多条件选择,`where`、`set` 管理SQL关键字,`trim` 提供通用修剪功能,`foreach` 遍历集合数据。`sql` 和 `include` 用于代码重用,`selectKey` 处理插入后的返回值。参数传递支持匿名、具名、列表、Map、Java Bean和JSON方式。注意SQL转义及使用合适的jdbcType映射Java类型。
91 7
|
5月前
|
SQL XML Java
MyBatis动态SQL------------------choose用法
MyBatis动态SQL------------------choose用法
59 1
|
5月前
|
SQL XML Java
MyBatis第四课动态SQL
MyBatis第四课动态SQL
|
5月前
|
SQL XML Java
Mybatis进阶——动态SQL(1)
Mybatis进阶——动态SQL(1)
44 3
|
5月前
|
SQL 缓存 Java
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
|
5月前
|
SQL Java 数据库连接
MyBatis动态SQL
MyBatis动态SQL
62 0
|
5月前
|
JSON 前端开发 数据格式
MyBatis-Plus动态分页查询
MyBatis-Plus动态分页查询
|
5月前
|
SQL Java 数据库连接
【MyBatis】MyBatis操作数据库(二):动态SQL、#{}与${}的区别
【MyBatis】MyBatis操作数据库(二):动态SQL、#{}与${}的区别
62 0
|
5月前
|
SQL Java 数据库连接
JavaWeb基础第三章(MyBatis的应用,基础操作与动态SQL)
JavaWeb基础第三章(MyBatis的应用,基础操作与动态SQL)
|
6月前
|
SQL XML Java