java - 在 MyBatis 中列出 'IN' 子句

标签 java mysql xml mybatis in-clause

<分区>

如何将整数列表传递给 MyBatis XML,以便在我的 MySQL 查询的 in 子句中使用?

我在 mapper-xml 中使用 Java 7、MySQL 5.6 数据库和 MyBatis 3.0.4 进行查询。文件。

目前,我正在将这个整数列表转换为字符串,并使用字符串替换(${} 运算符)将值放入“IN”子句中 - 虽然它按预期工作,但这种方法使参数容易受到攻击注入(inject)。

我试过使用 <foreach>元素,但我不知道要指定哪些属性。

下面是一个示例 Java 代码:

public List<Stripper> getStripperDetails(String club, List<Integer> stripperIds) {
        Map<String, Object> input = new HashMap<>();
        input.put("club", club);
        input.put("stripperIds", stripperIds);
        return stripClubMapper.getStripperDetails(input);
}

映射器 xml:

<select id="getStripperDetails" parameterType="java.util.HashMap" resultMap="StripperMap">
    SELECT STRIPPER_ID, STAGE_NAME, REAL_NAME, CLUB FROM EXOTIC_DANCERS WHERE CLUB = #{club} AND STRIPPER_ID IN     
    <foreach item="item" index="index" collection="stripperIds" open="(" separator="," close=")">
        #{index}
    </foreach>
</select>

我不知道要为 <foreach> 指定哪些属性元素 - 我不断遇到 #{index} 值的 NullPointerException。

你能帮我理解 <foreach> 的正确用法吗?元素?

编辑:

@10086 ,

下面是堆栈跟踪:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.NullPointerException
### The error may involve com.stripclub.mapper.stripClubMapper.getStripperDetails-Inline
### The error occurred while setting parameters
### Cause: java.lang.NullPointerException
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:67) ~[mybatis-spring-1.0.0-RC3.jar:1.0.0-RC3]
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:345) ~[mybatis-spring-1.0.0-RC3.jar:1.0.0-RC3]
    at com.sun.proxy.$Proxy208.selectList(Unknown Source) ~[na:na]
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:193) ~[mybatis-spring-1.0.0-RC3.jar:1.0.0-RC3]
    at org.apache.ibatis.binding.MapperMethod.executeForList(MapperMethod.java:85) ~[mybatis-3.0.4.jar:3.0.4]
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:65) ~[mybatis-3.0.4.jar:3.0.4]
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:38) ~[mybatis-3.0.4.jar:3.0.4]
    at com.sun.proxy.$Proxy209.getTransactionIds(Unknown Source) ~[na:na]

最佳答案

当与列表一起使用时,item 属性指定的值应该在 foreach 标签内使用。使用如下:

    <foreach item="sId" collection="stripperIds" separator="," open="(" close=")">
        #{sId}
    </foreach>

当使用列表时,索引属性不是强制性的。请参阅 MyBatis 文档部分以获取更多信息,或查看 DTD - http://mybatis.org/dtd/mybatis-3-mapper.dtd有关参数的更多信息:

    <!ELEMENT foreach (#PCDATA | include | trim | where | set | foreach | choose | if | bind)*>
    <!ATTLIST foreach
    collection CDATA #REQUIRED
    item CDATA #IMPLIED
    index CDATA #IMPLIED
    open CDATA #IMPLIED
    close CDATA #IMPLIED
    separator CDATA #IMPLIED
    >

此外,对象列表可以在 foreach 中访问,如下所示。您通常会将其用于 INSERT/UPDATE 语句:

示例 bean:

public class StripperBean {

    public StripperBean(int stripperID, String stripperName, String realName) {
        this.stripperID = stripperID;
        this.stripperName = stripperName;
        this.realName = realName;
    }

    private int stripperID; 
    private String stripperName;
    private String realName;        

    public int getStripperID() {
        return stripperID;
    }
    public void setStripperID(int stripperID) {
        this.stripperID = stripperID;
    }
    public String getStripperName() {
        return stripperName;
    }
    public void setStripperName(String stripperName) {
        this.stripperName = stripperName;
    }
    public String getRealName() {
        return realName;
    }
    public void setRealName(String realName) {
        this.realName = realName;
    }       
}

在您的实现中:

    Map<String, Object> input = new HashMap<>();
    input.put("club", club);
    List<StripperBean> strippers = new ArrayList<>();
    strippers.add(new StripperBean(1,"Ashley", "Jean Grey"));
    strippers.add(new StripperBean(2,"Candice","Diana Prince"));
    strippers.add(new StripperBean(3,"Cristal","Lara Croft"));        
    input.put("strippers", strippers);
    return stripClubMapper.saveStripperDetails(input);

在映射器 xml 中:

    <insert id="saveStripperDetails">
        INSERT INTO EXOTIC_DANCERS (STRIPPER_ID, STAGE_NAME, REAL_NAME)
        VALUES
        <foreach item="stripper" collection="input" separator=",">
            (#{stripper.stripperID},
            #{stripper.stripperName},
            #{stripper.realName})
        </foreach>
    </select>

顺便问个好问题 :)

关于java - 在 MyBatis 中列出 'IN' 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37885076/

相关文章:

php - 如何在 symfony 中输出 xml?

java - IntFunction<String> 和 Function<Integer, String>

Java:计算单词出现次数,程序计算 'empty'个单词

php - 将 'Array' 插入 mysql 表的各个字段(不是原始数据)

php - MySQL 将两个查询组合成 JSON 对象

python - lxml:获取所有叶节点?

java - Oracle->MSSQL : How to set identifier generator?

java - 改进 Java 中的字节转换

php - Mysql 正则表达式按数字选择

c++ - C++ 中 <Pointer, String> 的 unordered_map