iBATIS SQL Maps(三)

看看 iBATIS SQL Maps 是怎樣從數據庫按照 one-to-many 關係查詢數據的:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap
    PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "
http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap>
    <resultMap id="get-autoInfo-result" class="bo.AutoInfo">
        <result property="id" column="auto_id"/>
        <result property="licensePlate" column="license_plate"/>
    </resultMap>

    <resultMap id="get-people-result" class="bo.People">
        <result property="id" column="owner_id"/>
        <result property="name" column="name"/>
        <result property="address" column="address"/>
        <result property="autoInfoList" column="owner_id" select="getAutoInfo"/>
    </resultMap>

  <select id="getPeople" resultMap="get-people-result" parameterClass="bo.People">
       <![CDATA[
       select * from people where owner_id=#id#
        ]]>
  </select>

  <select id="getAutoInfo" resultMap="get-autoInfo-result" parameterClass="int">
       <![CDATA[
       select * from auto_info where owner_no=#id#
        ]]>
  </select>
</sqlMap>

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap
    PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "
http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap>
    <resultMap id="get-autoInfo-result" class="bo.AutoInfo">
        <result property="id" column="auto_id"/>
        <result property="licensePlate" column="license_plate"/>
    </resultMap>

    <resultMap id="get-people-result" class="bo.People">
        <result property="id" column="owner_id"/>
        <result property="name" column="name"/>
        <result property="address" column="address"/>
        <result property="autoInfoList" column="owner_id" select="getAutoInfo"/>
    </resultMap>

  <select id="getPeople" resultMap="get-people-result" parameterClass="bo.People">
       <![CDATA[
       select * from people where owner_id=#id#
        ]]>
  </select>

  <select id="getAutoInfo" resultMap="get-autoInfo-result" parameterClass="int">
       <![CDATA[
       select * from auto_info where owner_no=#id#
        ]]>
  </select>
</sqlMap>

 

resultMap id="get-autoInfo-result" class="bo.AutoInfo"

    resultMap iBATIS SQL Maps 框架中重要組件之一,你也許還記得 resultClass 吧?兩者概念基本一致。resultMap 則是可定製 Mapped Statement 返回對象的。可定製表現在:比如我有一張數據表包含10個字段,但我的 POJO 只定義了5個屬性,這時,只要取出我關心的字段就行。和 Hibernate 類似,resultMap result 元素定義了 POJO 屬性到數據表字段的映射。

需要說明的是 result 元素 select 屬性,該屬性類似於加載了一個子查詢,並自動載入,如果這個子查詢包含多條結果,就自動把結果裝載進 List 類型。該 result 元素對應 People 中的屬性爲autoInfoList”,而由 Hibernate 生成的 People 卻是 Set 類型autoInfoSet”,這兩種類型無法直接互轉,所以我修改了 POJO 屬性。

select id="getPeople" resultMap="get-people-result" parameterClass="bo.People"

此爲 select 類型 Mapped Statement。傳入 People 實例,返回爲自己定製、包含autoInfoList” People 實例。傳入People 類型參數是爲了便於多字段匹配查詢,今天也許我只需利用 People.id 單字段匹配就能得到結果,但下次的新需求也許是 People.address People.name 聯合匹配!

相應程序代碼:

package test;

import java.io.Reader;
import java.util.List;

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

import bo.*;

public class AutoMag {

 private Reader reader;
 private People people=new People();
 private SqlMapClient sqlMap;
 private String resource = "SqlMapConfig.xml";
 
 public People findPeople() throws Exception{
  reader = Resources.getResourceAsReader(resource);
   sqlMap=SqlMapClientBuilder.buildSqlMapClient(reader);
  
   people.setId(new Integer("1"));
   people=(People)sqlMap.queryForObject("getPeople",people);
   return people;
 }
}

 

package test;

import java.io.Reader;
import java.util.List;

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

import bo.*;

public class AutoMag {

 private Reader reader;
 private People people=new People();
 private SqlMapClient sqlMap;
 private String resource = "SqlMapConfig.xml";
 
 public People findPeople() throws Exception{
  reader = Resources.getResourceAsReader(resource);
   sqlMap=SqlMapClientBuilder.buildSqlMapClient(reader);
  
   people.setId(new Integer("1"));
   people=(People)sqlMap.queryForObject("getPeople",people);
   return people;
 }
}

 

sqlMap.queryForObject(String arg0, Object arg1)

此方法類似 Hibernate session.load(…),傳入 Mapped Statement id,再傳入包含主鍵的對象實例。除我上面列舉的 sqlMap.queryForObject(String arg0, Object arg1) 外,還有重載方法

people=(People)sqlMap.queryForObject("getPeople",people);

替換成

sqlMap.queryForObject("getPeople", people, people);

 

people=(People)sqlMap.queryForObject("getPeople",people);

替換成

sqlMap.queryForObject("getPeople", people, people);

 

第一個people是傳入參數,第二個people是返回的結果。要表達的意思一樣,只不過換了種表現形式

下面我會講到如何以集合類持有多個 People 對象實例。

