玖叶教程网

前端编程开发入门

使用mybatis提供的@InsertProvider注解实现动态sql

背景

最近在做一个订单全链路追踪的系统,需求追踪几十个业务的订单链路,每次业务链路的开发工作量特别大,为了减少重复开发,实现灵活性和可修改性,系统进行了重新设计,采用管道-过滤器架构风格。为了适应不同的业务表,持久化层必须使用动态sql实现,达到通用的目的。

talk is simple,show me the codes

如何实现通用的动态sql

全网唯一实现的真正动态sql,适用于不同的表,不同的字段。灵活配置不同的表和字段。

直接上代码了,需要的可以直接复制。

全链路持久化处理器

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class StandardFullLinkPersistentHandler extends AbstractHandler {

    private static final String PERSISTENT_TABLE_NAME = "persistentTableName";

    private static final String PERSISTENT_FIELD_CODE = "persistentFieldCode";

    @Autowired
    private FullLinkService fullLinkService;

    @Override
    public void handle(HandleMessage handleMessage) {
        super.handle(handleMessage);
        FullLinkHandleMessage fullLinkHandleMessage = (FullLinkHandleMessage) this.handleMessage;
        List<Map<String, Object>> waitPersistentDataMap = fullLinkHandleMessage.getWaitPersistentDataMap();
        if (CollectionUtils.isEmpty(waitPersistentDataMap)) return;

        String tableName = this.getConfigValue(PERSISTENT_TABLE_NAME);
        String[] fieldNames = this.getConfigArrayValue(PERSISTENT_FIELD_CODE);
        //保存新的链路数据
        fullLinkService.insertByDynamicSql(waitPersistentDataMap,tableName,fieldNames);
    }

动态sql实现

public interface FullLinkCommonMapper {
  //动态批量插入数据
		@InsertProvider(type = FullLinkSqlProvider.class,method ="insertDynamicSql" )
    void insertByDynamicSql(@Param("list") List<Map<String, Object>> list, @Param("tableName") String tableName, @Param("fieldNames") String[] fieldNames);
}
public class FullLinkSqlProvider {

    public String insertDynamicSql(@Param("list") final List<Map<String, Object>> list, @Param("tableName") final String tableName,@Param("fieldNames") final String[] fieldNames) {

        SQL sql = new SQL()
                .INSERT_INTO(tableName)
                .INTO_COLUMNS(String.join(",", fieldNames));
        String pattern = buildFormatPattern(fieldNames);
        MessageFormat mf = new MessageFormat(pattern);
        for (int i = 0; i < list.size(); i++) {
            sql.INTO_VALUES(mf.format(new Object[]{i}));
            if (i != list.size() - 1){
                sql.ADD_ROW();
            }
        }

        return sql.toString();
    }

    private String buildFormatPattern(String[] fieldNames) {

        StringBuilder sb = new StringBuilder();
        String p= "#'{'list[{0}].%s}";
        final int length = fieldNames.length;
        for (int i = 0; i < length; i++) {
            sb.append(p);
            if (i != length - 1)
                sb.append(",");
        }
        return String.format(sb.toString(), fieldNames);
    }
}

全网唯一实现的真正动态sql,适用于不同的表,不同的字段。灵活配置不同的表和字段。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言