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 ...
随机推荐
- WebRTC手记Channel概念
转载请注明出处:http://www.cnblogs.com/fangkm/p/4401075.html 前面两篇博文完整地介绍了WebRTC音视频的采集模块,接下来应该开始介绍关键的音视频编码模块. ...
- Dynamic LINQ OrderBy
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string pr ...
- [转载] c++ cout 格式化输出浮点数、整数及格方法
C语言里可以用printf(),%f来实现浮点数的格式化输出,用cout呢...? 下面的方法是在网上找到的,如果各位有别的办法谢谢留下... iomanip.h是I/O流控制头文件,就像C里面的格式 ...
- ASP中可能出现的一种包含漏洞(Server.execute)
author: bin <% Server.execute(request(“file”)) %> 与include的区别,它可以动态包含文件. 被包含文件里面可执行ASP代码,在国外的源 ...
- 三层交换单臂路由vlan间通信综合实验之降龙要点--Lee
单臂路由三层交换机提供vlan间的通信之菜鸟之降龙详解要点: 图示 PC:左到右依次设置IP172.16.10.1, 20.1, 30.1, 40,1 ,50,1 /24 网关10.2 ...
- Solr定时更新
今天用到solr定时重建索引和增量更新技术,就从网上搜了一些资料,在这里给大家整理了一下,也经过了自己的测试,没有异常. Solr官方提供了很强大的Data Import Request Handle ...
- mysql之触发器trigger 详解
为了梦想,努力奋斗! 追求卓越,成功就会在不经意间追上你 mysql之触发器trigger 触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) ...
- Universal Serial Bus USB 3.0
Computer Systems A Programmer's Perspective Second Edition A Universal Serial Bus (USB) controller i ...
- 在Delphi下基于MapWinGIS添加和删除图层标注的方法
unit Form_MainU; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, ...
- Delphi Application.MessageBox详解
引数:1. Text:要显示的讯息2. Caption:讯息视窗的标题列文字3. Flags:讯息旗标 3.1. 可指定讯息视窗上的图示 3.2. 可指定讯息视窗出现的按钮 3 ...