在車輛管理應用中,需要把人員一一列出,選中某個再顯示詳細內容。類似於這樣的需求,iBATIS SQL Maps 引入 sqlMap.queryForList(String arg0, Object arg1) 來滿足。

      還記得我們的映射文件怎麼寫的?對了,傳入主鍵值再查詢!

但是,新需求不要任何條件,直接列出人員啊!難道還要再添加新的 Mapped Statement 來滿足?動態 Mapped Statement 能滿足在不改變映射文件的前提下提供有參數和無差數查詢:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap
    PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "
http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap>
    <resultMap id="get-autoInfo-result" class="bo.AutoInfo">
        <result property="id" column="auto_id"/>
        <result property="licensePlate" column="license_plate"/>
    </resultMap>

    <resultMap id="get-people-result" class="bo.People">
        <result property="id" column="owner_id"/>
        <result property="name" column="name"/>
        <result property="address" column="address"/>
        <result property="autoInfoList" column="owner_id" select="getAutoInfo"/>
    </resultMap>

  <select id="getPeople" resultMap="get-people-result" parameterClass="bo.People">
       <![CDATA[
       select * from people
       ]]>
       <dynamic prepend="where">
         <isNotNull property="id">
           <![CDATA[
           owner_id=#id#
           ]]>
         </isNotNull>
       </dynamic>
  </select>

  <select id="getAutoInfo" resultMap="get-autoInfo-result" parameterClass="int"
                    resultClass="bo.AutoInfo">
       <![CDATA[
       select * from auto_info where owner_no=#id#
        ]]>
  </select>
</sqlMap>

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap
    PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "
http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap>
    <resultMap id="get-autoInfo-result" class="bo.AutoInfo">
        <result property="id" column="auto_id"/>
        <result property="licensePlate" column="license_plate"/>
    </resultMap>

    <resultMap id="get-people-result" class="bo.People">
        <result property="id" column="owner_id"/>
        <result property="name" column="name"/>
        <result property="address" column="address"/>
        <result property="autoInfoList" column="owner_id" select="getAutoInfo"/>
    </resultMap>

  <select id="getPeople" resultMap="get-people-result" parameterClass="bo.People">
       <![CDATA[
       select * from people
       ]]>
       <dynamic prepend="where">
         <isNotNull property="id">
           <![CDATA[
           owner_id=#id#
           ]]>
         </isNotNull>
       </dynamic>
  </select>

  <select id="getAutoInfo" resultMap="get-autoInfo-result" parameterClass="int"
                    resultClass="bo.AutoInfo">
       <![CDATA[
       select * from auto_info where owner_no=#id#
        ]]>
  </select>
</sqlMap>

 

dynamic prepend="where"

select 類型 Mapped Statement 的本質並無改變,只是通過 dynamic 元素定義了動態 where 子句。dynamic 元素屬性 prepend=”where”在一元判定元素 isNotNull 返回”true”時有效。isNotNull 元素屬性 property="id" 用於判定 People.id 是否爲 null,假如未傳入包含主鍵值的 People 實例,dynamic 元素將會無效,反之則亦然,這樣就達到了在不改變映射文件的前提下實現動態 SQL 的目的。關於一元判定元素和二元判定元素的詳細資料請查閱官方文檔,如能恰當利用這些判定元素,動態 SQL 將會更靈活。

相應程序代碼:

package test;

import java.io.Reader;
import java.util.List;

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

import bo.*;

public class AutoMag {

 private Reader reader;
 private People people=new People();
 private SqlMapClient sqlMap;
 private String resource = "SqlMapConfig.xml";
 
 public List findPeople() throws Exception{
  reader = Resources.getResourceAsReader(resource);
  sqlMap=SqlMapClientBuilder.buildSqlMapClient(reader);
     
  List list=sqlMap.queryForList("getPeople",null);
  return list;
 }
}

 

package test;

import java.io.Reader;
import java.util.List;

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

import bo.*;

public class AutoMag {

 private Reader reader;
 private People people=new People();
 private SqlMapClient sqlMap;
 private String resource = "SqlMapConfig.xml";
 
 public List findPeople() throws Exception{
  reader = Resources.getResourceAsReader(resource);
  sqlMap=SqlMapClientBuilder.buildSqlMapClient(reader);
     
  List list=sqlMap.queryForList("getPeople",null);
  return list;
 }
}

 

傳入 Mapped Statement id,再傳入未包含主鍵的對象實例,也可以乾脆傳 null 進去。重載方法 sqlMap.queryForList(String arg0, Object arg1, int arg2, int arg3) 用於分頁arg2arg3分別代表頁碼和每頁個數。

好了,使用動態 Mapped Statement,再試試 queryForObject(String arg0, Object arg1) 吧!

   

(請注意!引用、轉貼本文應註明原作者:Rosen Jiang 以及出處:http://blog.csdn.net/rosen

   

(請注意!引用、轉貼本文應註明原作者:Rosen Jiang 以及出處:http://blog.csdn.net/rosen

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章