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

2018-10-14 10:41 更新

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


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

<statement id="addColumn">  
    alter table orderitem add column type VARCHAR(50);  
</statement>  
  下面編寫程序來調(diào)用這個(gè)語句:
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來測(cè)試是成功的,我們得到了如下的數(shù)據(jù)庫表結(jié)構(gòu): 

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


    iBatis的resultMap可以使用<discriminator>標(biāo)簽來支持繼承體系。使用鑒別器標(biāo)簽可以根據(jù)數(shù)據(jù)庫中某字段的值來確定要實(shí)例化類的類型。那么我們來看一下oderitem關(guān)于映射繼承的示例,首先我們修改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的類型,并查找子映射,這里我們?cè)趏rderitem表中添加兩個(gè)字段,username表示individual的訂單的用戶名,company表示group的訂單的公司名稱,就很好理解了。 
   來看一下這里我們定義的兩個(gè)類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 + "]";  
    }  
}  
   我們可以這么來理解,個(gè)體訂單是訂單的一個(gè)子類,其中我們要標(biāo)識(shí)下該訂單的用戶名稱,那么我們就在這個(gè)類中定義一個(gè)username屬性,給出getter和setter方法,加上toString()方法,便于我們后續(xù)測(cè)試來打印其內(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類相同,這里不再解釋了。下面編寫一個(gè)查詢語句: 
<select id="getOrderItemById" resultMap="orderItem">  
    select * from orderitem where orderitemId=1  
</select>  
  為了測(cè)試,我們將SQL直接給定,那么后面就需要編寫測(cè)試代碼了,也很簡(jiǎn)單,我們來看一下: 
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類的名稱,看看到底是哪種類型,最后打印出這個(gè)對(duì)象所包含的內(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時(shí),這是一個(gè)個(gè)人訂單,最終的Object為Individual類型,我們可以打印出OrderItem和子類Individual的信息,那么下單人也會(huì)打印出來。同理,我們查詢一個(gè)團(tuán)體訂單,可以得到如下結(jié)果: 
ibatis.model.Group 
OrderItem [itemName=Lenovo X201, orderId=2, orderItemId=3, price=5000.0, quantity=1, type=group]Group [company=soft] 


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

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)