首页  编辑  

Java/SpringBoot/Mybatis 处理 List 数据,例如 IN 查询

Tags: /Java/   Date Created:

在SpringBoot/Mybatis中,Mapper如果要处理 IN 语句,需要利用脚本功能。
如果按普通字符串处理,无法避免SQL注入攻击,所以建议按下面的方式处理:

考虑以下查询(Mybatis):

SELECT field1, avg(field2), min(field3), max(field4)
FROM your_table
WHERE create_time >= #{start} AND create_time < #{end}
    AND hour(create_time) IN (#{hours})
GROUP BY field1

如果直接运行,会SQL语法报错,因为 #{hours} 无法在mapper中正确处理。

正确的Mapper中的代码写法:

@Select({"<script>",
        "   SELECT field1,",
        "       avg(field2)",
        "       min(field3)",
        "       max(field4)",
        "   FROM your_table",
        "   WHERE create_time <![CDATA[ >= ]]> #{start} AND create_time <![CDATA[ < ]]> #{end} ",
        "       <foreach item='item' index='index' collection='hours' open=\"AND hour(create_time) IN (\" separator=',' close=\")\">",
        "           #{item}",
        "       </foreach>",
        "   GROUP BY field1",
        "</script>",})
List<Result> getReport(LocalDateTime start, LocalDateTime end, List<Integer> hours);
特别注意其中 >= 和 < 的处理,因为使用<script>后,<和>会当作XML的特殊字符处理,导致Mapper无法正常注册Bean,程序启动就报错失败,必须使用 <![CDATA[ 特殊字符 ]]> 方式 来转义。
特别注意 open 和 close 处理,上面的方法是可以处理 List 为空的情况的。