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

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

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

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

 "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[]#

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

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

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

1、iterate property的问题

网上很多写法是:

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文档中预定义好的实体:

< &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作为传入参数的使用方法及 CDATA使用的更多相关文章

  1. 关于Mybatis中mapper.xml的传入参数简单技巧

    由于在做项目的时候,我看见同事使用的传入参数类型各式各样,感觉没规律可言,闲暇的时候我就自己搭建了项目做了一些传入参数的测试(当然其实更好的方式是看源码,但是博主能力有限,毕竟入行没多久,看起来很吃力 ...

  2. 如何给ioloop.run_sync()中调用的函数传入参数

    问题 如何给tornado.ioloop.IOLoop中的run_sync方法中调用的函数添加参数 解决方案 使用functools.partial 解决示例 from tornado import ...

  3. @Param注解在mybatis中的使用以及传入参数的几种方式(转)

    第一种: Dao层的方法 <span style="font-size:12px;">Public User selectUser(String name,String ...

  4. [AX2012]在SSRS报表中获取从Menuitem传入的记录

    在较早版本的AX中我们运行一个报表时会用到类RunBaseReport,从它扩展一个子类,再由它运行报表,一个典型的Axapta3中的例子: class ReportProdInfo extends ...

  5. 动态sql语句和动态传入参数个数

    1.可以将要传入的几个参数封装成一个实体类,然后将实体类作为一个参数传入到相应的方法中,这时候就需要这sqlMapper.xml文件中对传入的字段利用<if test=""& ...

  6. ibatis中in语句参数传入方法

    第一种:传入参数仅有数组,iterate中不能有数组的属性名       <select id="GetEmailList_Test"  resultClass=" ...

  7. (转载)mybatis中传入参数是list或map

    原文地址:http://blog.csdn.net/aya19880214/article/details/41961235 foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集 ...

  8. mysql存储过程或函数中传入参数与表字段名相同引发的悲剧

    真实案例.如下的一个存储过程: create procedure Apple(in user_id int) begin delete from users where user_id = user_ ...

  9. MyBatis中传入参数parameterType类型详解

    前言 Mybatis的Mapper文件中的select.insert.update.delete元素中有一个parameterType属性,用于对应的mapper接口方法接受的参数类型.本文主要给大家 ...

随机推荐

  1. Python学习笔记 使用数据库SQlite Mysql

    SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用当中, 甚至在IOS和Android的APP中都可以集成 Python就内 ...

  2. linux 中解析命令行参数(getopt_long用法)

    linux 中解析命令行参数(getopt_long用法) http://www.educity.cn/linux/518242.html 详细解析命令行的getopt_long()函数 http:/ ...

  3. cookie和session的区别与会话跟踪技术

    会话跟踪技术: HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的.非连续的.当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟 ...

  4. Oracle基础 12 对象 objects 同义词/序列/试图/索引

    --创建同义词create public synonym employees for hr.employees;  --公共同义词需要 create public synonym 权限 表的所有用户授 ...

  5. web页面的点对点复制粘贴

    js-code如下: //复制抵押人信息 function copyDYR(obj){ var customerType_paste=$(obj).parent().find("[name$ ...

  6. background-clip,origin属性

    background-clip是新增属性之一,其作用是确定背景的裁剪区域. background-clip语法: background-clip:margin-box | padding-box | ...

  7. 用IJ和gradle启动elasticsearch5.4.3

    环境准备 jdk gradle3.3+ idea git 从git clone源码 git checkout v5.4.3 打开项目 1. 在edit configurations添加new conf ...

  8. request.getServletContext()的问题!

    ServletRequest的getServletContext方法是Servlet3.0添加的,这个可以看一下官方文档 http://docs.oracle.com/javaee/6/api/jav ...

  9. PostgreSQL教程

    https://www.yiibai.com/postgresql/ https://blog.csdn.net/zhangzeyuaaa/article/details/77941039

  10. 使用navicat修改Mysql默认密码

    本质就是修改数据库mysql里面的数据表user一个字段,并执行如下一句mysql语句: UPDATE user SET password=PASSWORD('密码') WHERE user='roo ...