当前位置: 代码迷 >> Web前端 >> ibatis中输入/输出各种类型的参数分析及#与$差异
  详细解决方案

ibatis中输入/输出各种类型的参数分析及#与$差异

热度:813   发布时间:2013-01-28 11:49:56.0
ibatis中输入/输出各种类型的参数分析及#与$区别
(1) 
在数据库持久层的框架中,大家一定听过Hibernate的大名了吧,经典的SSH框架就有它的一份哦!可是我今天要说的却是另外一个持久层的框架,它就是iBatis。与Hibrenate相比,它的主要优势就是简单、小巧、轻量级,但是它的功能却丝毫不亚于 Hibernate,下面让我们来看看iBatis在项目中的应用吧! 
iBatis确实很简单,它的工作原理就是通过SQL Map映射文件将sql语句和java对象对应起来(如:在利用对象属性的getter从属性中获取值,查询结果后,将各值用setter方法放到对象中).在iBatis中,sql语句是我们手工编写好的,这一点与Hibernate不同,Hibernate是通过映射java对象和数据库表字段来自动生成的sql语句。 
 原文参考自站长网http://www.software8.co/wzjs/java/2614.html
(2) 
ibatis中的namespace与resultMap 
<sqlMap namespace="admin">在运用时如下: 
this.getSqlMapClient().update(“admin.update”, entity); 
 
分析: 
ibatis 配置文件中的useStatementNamespaces:是否使用Statement命名空间。这里的命名空间指的是映射文件中,sqlMap节点的 namespace属性,如:<sqlMap namespace="User">。这里,指定了此sqlMap节点下定义的操作均从属于"User"命名空间。 
在 useStatementNamespaces="true"的情况下,Statement调用需追加命名空间,如:sqlMap.update("User.updateUser",user);否则直接通过Statement名称调用即可,如:sqlMap.update("updateUser",user); 
好处: 
在实际应用中,利用namespace可以防止两个同名的方法而引起冲突。如有两个updateUser,可以通过A updateUser/B. updateUser来区分。 
另一种方法: 
但有一种更方便的方法,可以在不采用namspace的情况下,解决上面的问题:即直接在方法的前面直接命名为A updateUser/B. updateUser。调用时,直接调用A updateUser/B. updateUser即可。如下: 
<sqlMap> 
       <typeAlias type="com.admin.entity.Admin" alias="Admin" /> 
 
       <select id="Admin.findUserByLoginName" parameterClass="java.lang.String" 
              resultMap="AdminResult"> 
              select * from T_ADMINISTRATORS where longinName = #value# 
              and status != 4 
       </select> 
调用时,getSqlMapClientTemplate.queryForList(“Admin.findUserByLoginName”,”test”);即可。 
 
请注意: 
此时需要保证所有映射文件中,Statement定义无重名。 
 
第二: 
resultMap:结果映射,需结合resultMap节点对映射关系加以定义。 
<sqlMap> 
       <typeAlias type="com.admin.entity.Admin" alias="Admin" /> 
       <resultMap id="AdminResult" class="Admin"> 
              <result column="staff_id" property="id" /> 
              <result column="loginName" property="loginName" /> 
              <result column="password" property="password" /> 
              <result column="staff_name" property="username" /> 
              <result column="status" property="status" /> 
              <result column="phone" property="phone" /> 
              <result column="email" property="email" /> 
       </resultMap> 
 
       <select id="Admin.findUserByLoginName" parameterClass="java.lang.String" 
              resultMap="AdminResult"> 
              select * from T_ADMINISTRATORS where longinName = #value# 
              and status != 4 
       </select> 
</sqlMap> 
 
(3)关于ibatis中输入/输出各种类型的参数分析 
在ibatis,输入的参数对象常以parameterClass来定义,输出的结果集常以resultMap来定义。(resultMap: 方便JAVABEAN属性及字段的映射,调用JAVABEAN的setter进行设置值。通常我们不采用resultClass属性进行映射,因为它不具备映射数据库表字段的持久化特性。) 
 
在ibateis中,parameterClass的类型大都是:string,int/对象/hashmap 
                        resultclass/resultMap的类型大都是:对象/hashmap 
当parameterClass为string,int时,可用#value#表示或直接用传入的值名表示。 
当parameterClass/resultMap的类型是对象时,用#属性#表示。程序会调用JAVABEAN的getter方法,进行获取属性值。 
当parameterClass/resultMap的类型是hashmap(Map是key-value结构的)时,那程序会直接通过key来分析取参数。 
 
具体请见以下两部分: 
ibatis各种参数数据集 
原型参数 
<select id="select1" parameterClass="java.lang.String" resultClass="AppLog"> 
    select 
      ID as id, 
      TYPE as type, 
      DESCR as descr 
    from APP_LOG 
    where ID = #id# 
</select> 
sqlMapper.queryForObject("select0", id); 
--参数名与传入值名称一样。--应该也可用参数#value#表示 
 
