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

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

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

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

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

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

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

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

1、iterate property的问题

网上很多写法是:

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

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

  1. 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'

解决方法,就是缩小 CDATA的范围。原因是CDATA导致系统无法识别动态判断部分。

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

环境:oracle、ibatis、java

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

  1. <select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">
  2.  
  3. select id
  4.  
  5. from tableA a,
  6.  
  7. tableB b
  8.  
  9. <dynamic prepend="WHERE">
  10.  
  11. <isNotNull prepend="AND" property="startDate">
  12.  
  13. a.act_time >= #startDate#
  14.  
  15. and a.act_time <= #endDate#
  16.  
  17. and a.id = b.id
  18.  
  19. </isNotNull>
  20.  
  21. </dynamic>
  22.  
  23. </select>

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

  1. <select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">
  2.  
  3. < ![CDATA[
  4.  
  5. select id
  6.  
  7. from tableA a,
  8.  
  9. tableB b
  10.  
  11. <dynamic prepend="WHERE">
  12.  
  13. <isNotNull prepend="AND" property="startDate">
  14.  
  15. a.act_time >= #startDate#
  16.  
  17. and a.act_time <= #endDate#
  18.  
  19. and a.id = b.id
  20.  
  21. </isNotNull>
  22.  
  23. </dynamic>
  24.  
  25. ]]>
  26.  
  27. </select>

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

  1. <select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">
  2.  
  3. select id
  4.  
  5. from tableA a,
  6.  
  7. tableB b
  8.  
  9. <dynamic prepend="WHERE">
  10.  
  11. <isNotNull prepend="AND" property="startDate">
  12.  
  13. a.act_time >= #startDate#
  14.  
  15. < ![CDATA[ and a.act_time <= #endDate# ]]>
  16.  
  17. and a.id = b.id
  18.  
  19. </isNotNull>
  20.  
  21. </dynamic>
  22.  
  23. </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. es修改数据

    # 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html#bulk-routing * ...

  2. MySQL 查询语句练习2

    创建表 /* Navicat MySQL Data Transfer Source Server : localhost_3306 Source Server Version : 50719 Sour ...

  3. C++11 lambda函数符

    #include<iostream> #include<vector> #include<algorithm> #include<cmath> #inc ...

  4. appium===Python+Appium环境部署教程

    *前提是你已经安装好python,以及python的pip工具 *安装python请自行百度教程~ 1.安装安卓sdk 安装包:http://tools.android-studio.org/inde ...

  5. Python学习笔记 chapter 2基础

    程序输入 >>> print('%s is number %d'%('Python', 1))Python is number 1 输出重定向有问题(待定) 文本输入>> ...

  6. JSP(1) - JSP简介、原理、语法 - 小易Java笔记

    1.JSP简介 (1)JSP的全称是Java Server Pages(运行在服务器端的页面),实际就是Servlet(学习JSP的关键就是时刻联想到Servlet) (2)JSP.Servlet各自 ...

  7. 【 Linux 】为lnmp架构添加memcached支持

    一.首先搭建lnmp平台,这里不再演示.通过php页面来进行测试如下: [root@node1 ~]# vim /usr/local/nginx/html/info.php <?php $lin ...

  8. BAT 前端开发面经 —— 吐血总结

    更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘,在此总结一下 一是备忘.总结提升,二是希望给大家一些参考 其他面试及基础相关可以参考其他博文: ...

  9. 【python】抄写大神的百度贴吧代码

    原文链接:http://cuiqingcai.com/993.html 划重点: 1.提取帖子内容时,对图片,贴吧自动增加的超链接,制表符,换行符要做删除或替换处理 2.decode是把bytes转换 ...

  10. 【C++】继承时构造函数和析构函数

    1. 顺序 先调用基类的构造函数,再调用派生类构造函数.析构顺序相反. 2. 构造函数 派生类 不用初始化列表调用基类构造函数->调用基类的默认构造函数 派生类 使用初始化列表调用基类带参构造函 ...