欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于MyBatis中映射對(duì)象關(guān)系的舉例

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

MyBatis映射對(duì)象關(guān)系

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

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

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

所謂聚合就是one方和many方可以獨(dú)立存在;組合關(guān)系是強(qiáng)聚合關(guān)系,one方和many方解除關(guān)系后,就沒(méi)有實(shí)際意義了。

在組合關(guān)系中,必須要處理的一個(gè)問(wèn)題就是級(jí)聯(lián)關(guān)系。

下面使用SaleBill和SaleBillItem對(duì)象來(lái)完成雙向的many2one/one2many的組合關(guān)系。

對(duì)象設(shè)計(jì)如下:

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

下面來(lái)看看映射文件:    

<mapper namespace="cd.itcast.mybatis.salebill.SaleBillMapper">
<!-- 保存SaleBill對(duì)象,該調(diào)用必須放在SaleBillItem對(duì)象保存之前 -->
    <insert id="saveSaleBill" keyProperty="id" parameterType="SaleBill"
                useGeneratedKeys="true">
                INSERT INTO salebill(sn) values (#{sn})
    </insert>
<!-- 保存SaleBillItem對(duì)象 -->
    <insert id="saveSaleBillItem" keyProperty="id" parameterType="SaleBillItem" useGeneratedKeys="true">
            INSERT INTO salebillitem(price,bill_id) values (#{price},#{bill.id})
</insert>
<!-- 內(nèi)嵌映射SaleBill對(duì)象,注意,因?yàn)槭墙M合關(guān)系,所以不會(huì)出現(xiàn)單獨(dú)去拿SaleBillItem對(duì)象的情況,所以只需要映射SaleBill主對(duì)象即可 -->
<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>
 
<!-- 因?yàn)榱斜砗蛦为?dú)的get方法都是采用內(nèi)聯(lián)的查詢,所以把公用的SQL提取出來(lái) -->
    <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對(duì)象 -->
    <delete id="delete" parameterType="long">
            DELETE FROM salebill WHERE id = #{id}      
    </delete>
 
<!-- 刪除SaleBill對(duì)象對(duì)應(yīng)的Item對(duì)象,注意,因?yàn)橛型怄I的約束,這條刪除語(yǔ)句應(yīng)該放在delete SaleBill之前執(zhí)行。注意,傳入的這個(gè)id應(yīng)該是SaleBill的id -->
    <delete id="deleteItems" parameterType="long">
     DELETE FROM salebillitem WHERE bill_id = #{id}
    </delete>
</mapper>

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

主要注意一點(diǎn)的就是在設(shè)計(jì)映射文件的時(shí)候需要考慮組合關(guān)系的一般設(shè)計(jì)方式,所以在上面的配置文件中只做了SaleBill對(duì)象的映射。

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

在組合關(guān)系中,主要的問(wèn)題就是一個(gè)級(jí)聯(lián)保存,但是注意,在mybatis中設(shè)計(jì)組合的級(jí)聯(lián)保存,刪除,這個(gè)過(guò)程應(yīng)該是我們自己來(lái)控制的。  

下面來(lái)看看怎么測(cè)試組合關(guān)系:

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

具體測(cè)試代碼:

@Test
public void testSave() {
? ? //創(chuàng)建SaleBill對(duì)象
? ? SaleBill sb = new SaleBill();
? ? sb.setSn("001");
? ? //創(chuàng)建一個(gè)明細(xì)對(duì)象
? ? SaleBillItem sbi = new SaleBillItem();
? ? sbi.setPrice(100d);
? ? sbi.setBill(sb);
? ? //創(chuàng)建一個(gè)明細(xì)對(duì)象
? ? SaleBillItem sbi2 = new SaleBillItem();
? ? sbi2.setPrice(300d);
? ? sbi2.setBill(sb);
? ? //處理關(guān)系
? ? sb.getItems().add(sbi);
? ? sb.getItems().add(sbi2);
? ? //保存
? ? SqlSession session = MyBatisUtil.openSession();
? ? SaleBillMapper mapper = session.getMapper(SaleBillMapper.class);
? ? //注意,先保存SaleBill對(duì)象
? ? mapper.saveSaleBill(sb);
? ? //保存明細(xì)對(duì)象
? ? mapper.saveSaleBillItem(sbi);
? ? mapper.saveSaleBillItem(sbi2);
? ? session.commit();
? ? session.close();
}
?
@Test
public void testGet() {
? ? SqlSession session = MyBatisUtil.openSession();
? ? //得到SaleBill對(duì)象
? ? 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的真正強(qiáng)大之處在于它的映射語(yǔ)句,這也是它的魔力所在。由于它的映射語(yǔ)句異常強(qiáng)大,映射器的 XML 文件就顯得相對(duì)簡(jiǎn)單。

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

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

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>根標(biāo)簽的 name space 屬性。當(dāng) Mapper 接口和 XML 文件關(guān)聯(lián)的時(shí)候,命名空間口amespace 的值就需要配置成接口的全限定名稱,例如 UserMapper 接口對(duì)應(yīng)的 tk. mybatis . simple .mapper . UserMapper, MyBatis 內(nèi)部就是通過(guò)這個(gè)值將接口和XML 關(guān)聯(lián)起來(lái)的。

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>

更簡(jiǎn)單的配置方式,代碼如下

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

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

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

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

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

由于方法參數(shù)和返回值存在很多種情況,因此 MyBatis 的內(nèi)部實(shí)現(xiàn)會(huì)比上面的邏輯復(fù)雜得多,正是因?yàn)?MyBatis 對(duì)接口動(dòng)態(tài)代理的實(shí)現(xiàn),我們?cè)谑褂媒涌诜绞降臅r(shí)候才會(huì)如此容易。 

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

