项目场景:
动态处理SQL查询多个表,其中多个字段列名相同
例如:表A和表B都有列NAME和CODE,于是理解为:通过StringBuilder存储一个固定的SELECT NAME, CODE,
后再分别处理FROM A
和FROM B
及其各自的过滤条件
问题描述
通过StringBuilder动态处理多个SQL,其中部分列名一致,想直接存储一个StringBuilder后,只拼接后面的
public static void main(String[] args){
StringBuilder sqlBuilder = new StringBuilder("SELECT NAME, CODE, ");
String sql_SelectA = sqlBuilder.append("A.AGE FROM A").toString();
String sql_SelectB = sqlBuilder.append("B.PRICE FROM B").toString();
// 理想结果是
// sql_SelectA = "SELECT NAME, CODE, A.AGE FROM A";
// sql_SelectB = "SELECT NAME, CODE, B.PRICE FROM B";
// 实际却是
// sql_SelectA = "SELECT NAME, CODE, A.AGE FROM A";
// sql_SelectB = "SELECT NAME, CODE, A.AGE FROM ASELECT NAME, CODE, B.PRICE FROM B";
}
原因分析:
下面是StringBuilder的append方法源码,他会返回以自身操作后的值,即会改变原始的sqlBuilder
@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(String str) {
super.append(str);
return this;
}
解决方案:
sqlBuilder先转换为String存储(String是不可变的,之所以可以String a = “a” + “b”;是因为这样是新生成了一个String对象后重新处理,频繁操作对于内存不友好。)
// 解决方案
StringBuilder sqlBuilder = new StringBuilder("SELECT NAME, CODE, ");
String sql = sqlBuilder.toString();
String sql_SelectA = new StringBuilder(sql).append("A.AGE FROM A").toString();
String sql_SelectB = new StringBuilder(sql).append("A.AGE FROM A").toString();
String和StringBuilder互转
// String -> StringBuilder
StringBuilder stringBuilder = new StringBuilder("string");
String string = stringBuilder.toString();