Map类参数 
<select id="select2" parameterClass="java.util.HashMap" resultClass="AppLog"> 
    select 
      ID as id, 
      TYPE as type, 
      DESCR as descr 
    from APP_LOG 
    where ID = #ids# 
</select>      
map.put("ids", id); 
AppLog log = (AppLog) sqlMapper.queryForObject("select0", map); 
--通过key来获取值 
 
对象参数 
   <select id="select3" parameterClass="AppLog" resultClass="AppLog"> 
    select 
      ID as id, 
      TYPE as type, 
      DESCR as descr 
    from APP_LOG 
    where ID = #id# 
</select> 
AppLog p=new AppLog(); 
p.setId(id); 
AppLog log = (AppLog) sqlMapper.queryForObject("select3", p); 
 
动态字段、表 
<select id="selectd" resultClass="java.util.HashMap" parameterClass="java.util.HashMap" 
remapResults="true"> 
    select $fieldList$      
    from $table$ 
    where ID = #id# 
</select> 
Map p = new HashMap(); 
p.put("id", id); 
p.put("table","APP_LOG"); 
p.put("fieldList", "ID,TYPE,DESCR"); 
Map map = (Map) sqlMapper.queryForObject("selectd", p); 
String id1 = (String) map.get("ID"); 
String type = (String) map.get("TYPE"); 
String descr = (String) map.get("DESCR"); 
注意:#与$区别: 
1.#是把传入的数据当作字符串,如#field#传入的是id,则sql语句生成是这样,order by "id",这当然会报错.. 
2.$传入的数据直接生成在sql里,如#field#传入的是id,则sql语句生成是这样,order by id, 这就对了. 
$方式一般用于传入数据库对象.例如传入表名. 
#方式一般用于传入插入/更新的值或查询/删除的where条件 
 
ibatis各种返回数据集 
别名映射->实体类 + resultClass 
<select id=" selectAll" resultClass="AppLog"> 
    select 
      ID as id, 
      TYPE as type, 
      DESCR as descr 
    from APP_LOG 
    where ID = #id# 
