小结一下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["转义符中间不要用标签。

ibatis传入数组或List的更多相关文章

  1. 异步控制---实现函数asyncAll,在执行完传入数组中func1,func2,func3异步函数后,输出“end”

    实现函数asyncAll,在执行完传入数组中func1,func2,func3异步函数后,输出"end" function func1(callback) { setTimeout ...

  2. SQL 存储过程 传入数组参数

    今天在做统计数据的时候,传入数组导致数据不显示.解决方式和大家分享一下: --参数@CompanyName='北京,天津,上海' DECLARE @PointerPrev int     DECLAR ...

  3. Java中将一个字符串传入数组的几种方法

    String Str="abnckdjgdag"; char a[]=new char[Str.length()]; -------------------方法1 用于取出字符串的 ...

  4. c 函数传入数组。

    php 里面 直接 count($arr); 一个函数搞定, c里面想判断下数组的个数却非常困难. 想到php是C写的,那看看他的函数怎么写的不就行了... 哦,天啊,,事实比我想的要复杂的多... ...

  5. 题目要求:传入数组 内容为[['lisi','男','27'],['wangwu','男',18],['zhaoliu','男','30']],将此二维数组转化为一维数组,创建自定义函数完成

    //自定义函数 function getOne($arr){ $str = ''; //定义空的字符串,用来接收值 foreach ($arr as $key=>$value){ //循环遍历数 ...

  6. ibatis遍历数组:ParameterObject or property was not a Collection, Array or Iterator.

    这个问题在使用ibatis的<iterate></iterate>时出现的,很简单,但是蛋疼了很久,记下来 首先从错误提示看,明显意思是你给出ibatis的参数不对路,人家不认 ...

  7. ibatis传入list对象

    在使用ibatis的时候经常需要传入list对象,sql语句如下. <select id="GET-PERSONS" parameterClass="java.ut ...

  8. 一行代码解决 sql语句 in传入数组变字符串

    --数组 var arrs= ['test1','test2','test3'];--变字符串 var instring = "'"+arrs.join("','&quo ...

  9. 向Oracle中传入数组,批量执行SQL语句

    1.首先用PL/SQL创建package create or replace package excuteBatchOperate as type sqlStr_Array ) index by bi ...

随机推荐

  1. [Unity2D]Box Collider 2D盒子碰撞器

    盒子碰撞器(BoxCollider2D)是Unity2D中常用的碰撞器,所有为碰撞器,顾名思义,就是用于检测物体之间的碰撞情况的,Unity2D里面除了BoxCollider2D碰撞器之外还集成Box ...

  2. 开学后,板刷usaco!

    我要开权限我要开权限我要开权限我要开权限我要开权限我要开权限我要开权限我要开权限 他们刷rank的太可恶了 没有usaco银组金组分类的oj太可恶了 没有usaco翻译的太可恶了 没有usaco数据的 ...

  3. C#中使用JQueryUI中Autocomplete插件

    服务器端后台代码: 1 private string GetModelNames() { 2 return @"[ 3 { 4 'value': 'jquery', 5 'label': ' ...

  4. 利用Oracle的row_number() over函数消除重复的记录

    .select d.id,d.outer_code from dict_depts_source d order by outer_code(查看重复数据) .select d.id,d.outer_ ...

  5. 如何使用数据库保存session的方法简介

    使用数据库保存session的方法 php的session默认是以文件方式保存在服务器端,并且在客户端使用cookie保存变量,这就会出现一个问题,当一个用户由于某种安全原因关闭了浏览器的cookie ...

  6. 从个人的角度谈谈本次GNTC大会的收获

    GNTC资料:from sdnlab 从个人的角度谈谈本次大会的收获 从本次大会的主题演讲来看,目前SDN.NFV的最前沿已经不再像五年前持观望态度以及探讨,各大运营商.各大厂商已经将SDN.NFV具 ...

  7. DS实验题 Floyd最短路径 & Prim最小生成树

    题目: 提示: Floyd最短路径算法实现(未测试): // // main.cpp // Alg_Floyd_playgame // // Created by wasdns on 16/11/19 ...

  8. Unknown collation: 'utf8mb4_unicode_ci'

    日前给一个政府机关做个小的门户网站,用的是wordpress+主题开发,部署时发现导入数据库sql文本时出现Unknown collation: 'utf8mb4_unicode_ci'的错误,查了下 ...

  9. 4.PHP内核探索:单进程SAPI生命周期

    CLI/CGI模式的PHP属于单进程的SAPI模式.这类的请求在处理一次请求后就关闭.也就是只会经过如下几个环节: 开始 - 请求开始 - 请求关闭 - 结束 SAPI接口实现就完成了其生命周期. 单 ...

  10. push to deploy

    1.server端 建立裸仓 $ mkdir ~/repo.git $ cd ~/repo.git $ git init --bare 脚本 $ vim ~/repo.git/hooks/post-r ...