ibatis中輸入/輸出各種類型的參數分析及#與$區別 (轉)

(1)
在數據庫持久層的框架中,大家一定聽過Hibernate的大名了吧,經典的SSH框架就有它的一份哦!可是我今天要說的卻是另外一個持久層的框架,它就是iBatis。與Hibrenate相比,它的主要優勢就是簡單、小巧、輕量級,但是它的功能卻絲毫不亞於 Hibernate,下面讓我們來看看iBatis在項目中的應用吧!
iBatis確實很簡單,它的工作原理就是通過SQL Map映射文件將sql語句和java對象對應起來(如:在利用對象屬性的getter從屬性中獲取值,查詢結果後,將各值用setter方法放到對象中).在iBatis中,sql語句是我們手工編寫好的,這一點與Hibernate不同,Hibernate是通過映射java對象和數據庫表字段來自動生成的sql語句。
 
(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. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章