</select> 
List list = sqlMapper.queryForList("selectAll"); 
for (int i = 0; i < list.size(); i ) { 
    AppLog log = (AppLog) list.get(i); 
   //add your code here; 
注意: 
为什么定义了resultClass="AppLog",而queryForList出来的是list? 
这里的resultClass="AppLog",是指查询出来的每条记录的格式是AppLog。 
当我们queryForList时,系统会将各条记录(即各个AppLog放到list中)传回给我们。当我们queryForObject时,就只传回一个AppLog。 
 
别名映射->Map类+resultClass --》把每条记录放于map中,字段名为key,值为value. 
<select id=" selectAll" resultClass="java.util.HashMap"> 
    select 
      ID as id, 
      TYPE as type, 
      DESCR as descr 
    from APP_LOG 
    where ID = #id# 
</select> 
List list = sqlMapper.queryForList("selectAll"); 
for (int i = 0; i < list.size(); i ) { 
    Map map = (Map) list.get(i); 
    String id = (String) map.get("id"); 
    String type = (String) map.get("type"); 
    String descr = (String) map.get("descr"); 
   //add your code here; 
无映射 
<select id="selectAll3" resultClass="java.util.HashMap"> 
    select * from APP_LOG 
</select> 
List list = sqlMapper.queryForList("selectAll3"); 
for (int i = 0; i < list.size(); i ) { 
    Map map = (Map) list.get(i); 
    String id = (String) map.get("ID"); 
    String type = (String) map.get("TYPE"); 
    String descr = (String) map.get("DESCR"); 
 
显式映射->实体类:resultMap 
<resultMap id="AppLogResult" class="AppLog"> 
    <result property="id" column="ID"/> 
    <result property="type" column="Type"/> 
    <result property="descr" column="DESCR"/>    
</resultMap> 
 
<select id="selectAll" resultMap="AppLogResult"> 
    select * from APP_LOG 
</select> 
List list = sqlMapper.queryForList("selectAll"); 
for (int i = 0; i < list.size(); i ) { 
    AppLog log = (AppLog) list.get(i); 
   //add your code here; 
 
显式映射->Map类:resultMap  --》把每条记录放于map中,字段名为key,值为value. 
    <resultMap id="map-result" class="java.util.HashMap"> 
       <result property="id" column="ID"/> 
    <result property="type" column="Type"/> 
    <result property="descr" column="DESCR"/> 
    </resultMap> 
 
<select id="selectAll2" resultMap="map-result"> 
    select * from APP_LOG 
</select> 
List list = sqlMapper.queryForList("selectAll2"); 
       for (int i = 0; i < list.size(); i ) { 
           Map map = (Map) list.get(i); 
           String id = (String) map.get("id"); 
           String type = (String) map.get("type"); 
           String descr = (String) map.get("descr");        
       } 
 
又如: 
map.put("appIds", Ids); 
executor.update("Device.OpenClientApp", map); 
下面的property属性及循环变量,都是对应map的key名。 
                 -----证明,ibatis对于hashmap,都是通过key来获取值的。所以,所有参数须用key来表示!!! 
如下: 
<update id="Device.OpenClientApp" parameterClass="java.util.HashMap"> 
        update T_Device_App_R_Info set Opr='1' where App_ID in 
        <iterate conjunction="," open="(" close=")" property="appIds"> 
            #appIds[]# 
        </iterate> 
</update> 
 
例子: 
<statement id=”statementName” parameterClass=” examples.domain.Product”> 
insert into PRODUCT values (#id#, #description#, #price#, #classify.id#) 
</statement> 
蓝色部分#classify.id#翻译过来实际是product.getClassify().getId(),classify是Product对象的一个子对象。 
(4)关于参数的三种设置方法 及 ParameterMap用法 
前提:有一个user的javabean. 
一,自动参数映射: 
<insert id="insertUser7" parameterClass="user"> 
   <![CDATA[ 
    INSERT INTO t_user ( ID, NAME, PASS )VALUES( #id#,#name#,#pass# ) 
   ]]> 
</insert> 
二,内联参数映射: 
<insert id="insertUser8" parameterClass="user"> 
   <![CDATA[ 
    INSERT INTO t_user ( ID, NAME, PASS ) VALUES( #id:INT#, #name:VARCHAR#, #pass:VARCHAR# ) 
   ]]> 
</insert> 
备注:  好像将属性对应的数据类型故意写错,程序也可正常执行,没报错. 
三,外联参数映射: 
以上二种方式都用paramClass,但此处用parameterMap. 
<parameterMap id="parameterMap" class="user"> 
   <parameter property="id" jdbcType="INTEGER" /> 
   <parameter property="name" jdbcType="VARCHAR" /> 
   <parameter property="pass" jdbcType="VARCHAR" /> 
</parameterMap> 
<insert id="insertUser9" parameterMap="parameterMap"> 
   <![CDATA[ 
    INSERT INTO t_user ( ID, NAME, PASS )VALUES( ?,?,? ) 
   ]]> 
</insert> 
若此处的对象不是javabean,而是一个hashMap.用法也一样,只是id,name,pass不是javabean的属性,而是hashMap的key. 
Xml代码  
1.String[] ids;  
2............         
3.map.put("devId", ids[0]);  
4.map.put("appId", ids[1]);  
5.   
6.<!-- 自动参数映射方式 -->      
7.  <insert id="DAPermit.addAppDevMapping" parameterClass="java.util.HashMap">  
8.    insert into T_Device_App_R_Info(Device_ID,App_ID,Opr) values (#devId#,#appId#,'2');  
9.  </insert>  
10.      
11.<!--      
12.内联方式:  
13.  <insert id="DAPermit.addAppDevMapping" parameterClass="java.util.HashMap">  
14.    insert into T_Device_App_R_Info(Device_ID,App_ID,Opr) values (#devId:varchar#,#appId:varchar#,'2');  
15.  </insert>  
16.  
17.外联方式:  
18.  <parameterMap    id="dapermitParams" class="java.util.HashMap">  
19.         <parameter property="devId" jdbcType="VARCHAR"/>  
20.         <parameter property="appId" jdbcType="VARCHAR"/>  
21.  </parameterMap>  
22.      
23.  <insert id="DAPermit.addAppDevMapping" parameterMap="dapermitParams">  
24.    insert into T_Device_App_R_Info(Device_ID,App_ID,Opr) values (?,?,'2');  
25.  </insert>  
26.-->  
四,利用parameterMap调用存储过程: 
Java代码:  
1.<!-- example 11: 存储过程 -->  
2.<resultMap id="returnResultMap" class="user">  
3.     <result property="id" column="ID" />  
4.</resultMap>  
5.<parameterMap id="paramUser" class="java.util.Map">  
6.     <parameter property="name" jdbcType="VARCHAR" javaType="string" mode="IN" />  
7.     <parameter property="pass" jdbcType="VARCHAR" javaType="string" mode="IN" />  
8.     <parameter property="id" jdbcType="INT" javaType="Integer" mode="INOUT" resultMap="returnResultMap" />  
9.</parameterMap>  
10.  
11.<procedure id="pro_insertUser11" parameterMap="paramUser" resultClass="int">  
12.     <![CDATA[  
13.        {call proc_userinsert(?,?,?)}  
14.     ]]>  
15.</procedure>  
16.然后在UserDaoTest.java中增加如下一个方法:  
17.public static void example11() throws Exception {  
18.     try {  
19.        Map map = new HashMap();  
20.        map.put("name", "procedure");  
21.        map.put("pass", "123456");  
22.        Integer returnValue = (Integer)sqlMapClient.insert("pro_insertUser11", map);  
23.        System.out.println(returnValue);  
24.     } catch (Exception e) {  
25.        e.printStackTrace();  
26.     }  
27.} 
28.
  相关解决方案