相關(guān)文章

  • springboot 接收List 入?yún)⒌膸追N方法

    springboot 接收List 入?yún)⒌膸追N方法

    本文主要介紹了springboot 接收List 入?yún)⒌膸追N方法,本文主要介紹了7種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • Shell重啟SpringBoot項(xiàng)目腳本的示例代碼(含服務(wù)守護(hù))

    Shell重啟SpringBoot項(xiàng)目腳本的示例代碼(含服務(wù)守護(hù))

    本文介紹了如何使用?Bash?腳本來(lái)管理和守護(hù)運(yùn)行服務(wù),將展示一個(gè)示例腳本,該腳本可以停止、啟動(dòng)和守護(hù)運(yùn)行一個(gè)服務(wù),并提供了相應(yīng)的解釋和用法說(shuō)明,文章通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法

    springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法

    今天小編就為大家分享一篇springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題

    java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題

    這篇文章主要介紹了java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • spring boot 添加admin監(jiān)控的方法

    spring boot 添加admin監(jiān)控的方法

    這篇文章主要介紹了spring boot 添加admin監(jiān)控的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • Java使用POI導(dǎo)出Excel(一):?jiǎn)蝧heet

    Java使用POI導(dǎo)出Excel(一):?jiǎn)蝧heet

    這篇文章介紹了Java使用POI導(dǎo)出Excel的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • SpringCloud中數(shù)據(jù)認(rèn)證加密的方法總結(jié)

    SpringCloud中數(shù)據(jù)認(rèn)證加密的方法總結(jié)

    在當(dāng)今分布式系統(tǒng)的日益復(fù)雜和信息傳遞的廣泛網(wǎng)絡(luò)化環(huán)境中,數(shù)據(jù)的加密和認(rèn)證作為保障信息傳遞安全的關(guān)鍵手段,Spring?Cloud,作為一套構(gòu)建微服務(wù)架構(gòu)的強(qiáng)大框架,提供了多種靈活而強(qiáng)大的數(shù)據(jù)加密和認(rèn)證方式,本文給大家總結(jié)了SpringCloud數(shù)據(jù)認(rèn)證加密的方法
    2024-03-03
  • Spring框架的JdbcTemplate使用

    Spring框架的JdbcTemplate使用

    它是 Spring 框架中提供的一個(gè)對(duì)象,是對(duì)原始 Jdbc API 對(duì)象的簡(jiǎn)單封裝。本文就來(lái)介紹一下Spring框架的JdbcTemplate使用,感興趣的可以了解一下
    2021-09-09
  • Maven默認(rèn)使用JDK1.5的問(wèn)題及解決方案

    Maven默認(rèn)使用JDK1.5的問(wèn)題及解決方案

    這篇文章主要介紹了Maven默認(rèn)使用JDK1.5的問(wèn)題及解決方案,本文給大家分享兩種方式,通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Springboot如何同時(shí)裝配兩個(gè)相同類型數(shù)據(jù)庫(kù)

    Springboot如何同時(shí)裝配兩個(gè)相同類型數(shù)據(jù)庫(kù)

    這篇文章主要介紹了Springboot如何同時(shí)裝配兩個(gè)相同類型數(shù)據(jù)庫(kù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論