iBatis開發(fā)詳解(10)---操作DDL和映射繼承

2018-10-14 10:41 更新

   DDL作為SQL的一個子集,是專門用于數(shù)據(jù)定義的語言,也就是我們所說的對數(shù)據(jù)庫表/模式的操作。最為常見的就是修改表的結(jié)構(gòu),比如添加字段,修改字段類型,為字段改名等。那么我們來看看如何使用iBatis來進行DDL操作。 


    前面介紹的iBatis操作數(shù)據(jù)庫都屬于DML范疇,比如select,update,delete等。那么操作DDL我們使用的是statement標簽,我們來看看對我們之前示例的訂單項表來進行修改: 

<statement id="addColumn">  
    alter table orderitem add column type VARCHAR(50);  
</statement>  
  下面編寫程序來調(diào)用這個語句:
package ibatis;  
import java.io.IOException;  
import java.io.Reader;  
import com.ibatis.common.resources.Resources;  
import com.ibatis.sqlmap.client.SqlMapClient;  
import com.ibatis.sqlmap.client.SqlMapClientBuilder;  
public class DDLDemo {  
    private static String config = "ibatis/SqlMapConfig.xml";  
    private static Reader reader;  
    private static SqlMapClient sqlMap;  
    static {  
        try {  
            reader = Resources.getResourceAsReader(config);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);  
    }  
    public static void main(String[] args) throws Exception {  
        sqlMap.update("OrderItem.addColumn", null);  
    }  
}  
   我們使用SqlMapClient的update方法來調(diào)用statement語句,那么執(zhí)行完后,我們可以看到數(shù)據(jù)表被修改了。可能不同的數(shù)據(jù)庫并不支持這種方式的修改,但用MySQL 5.5來測試是成功的,我們得到了如下的數(shù)據(jù)庫表結(jié)構(gòu): 

    現(xiàn)在,我們?yōu)闉閠ype設置值,個人訂單為indi,團體訂單為group,然后我們來介紹iBatis的映射繼承特性。 
    繼承是面向?qū)ο蟮木幊讨械淖罨镜母拍?,我們這里不對繼承的概念做過多的介紹,只是來看看在iBatis中對映射繼承的做法。 


    iBatis的resultMap可以使用<discriminator>標簽來支持繼承體系。使用鑒別器標簽可以根據(jù)數(shù)據(jù)庫中某字段的值來確定要實例化類的類型。那么我們來看一下oderitem關于映射繼承的示例,首先我們修改orderItem模型類,添加type屬性: 

package ibatis.model;  
public class OrderItem implements java.io.Serializable {  
    private Integer orderItemId;  
    private String itemName;  
    private int quantity;  
    private float price;  
    private String type;  
    private Integer orderId;  
    public OrderItem() {  
    }  
    public OrderItem(Integer orderItemId, String itemName, int quantity,  
            float price, String type, Integer orderId) {  
        super();  
        this.orderItemId = orderItemId;  
        this.itemName = itemName;  
        this.quantity = quantity;  
        this.price = price;  
        this.orderId = orderId;  
    }  
    //getters and setters  
    public String toString() {  
        return "OrderItem [itemName=" + itemName + ", orderId=" + orderId  
                + ", orderItemId=" + orderItemId + ", price=" + price  
                + ", quantity=" + quantity + ", type=" + type + "]";  
    }  
}  
  那么resultMap的映射文件我們可以寫為: 
<resultMap class="ibatis.model.OrderItem" id="orderItem">  
    <result property="orderItemId" column="orderItemId" />  
    <result property="orderId" column="orderId" />  
    <result property="itemName" column="itemName" />  
    <result property="quantity" column="quantity" />  
    <result property="price" column="price" />  
    <result property="type" column="type" />  
    <discriminator column="type" javaType="java.lang.String">  
        <subMap resultMap="Individual" value="individual" />  
        <subMap resultMap="Group" value="group" />  
    </discriminator>  
