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的问题
网上很多写法是
- "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如果写成
- <select id="getProjectJobIdsByProjectIds" resultClass="java.lang.Integer"
- parameterClass="java.util.ArrayList">
- <![CDATA[
- SELECT id
- FROM cic_job
- WHERE last_buildid <> 'NULL'
- <iterate prepend="AND" open="(" close=")" conjunction="or">
- CRID=#projectIdList[]#
- </iterate>
- ]]>
- </select>
即扩大转义范围会出现如下错误
- com.ibatis.common.beans.ProbeException: There is no READABLE property named 'projectIdList[]' in class 'java.util.ArrayList'
解决方法,就是缩小 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文档中预定义好的实体:
< > 小于号 > < 大于号 & & 和 ' ' 单引号 " " 双引号 一个 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的更多相关文章
- 异步控制---实现函数asyncAll,在执行完传入数组中func1,func2,func3异步函数后,输出“end”
实现函数asyncAll,在执行完传入数组中func1,func2,func3异步函数后,输出"end" function func1(callback) { setTimeout ...
- SQL 存储过程 传入数组参数
今天在做统计数据的时候,传入数组导致数据不显示.解决方式和大家分享一下: --参数@CompanyName='北京,天津,上海' DECLARE @PointerPrev int DECLAR ...
- Java中将一个字符串传入数组的几种方法
String Str="abnckdjgdag"; char a[]=new char[Str.length()]; -------------------方法1 用于取出字符串的 ...
- c 函数传入数组。
php 里面 直接 count($arr); 一个函数搞定, c里面想判断下数组的个数却非常困难. 想到php是C写的,那看看他的函数怎么写的不就行了... 哦,天啊,,事实比我想的要复杂的多... ...
- 题目要求:传入数组 内容为[['lisi','男','27'],['wangwu','男',18],['zhaoliu','男','30']],将此二维数组转化为一维数组,创建自定义函数完成
//自定义函数 function getOne($arr){ $str = ''; //定义空的字符串,用来接收值 foreach ($arr as $key=>$value){ //循环遍历数 ...
- ibatis遍历数组:ParameterObject or property was not a Collection, Array or Iterator.
这个问题在使用ibatis的<iterate></iterate>时出现的,很简单,但是蛋疼了很久,记下来 首先从错误提示看,明显意思是你给出ibatis的参数不对路,人家不认 ...
- ibatis传入list对象
在使用ibatis的时候经常需要传入list对象,sql语句如下. <select id="GET-PERSONS" parameterClass="java.ut ...
- 一行代码解决 sql语句 in传入数组变字符串
--数组 var arrs= ['test1','test2','test3'];--变字符串 var instring = "'"+arrs.join("','&quo ...
- 向Oracle中传入数组,批量执行SQL语句
1.首先用PL/SQL创建package create or replace package excuteBatchOperate as type sqlStr_Array ) index by bi ...
随机推荐
- 【BZOJ】1076: [SCOI2008]奖励关(状压dp+数学期望)
http://www.lydsy.com/JudgeOnline/problem.php?id=1076 有时候人蠢还真是蠢.一开始我看不懂期望啊..白书上其实讲得很详细的,什么全概率,全期望(这个压 ...
- 【wikioi】1217 借教室
题目链接http://www.wikioi.com/problem/1217/ 算法:二分答案(线段树可过wikioi数据) 二分:http://www.wikioi.com/solution/lis ...
- 像jQuery那样,采用链式方法,封装一个方法:CSS()
主要思路就是:返回this对象,将所获取的操作元素放入一个数组中.在原型中添加拓展方法 <html> <head> <title></title> &l ...
- IOS第五天(2:用户登录,回车的监听(代理模式UITextFieldDelegate)) 和关闭键盘
*********用户登录,回车的监听(代理模式UITextFieldDelegate) #import "HMViewController.h" @interface HMVie ...
- 《GK101任意波发生器》升级固件发布(版本:1.0.2build539)
一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build539 编译日期:2014-10-08 ====================================== 二. ...
- 《GK101任意波形发生器》任意波文件格式说明
详见PDF 文档: http://files.cnblogs.com/xiaomagee/GK101%E4%BB%BB%E6%84%8F%E6%B3%A2%E6%95%B0%E6%8D%AE%E6%A ...
- alpha发布用户数
小组名称:天天向上 小组成员:张政.张金生.林莉.胡丽娜 项目内容:连连看 在连连看alpha发布的24小时内,我们将连连看安装包放入各个组员所加入的QQ群内,推荐朋友试玩,用户数达到9人. 现在有A ...
- 课堂Scrum站立会议演示
组名:连连看 组长:张政 组员:张金生.李权.武志远 时间:2016.10.13 20:20--20:40 会议内容: 已完成的内容: 1.选定编译语言,安装软件并配置环境,完成了游戏的基本模型. ...
- 省略nslog打印
//#if #endif宏定义的意思就是如果定义了DEBUG,那么就使用NSLog输出:否则这段代码直接忽略.有人会疑问这个DEBUG和_DEBUG来自哪里,这个其实不用担心,这个来自于Xcode的默 ...
- Web交互设计优化的简易check list
Web交互设计优化的简易check list 00 | 时间: 2011-02-11 | 28,842 Views 交互设计, 用户研究 “优化已有产品的体验”,这是用户体验相关岗位职责中常见的描 ...