如果有t1到t20张表,如何优化xml拼接 UNION ALL 的 SQL
当有
t1 到 t20 张表,要在 MyBatis 的动态 XML 中根据用户传入条件选择表并拼接 UNION ALL 的 SQL 时,可以考虑以下几种优化方式,以提高代码的可读性和可维护性:
-
使用
<foreach>标签简化 SQL 拼接:
可以使用<foreach>标签来遍历表名列表,动态生成UNION ALL部分的 SQL,而不是使用多个<when>标签来处理不同数量表的情况。 -
提取公共部分 SQL:
将SELECT语句的公共部分(如SELECT id, name, value)提取出来,避免重复编写。 -
参数验证和默认处理:
增加对传入参数的验证和默认处理逻辑,确保在异常情况下也能返回合理的结果。
以下是优化后的 MyBatis XML 映射文件示例:
xml
<mapper namespace="com.example.dao.DataMapper">
<select id="selectData" resultType="com.example.entity.DataEntity">
<!-- 公共的 SELECT 部分 -->
<sql id="commonSelect">
SELECT id, name, value
</sql>
<choose>
<when test="tableNames != null and tableNames.size() > 0">
<trim prefix="" suffixOverrides="UNION ALL">
<foreach collection="tableNames" item="tableName" separator="UNION ALL">
<include refid="commonSelect" />
FROM ${tableName}
<where>
<!-- 可以根据需要添加其他条件 -->
</where>
</foreach>
</trim>
</when>
<otherwise>
<!-- 如果没有传入表名,返回空结果 -->
<include refid="commonSelect" />
FROM t1 WHERE 1 = 0
</otherwise>
</choose>
ORDER BY value DESC
LIMIT #{offset}, #{limit}
</select>
</mapper>
对应的
DataMapper 接口和 DataService 类的代码基本保持不变:
java
import java.util.List;
import java.util.Map;
public interface DataMapper {
List<DataEntity> selectData(Map<String, Object> params);
}
java
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@Transactional
public class DataService {
private final DataMapper dataMapper;
public DataService(DataMapper dataMapper) {
this.dataMapper = dataMapper;
}
public List<DataEntity> getData(List<String> tableNames, int offset, int limit) {
Map<String, Object> params = new HashMap<>();
params.put("tableNames", tableNames);
params.put("offset", offset);
params.put("limit", limit);
return dataMapper.selectData(params);
}
}
通过以上优化,代码更加简洁,并且能够适应更多数量的表,同时提高了代码的可维护性和扩展性。注意在实际应用中,要对 SQL 注入风险进行防范,尽量使用预编译语句。
摘抄自网络,便于检索查找。

浙公网安备 33010602011771号