最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于MyBatis中映射對象關系的舉例

 更新時間:2022年06月22日 10:25:01   作者:lanyotechcs  
這篇文章主要介紹了關于MyBatis中映射對象關系的舉例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

MyBatis映射對象關系

雙向many2one/one2many關系中的組合關系(級聯(lián))

上面已經(jīng)看到了雙向many2one/one2many關系的映射。

但是我們說,在關聯(lián)關系中,還存在組合/聚合關系。

所謂聚合就是one方和many方可以獨立存在;組合關系是強聚合關系,one方和many方解除關系后,就沒有實際意義了。

在組合關系中,必須要處理的一個問題就是級聯(lián)關系。

下面使用SaleBill和SaleBillItem對象來完成雙向的many2one/one2many的組合關系。

對象設計如下:

//銷售單對象
public class SaleBill {
    private Long id;
    private String sn;
    private Set<</span>SaleBillItem> items = new HashSet<</span>SaleBillItem>();
    //getter & setter
}  
        
//銷售單明細對象
public class SaleBillItem {
    private Long id;
    private Double price;
    private SaleBill bill;
    //getter & setter
}
  • 對于組合關系,數(shù)據(jù)表的結(jié)構設計和many2one一樣,都是many方一個外鍵引用one方的主鍵。
  • 在組合關系中,一般來說,明細項是不需要額外有一個Mapper文件的,所有的映射都應該放在One方的映射文件中。

下面來看看映射文件:    

