fastmybatis write sub-table plugin

fastmybatis supports native plug-ins, you can configure the written plug-ins into the mybatis configuration file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<plugins>
		<plugin interceptor="xxxxx.MyInterceptor" />
	</plugins>

</configuration>

Here is a demo to write a sub-table plugin

Suppose there are 4 sub-tables, user_log0~3, to record the user's log situation

user_log0
user_log1
user_log2
user_log3

Now you need to dynamically query to specify a table

First generate the corresponding entity class, specify a table to generate, do not need to generate all

/**
 * 表名:user_logX
 * %index% 占位符
 */
@Table(name = "user_log%index%")
public class UserLog {
    ...
}

Note %index%the placeholders

Mapper unchanged

public interface UserLogMapper extends CrudMapper<UserLog, Long> {
}

Write a plug-in, create a new class to implement the org.apache.ibatis.plugin.Interceptorinterface

@Intercepts({@Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class, Integer.class})})
public class UserLogInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
        StatementHandler delegate = getFieldValue(handler, "delegate");
        MappedStatement mappedStatement = getFieldValue(delegate, "mappedStatement");
        BoundSql boundsql = handler.getBoundSql();
        String sqlId = mappedStatement.getId();

        if (StringUtils.startsWith(sqlId, "com.myapp.dao.UserLogMapper.")) {
            String sql = boundsql.getSql();
            // 获取index
            String index = String.valueOf(RequestContext.getCurrentContext().getIndex());
            // 替换sql
            sql = StringUtils.replace(sql, "%index%", index);
            setFieldValue(boundsql, "sql", sql);
        }
        return invocation.proceed();
    }

    private <T> T getFieldValue(Object handler, String name) {
        Field delegateField = ReflectionUtils.findField(handler.getClass(), name);
        delegateField.setAccessible(true);
        return (T) ReflectionUtils.getField(delegateField, handler);
    }

    private void setFieldValue(Object obj, String fieldName, Object fieldValue) {
        Field field = ReflectionUtils.findField(obj.getClass(), fieldName);
        if (field != null) {
            try {
                field.setAccessible(true);
                field.set(obj, fieldValue);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}

The function of this plugin is very simple, replace %index%the placeholder before executing sql, become a formal index, and then execute sql

Configure the plugin

<plugins>
    <plugin interceptor="com.myapp.interceptor.UserLogInterceptor" />
</plugins>

test case

public class PluginTest extends BaseTests {

    @Autowired
    private UserLogMapper userLogMapper;

    @Test
    public void testInsert() {
        // 指定某一张表
        RequestContext.getCurrentContext().setIndex(1);
        UserLog userLog = new UserLog();
        userLog.setLog("insert 111");
        userLogMapper.saveIgnoreNull(userLog);
    }

    @Test
    public void testUpdate() {
        RequestContext.getCurrentContext().setIndex(1);
        UserLog userLog = userLogMapper.getById(1L);
        userLog.setLog("update 111");
        userLogMapper.updateIgnoreNull(userLog);
    }

    @Test
    public void testGet() {
        RequestContext.getCurrentContext().setIndex(1);
        UserLog userLog = userLogMapper.getById(1L);
        System.out.println(userLog);
    }

    @Test
    public void testQuery() {
        RequestContext.getCurrentContext().setIndex(2);
        Query query = new Query();
        query.eq("user_id", 3);
        List<UserLog> list = userLogMapper.list(query);
        System.out.println(list);
    }

}

Here, a RequestContext.getCurrentContext().setIndex(1);specified table is used, and userIdwhich table can be dynamically calculated according to the modulo

For example, there are 16 sub-tables, thenindex=userId%16

See the complete code: fastmybatis-demo-plugin


fastmybatis is a mybatis development framework, its purpose is: simple, fast and effective.

  • Quick start with zero configuration
  • CRUD operations can be done without writing xml files
  • 支持mysql、sqlserver、oracle、postgresql、sqlite
  • Support custom sql, sql statement can be written in annotation or xml
  • Support integration with spring-boot, just rely on starter
  • Support plug-in writing
  • Lightweight, non-invasive, an extension of the official mybatis
{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324140592&siteId=291194637