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