<mapper namespace="cd.itcast.mybatis.salebill.SaleBillMapper">
<!-- 保存SaleBill對象,該調(diào)用必須放在SaleBillItem對象保存之前 -->
    <insert id="saveSaleBill" keyProperty="id" parameterType="SaleBill"
                useGeneratedKeys="true">
                INSERT INTO salebill(sn) values (#{sn})
    </insert>
<!-- 保存SaleBillItem對象 -->
    <insert id="saveSaleBillItem" keyProperty="id" parameterType="SaleBillItem" useGeneratedKeys="true">
            INSERT INTO salebillitem(price,bill_id) values (#{price},#{bill.id})
</insert>
<!-- 內(nèi)嵌映射SaleBill對象,注意,因為是組合關系,所以不會出現(xiàn)單獨去拿SaleBillItem對象的情況,所以只需要映射SaleBill主對象即可 -->
<resultMap type="SaleBill" id="salebillmap">
            <id property="id" column="id"/>
            <result column="sn" property="sn"/>
            <collection property="items" column="id" ofType="SaleBillItem" >
            <id column="item_id" property="id"/>
            <result column="item_price" property="price"/>
            <association property="bill" column="bill_id" resultMap="salebillmap" />
           </collection>
</resultMap>
 
<!-- 因為列表和單獨的get方法都是采用內(nèi)聯(lián)的查詢,所以把公用的SQL提取出來 -->
    <sql id="select">
            SELECT b.*,item.id as item_id,item.price as item_price FROM salebill b LEFT JOIN salebillitem item ON b.id = item.bill_id
     </sql>
 
<!-- get -->
    <select id="get" parameterType="long" resultMap="salebillmap">
            <include refid="select"/> WHERE b.id = #{id}
     </select>
 
<!-- 列表查詢 -->
    <select id="list" resultMap="salebillmap">
            <include refid="select"/>
     </select>
 
<!-- 刪除SaleBill對象 -->
    <delete id="delete" parameterType="long">
            DELETE FROM salebill WHERE id = #{id}      
    </delete>
 
<!-- 刪除SaleBill對象對應的Item對象,注意,因為有外鍵的約束,這條刪除語句應該放在delete SaleBill之前執(zhí)行。注意,傳入的這個id應該是SaleBill的id -->
    <delete id="deleteItems" parameterType="long">
     DELETE FROM salebillitem WHERE bill_id = #{id}
    </delete>
</mapper>

映射文件的內(nèi)容都已經(jīng)注釋詳細。

主要注意一點的就是在設計映射文件的時候需要考慮組合關系的一般設計方式,所以在上面的配置文件中只做了SaleBill對象的映射。

這個配置文件還是很好理解的,其中所有的配置點在前面都已經(jīng)介紹過。

在組合關系中,主要的問題就是一個級聯(lián)保存,但是注意,在mybatis中設計組合的級聯(lián)保存,刪除,這個過程應該是我們自己來控制的。  

下面來看看怎么測試組合關系:

//先創(chuàng)建一個Mapper接口,使用接口來完成映射
public interface SaleBillMapper {
? ? void saveSaleBill(SaleBill sb);
? ? void saveSaleBillItem(SaleBillItem sbi);
? ? SaleBill get(Long id);
? ? //在接口中可以直接映射分頁對象
? ? List<</span>SaleBill> list(RowBounds rb);
? ? void delete(Long id);
? ? void deleteItems(Long billId);
}

具體測試代碼:

@Test
public void testSave() {
? ? //創(chuàng)建SaleBill對象
? ? SaleBill sb = new SaleBill();
? ? sb.setSn("001");
? ? //創(chuàng)建一個明細對象
? ? SaleBillItem sbi = new SaleBillItem();
? ? sbi.setPrice(100d);
? ? sbi.setBill(sb);
? ? //創(chuàng)建一個明細對象
? ? SaleBillItem sbi2 = new SaleBillItem();
? ? sbi2.setPrice(300d);
? ? sbi2.setBill(sb);
? ? //處理關系
? ? sb.getItems().add(sbi);
? ? sb.getItems().add(sbi2);
? ? //保存
? ? SqlSession session = MyBatisUtil.openSession();
? ? SaleBillMapper mapper = session.getMapper(SaleBillMapper.class);
? ? //注意,先保存SaleBill對象
? ? mapper.saveSaleBill(sb);
? ? //保存明細對象
? ? mapper.saveSaleBillItem(sbi);
? ? mapper.saveSaleBillItem(sbi2);
? ? session.commit();
? ? session.close();
}
?
@Test
public void testGet() {
? ? SqlSession session = MyBatisUtil.openSession();
? ? //得到SaleBill對象
? ? SaleBillMapper mapper = session.getMapper(SaleBillMapper.class);
? ? SaleBill sb = mapper.get(5l);
? ? Set<</span>SaleBillItem> items = sb.getItems();
? ? for (SaleBillItem item : items) {
? ? ? ? ? ? System.out.println(item.getPrice());
? ? }
? ? session.close();
}
?
@Test
public void testDelete() {
? ? SqlSession session = MyBatisUtil.openSession();
? ? SaleBillMapper mapper = session.getMapper(SaleBillMapper.class);
? ? mapper.deleteItems(1l);
? ? mapper.delete(1l);
? ? session.commit();
? ? session.close();
} ? ?

Mybatis映射原理

MyBatis的真正強大之處在于它的映射語句,這也是它的魔力所在。由于它的映射語句異常強大,映射器的 XML 文件就顯得相對簡單。

MyBatis3.0相比2.0版本的一個最大變化,就是支持使用接口來調(diào)用方法。

  • 以前使用 SqlSession 通過命名空間調(diào)用 MyBatis 方法時,首先需要用到命名空間和方法id 組成的字符串來調(diào)用相應的方法 。
  • 當參數(shù)多于 1 個的時候,需要將所有參數(shù)放到一個 Map對象中 。 通過 Map 傳遞多個參數(shù),使用起來很不方便,而且還無法避免很多重復的代碼。
  • 使用接口調(diào)用方式就會方便很多, MyBatis 使用 Java 的動態(tài)代理可以直接通過接口來調(diào)用 相應 的方法,不需要提供接口的實現(xiàn)類,更不需要在實現(xiàn)類中使用 SqlSess 工∞以通過命名空 間間接調(diào)用 。
  • 另外,當有多個參數(shù)的時候,通過參數(shù)注解@ Par am 設置參數(shù)的名字省去了 手動構造 Map 參數(shù)的過程,尤其在 Spring 中使用的時候,可以配置為自動掃描所有的接口類 ,直接將接口注入需要用到的地方。

mapper文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cnpiec.ireader.dao.GetBookDataDao">
? ? <insert id="batchInsertBook" parameterType="Book">
? ? ? ? INSERT INTO BOOK (BOOKID,NAME,PARTNERNAME) VALUES
? ? ? ? <foreach collection="list" item="book" separator=",">
? ? ? ? ? ? (#{book.bookId}, #{book.name}, #{book.partnerName})
? ? ? ? </foreach>
? ? </insert>
</mapper>

需要注意的是<mapper>根標簽的 name space 屬性。當 Mapper 接口和 XML 文件關聯(lián)的時候,命名空間口amespace 的值就需要配置成接口的全限定名稱,例如 UserMapper 接口對應的 tk. mybatis . simple .mapper . UserMapper, MyBatis 內(nèi)部就是通過這個值將接口和XML 關聯(lián)起來的。

mybati s-config.xml 配置文件中的 mappers 元素中配置所有的 mapper ,部分配置代碼如下 。

<mappers>
? ? <mapper resource=” tk/mybatis/simple/mapper/CountryMapper.xml ” / >
? ? <mapper resource=” tk/mybatis/simple/mapper/UserMapper . xml ” / >
? ? <mapper resource=” tk/mybatis/simple/mapper/RoleMapper.xml ” />
? ? <mapper resource=” tk/mybatis/simple/mapper/PrivilegeMapper . xml ” />
? ? <mapper resource=” tk/mybatis/simple/mapper/UserRoleMapper . xml ” />
? ? <mapper resource=” tk/mybatis/simple/mapper / RolePrivilegeMapper.xml ” />
</mappers>

更簡單的配置方式,代碼如下

<mappers>
? ? <package name= ” tk.mybatis . simple . mapper ” />
</mappers>

這種配置方式會先查找 tk.mybatis.simple . mapper 包下所有的接口,循環(huán)對接口進行如下操作。這種配置方式會先查找 tk.mybatis.simple . mapper 包下所有的接口,循環(huán)對接口進行判斷接口對應的命名 空 間是否己經(jīng)存在,如果不存在就拋出異常,存在就繼續(xù)進行接下來的操作。加載接口對應的卻也映射文件 , 將接口全限定名轉(zhuǎn)換為路徑.

為什么 Mapper 接口沒有實現(xiàn)類卻能被正常調(diào)用呢?

這是因為MyBaits 在 Mapper 接口上使用了動態(tài)代理的一種非常規(guī)的用法,熟悉這動態(tài)代理的用法不僅有利于理解 MyBatis 接口和 XML 的關系,還能開闊思路 。

從代理類中可以看到,當調(diào)用 一個接口的方法時,會先通過接口的全限定名稱和當前調(diào)用的方法名的組合得到一個方法 id,這個 id 的值就是映射 XML 中口arnespa ce 和具體方法 id的組合。所以可以在代理方法中使用 sqlSession 以命名空間的方式調(diào)用方法。通過這種方式可以將接口和 XML 文件中的方法關聯(lián)起來。這種代理方式和常規(guī)代理的不同之處在于,這里沒有對某個具體類進行代理,而是通過代理轉(zhuǎn)化成了對其他代碼的調(diào)用。

由于方法參數(shù)和返回值存在很多種情況,因此 MyBatis 的內(nèi)部實現(xiàn)會比上面的邏輯復雜得多,正是因為 MyBatis 對接口動態(tài)代理的實現(xiàn),我們在使用接口方式的時候才會如此容易。 

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • mybatis plus or and 的合并寫法實例

    mybatis plus or and 的合并寫法實例

    這篇文章主要介紹了mybatis plus or and 的合并寫法實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • SpringBoot淺析緩存機制之Redis單機緩存應用

    SpringBoot淺析緩存機制之Redis單機緩存應用

    在上文中我介紹了Spring Boot使用EhCache 2.x來作為緩存的實現(xiàn),本文接著介紹使用單機版的Redis作為緩存的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Maven Spring jar包啟動報錯問題解決方案

    Maven Spring jar包啟動報錯問題解決方案

    maven 編譯jar包,放在linux服務器啟動不起來,提示:xxxx-0.0.1-SNAPSHOT.jar中沒有主清單屬性,接下來通過本文給大家分享問題原因及解決方案,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • JDK14之jpackage打包命令的使用

    JDK14之jpackage打包命令的使用

    這篇文章主要介紹了JDK14之jpackage打包命令的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Java棧的運用之中綴表達式求值詳解

    Java棧的運用之中綴表達式求值詳解

    本文來介紹一題中綴表達式求值的問題,就是給定一個中綴計算式,編寫程序?qū)⑦@個式子運算結(jié)果給計算出來,其實和后綴表達式的思路差不多,都是棧的運用問題,感興趣的可以了解一下
    2022-11-11
  • 使用Spring自定義實現(xiàn)IOC和依賴注入(注解方式)

    使用Spring自定義實現(xiàn)IOC和依賴注入(注解方式)

    這篇文章主要介紹了使用Spring自定義實現(xiàn)IOC和依賴注入(注解方式),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot中到底該如何解決跨域問題

    SpringBoot中到底該如何解決跨域問題

    跨域問題更是老生常談,隨便用標題去google或百度一下,能搜出一大片解決方案,這篇文章主要給大家介紹了關于SpringBoot中到底該如何解決跨域問題的相關資料,需要的朋友可以參考下
    2022-02-02
  • Spring?Boot?底層原理基礎深度解析

    Spring?Boot?底層原理基礎深度解析

    這篇文章主要介紹了Spring?Boot?底層原理基礎,包括底層注解@Configuration,底層注解@Import及底層注解@Conditional的相關知識,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • JAVA Vector源碼解析和示例代碼

    JAVA Vector源碼解析和示例代碼

    本文的學習方式是先對JAVA Vector有個整體認識,然后再學習它的源碼,最后再通過實例來學會使用。
    2013-11-11
  • net.sf.json.JSONObject 為null 的判斷方法

    net.sf.json.JSONObject 為null 的判斷方法

    下面小編就為大家?guī)硪黄猲et.sf.json.JSONObject 為null 的判斷方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02

最新評論

花莲县| 徐水县| 峨眉山市| 资阳市| 江城| 广丰县| 南皮县| 崇仁县| 洞口县| 雷山县| 甘洛县| 西充县| 贵定县| 祁阳县| 修武县| 峡江县| 丰顺县| 旺苍县| 新郑市| 安达市| 邯郸县| 清涧县| 墨竹工卡县| 雅安市| 德昌县| 嘉祥县| 图片| 哈巴河县| 达孜县| 卢氏县| 赞皇县| 佛冈县| 西乌珠穆沁旗| 绥滨县| 莎车县| 洪江市| 手游| 湖南省| 沙湾县| 寿光市| 易门县|