</resultMap>  
  
<resultMap class="ibatis.model.Individual" id="Individual"  
    extends="orderItem">  
    <result property="username" column="username" />  
</resultMap>  
  
<resultMap class="ibatis.model.Group" id="Group" extends="orderItem">  
    <result property="company" column="company" />  
</resultMap>  
   很容易理解discriminator為我們選擇type的類型,并查找子映射,這里我們在orderitem表中添加兩個字段,username表示individual的訂單的用戶名,company表示group的訂單的公司名稱,就很好理解了。 
   來看一下這里我們定義的兩個類Individual和Group: 
package ibatis.model;  
public class Individual extends OrderItem {  
    private String username;  
    public String getUsername() {  
        return username;  
    }  
    public void setUsername(String username) {  
        this.username = username;  
    }  
    @Override  
    public String toString() {  
        return super.toString() + "Individual [username=" + username + "]";  
    }  
}  
   我們可以這么來理解,個體訂單是訂單的一個子類,其中我們要標識下該訂單的用戶名稱,那么我們就在這個類中定義一個username屬性,給出getter和setter方法,加上toString()方法,便于我們后續(xù)測試來打印其內(nèi)容。同理,我們可以得到Group類: 
package ibatis.model;  
public class Group extends OrderItem {  
    private String company;  
    public String getCompany() {  
        return company;  
    }  
    public void setCompany(String company) {  
        this.company = company;  
    }  
    @Override  
    public String toString() {  
        return super.toString() + "Group [company=" + company + "]";  
    }  
}  
   其道理和Individual類相同,這里不再解釋了。下面編寫一個查詢語句: 
<select id="getOrderItemById" resultMap="orderItem">  
    select * from orderitem where orderitemId=1  
</select>  
  為了測試,我們將SQL直接給定,那么后面就需要編寫測試代碼了,也很簡單,我們來看一下: 
package ibatis;  
import java.io.IOException;  
import java.io.Reader;  
import com.ibatis.common.resources.Resources;  
import com.ibatis.sqlmap.client.SqlMapClient;  
import com.ibatis.sqlmap.client.SqlMapClientBuilder;  
public class DiscriminatorDemo {  
    private static String config = "ibatis/SqlMapConfig.xml";  
    private static Reader reader;  
    private static SqlMapClient sqlMap;  
    static {  
        try {  
            reader = Resources.getResourceAsReader(config);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);  
    }  
    public static void main(String[] args) throws Exception {  
        Object obj = sqlMap.queryForObject("OrderItem.getOrderItemById");  
        System.out.println(obj.getClass().getName());  
        System.out.println(obj);  
    }  
}  
    在主函數(shù)內(nèi),我們通過sqlMapClient獲取到這條查詢語句,不需要任何參數(shù),它的返回值我們先定義成Object類型,方便后續(xù)操作,之后我們打印出該Object類的名稱,看看到底是哪種類型,最后打印出這個對象所包含的內(nèi)容,執(zhí)行語句,我們得到如下結(jié)果: 
ibatis.model.Individual 
OrderItem [itemName=Moto MB525, orderId=1, orderItemId=1, price=1000.0, quantity=1, type=individual]Individual [username=Sarin] 


    可以看到orderitemId為1時,這是一個個人訂單,最終的Object為Individual類型,我們可以打印出OrderItem和子類Individual的信息,那么下單人也會打印出來。同理,我們查詢一個團體訂單,可以得到如下結(jié)果: 
ibatis.model.Group 
OrderItem [itemName=Lenovo X201, orderId=2, orderItemId=3, price=5000.0, quantity=1, type=group]Group [company=soft] 


    這也是我們期望的結(jié)果。請記住iBatis僅僅是一個SQL Mapping框架,而不是ORM框架,iBatis本身不知道也不關心我們類的關系和數(shù)據(jù)表之間的映射關系。那么你可以隨意使用鑒別器,只要合適業(yè)務,即可使用。 

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號