zoukankan      html  css  js  c++  java
  • ibatis传入数组或List

      小结一下ibatis框架下,传入参数为数组类型或者是List类型的sql写法。标签里面都不需要表名  

        1.传入字符串数组,不需要标明parameterClasss,数组和List类型对象一样都可以用<iterate>标签进行遍历。

    <select id="selectOrgIdByNameStr" resultClass="Integer">
    		SELECT id
    		FROM org
    		WHERE name IN
    		<iterate close=")" open="("  conjunction=",">
                <![CDATA[
                     #[]# 
                ]]> 
           </iterate> 
    	</select>
    

       java调用代码(注意空指针问题):

    @Override
    	public List<Integer> selectOrgIdByNameStr(String[] orgArchArr) {
    		 return baseDao.queryForList("org.selectOrgIdByNameStr", orgArchArr, Integer.class);
    	}
    

      2.传入List<Integer>,这个时候parameterClass传的是List接口的类路径,而不是List的泛型参数的类路径!

    @Override
    	public List<WaiterCgExt> searchWaiters(ModAccManVo vo) {
    		List<Integer> widList = baseDao.queryForList("zone.waiter.searchWaitersId", vo, Integer.class);
    		if(CollectionUtils.isEmpty(widList)) {
    			return new ArrayList<WaiterCgExt>();
    		}
    		return baseDao.queryForList("zone.waiter.searchWaiters", widList, WaiterCgExt.class);
    	}
    

        3.传入的List的元素是复杂的对象类型,类型类型里面包含id属性。同样,parameterClass传入的是List接口的类路径,而不是List的泛型参数的类路径。遍历的时候,用#list[].id#就行了,“.”后面跟上要枚举的属性名称

    <select id="selectWaitersByOrgList" resultClass="com.chat.domain.zone.Waiter" parameterClass="java.util.List">
    		SELECT id, pin as userName
    		FROM waiter
    		WHERE org_id IN 
    		 	<iterate open="(" close=")" conjunction=",">  
                	#list[].id#  
                </iterate>   
                AND yn = 1
    	</select>
    

      batis中list做回参很简单,resultClass设为list中元素类型,dao层调用

    (List)getSqlMapClientTemplate().queryForList("sqlName", paraName);
    

      

    并经类型转换即可,做入参还需要稍微调整下,本文主要讲list做入参碰到的几个小问题 

    做入参主要有两种方法一种是以list直接作为入参,另一种是将list作为map的元素之一为入参,个人觉得第一种明显优势,就一个list为入参,还用map包装一层多蛋疼。下面的介绍都以这个sql为例

    <sql> id="getProjectJobIdsByProjectIds" resultClass="java.lang.Integer"  
        parameterClass="java.util.ArrayList">  
          
        SELECT id   
        FROM cic_job   
        WHERE last_buildid <> 'NULL'  
          
        "AND" open="(" close=")" conjunction="or">  
            CRID=#projectIdList[]#  
    </sql>
    

      以上是正确的写法,意义大家不用关注,重点放在倒数2到4行,表示以list为入参,其中projectIdList为dao层传入的参数名。主要写法就是parameterClass="java.util.ArrayList",然后加上

      "AND" open="(" close=")" conjunction="or">  
    CRID=#projectIdList[]#  
    

      

    意思就是迭代器循环projectIdList,并用or拼接形成sql,拼接完后用()括起来,在加上前缀and

    1、iterate property的问题

    网上很多写法是

    1. "projectIdList" prepend="AND" open="(" close=")" conjunction="or">  

    即多了一个property,这个时候ibatis会从参数中寻找属性为projectIdList的对象,而list是一个对象没有属性就会报

    Cause: com.ibatis.common.beans.ProbeException: Error getting ordinal list from JavaBean. Cause java.lang.StringIndexOutOfBoundsException: String index out of range: -1  
    

      

    异常,解决方法就是去掉property="projectIdList"

    其实这种写法是相对第二种以map为参数而言的,你可以使用map传入参数设置属性为 property对应名即可

    2、< ! [ CDATA[的问题

    大家注意到上面sql添加有 ! [ CDATA[,它的作用是对一些字符进行转移,具体可以参见http://renren.it/a/JAVAbiancheng/iBATIS/20111105/139874.html

    但上面sql如果写成

    1. <select id="getProjectJobIdsByProjectIds" resultClass="java.lang.Integer"  
    2.     parameterClass="java.util.ArrayList">  
    3.     <![CDATA[  
    4.     SELECT id   
    5.     FROM cic_job   
    6.     WHERE last_buildid <> 'NULL'  
    7.     <iterate prepend="AND" open="(" close=")" conjunction="or">  
    8.         CRID=#projectIdList[]#  
    9.         </iterate>  
    10.     ]]>  
    11. </select>  

    即扩大转义范围会出现如下错误

    1. com.ibatis.common.beans.ProbeException: There is no READABLE property named 'projectIdList[]' in class 'java.util.ArrayList'  
    2. 解决方法,就是缩小 CDATA的范围。原因是CDATA导致系统无法识别动态判断部分。

      在使用ibatis时,经常需要配置待执行的sql语句。使用过ibatis的朋友都知道,无可避免的都会碰到一些不兼容、冲突的字符,多数人也都 知道用<![CDATA[   ]]>标记避免Sql中与xml规范相冲突的字符对xml映射文件的合法性造成影响。但是,如果在ibatis中使用了动态语句的时候,还是有一些 细节需要注意。下面举例说明一下:

      环境:oracle、ibatis、java

      错误例1:符号“<=”会对xml映射文件的合法性造成影响

      <select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">  

      select id

      from tableA a,

           tableB b

       <dynamic prepend="WHERE">

       <isNotNull prepend="AND" property="startDate">

        a.act_time >= #startDate# 

        and a.act_time <= #endDate#

        and a.id = b.id 

       </isNotNull>    

       </dynamic>  

      </select>

      错误例2:将整个sql语句用<![CDATA[   ]]>标记来避免冲突,在一般情况下都是可行的,但是由于该sql配置中有动态语句(where部分),将导致系统无法识别动态判断部分,导致整个sql语句非法。

      <select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">

      < ![CDATA[   

      select id

      from tableA a,

           tableB b

       <dynamic prepend="WHERE">

       <isNotNull prepend="AND" property="startDate">

        a.act_time >= #startDate# 

        and a.act_time <= #endDate#

        and a.id = b.id 

       </isNotNull>    

       </dynamic>  

        ]]>

      </select>

      正确做法:缩小范围,只对有字符冲突部分进行合法性调整。

      <select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">  

      select id

      from tableA a,

           tableB b

       <dynamic prepend="WHERE">

       <isNotNull prepend="AND" property="startDate">

        a.act_time >= #startDate# 

        < ![CDATA[ and a.act_time <= #endDate#  ]]>

        and a.id = b.id 

       </isNotNull>    

       </dynamic>  

      </select>

      ------------------------------------------------------------------

      ibatis中应该经常见到"<![CDATA["这样的东西吧,它的用处应该是转义一些特殊关键字字符,不合法的XML字符必须被替换为相应的实体。 下面是五个在XML文档中预定义好的实体:

      < &gt;  小于号
      > &lt;  大于号
      & &
      &apos; ' 单引号
      " " 双引号

      一个 CDATA 部件以"< ! [CDATA[" 标记开始,以"]]>"标记结束:

      <message>if salary < 1000 then</message>

      为了避免出现这种情况,必须将字符"<" 转换成实体,象下面这样:

      <message>if salary < 1000 then</message>

      这里有一个问题,由于我在ibatis中用到了一个循环标签"<iterate>" ,为了写一个  类似

      SELECT * FROM b 

      WHERE b.trade_no in
       <iterate property="tradeNoList" open="(" close=")" conjunction=",">#tradeNoList[]#</iterate>
         AND .........这样的一个语句。

      由于"<iterate"标签以 "<"开头,那么可能被"< ! [CDATA["转义了,所以造成语法错误,sql不能正常执行,去掉"<![CDATA["后发现sql能正常执行。

      所以在碰到类似问题的时候,应该留意,在"< ! [CDATA["转义符中间不要用标签。

  • 相关阅读:
    先创建项目 后版本化的步骤
    EditorLineEnds.ttr 错误问题
    TStringList 的Sorted属性
    Delphi out 参数 string Integer
    unity 调整摄像机视角完整脚本
    unity windowEditor平台下鼠标左键控制摄像机的视角
    C# 哈希表HashTable的简单使用
    唯一分解定理
    费马小定理的证明
    树状数组--求逆序对个数
  • 原文地址:https://www.cnblogs.com/hero4china/p/ibatis-list.html
Copyright © 2011-2022 走看看