<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
CREATE TABLE person ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(32) NOT NULL DEFAULT '', card_id INT , FOREIGN KEY (card_id) REFERENCES idencard(id) )CHARSET utf8;
-- 建立 mybatis_idencard 表 CREATE TABLE idencard ( id INT PRIMARY KEY AUTO_INCREMENT, card_sn VARCHAR(32) NOT NULL DEFAULT '' )CHARSET utf8 ; INSERT INTO idencard VALUES(1,'111111111111110'); INSERT INTO person VALUES(1,'張三',1); SELECT * FROM person; SELECT * FROM idencard
● 基本介紹
1. 專案中 1 對 1 的關係是一個基本的對映關係,比如 :Person( 人 ) --- IDCard( 身份證 )
2. 我們看看再 MyBatis 中如何實現 1 對 1 的處理 .
● 注意細節
1 對 1 , 我們這裡就研究一下單向 1 對 1 即可
對映方式
1. 通過設定 XxxMapper.xml 實現 1 對 1 [ 設定方式 ]
2. 通過註解的方式實現 1 對 1 [ 註解方式 ]
通過設定 XxxMapper.xml 的方式來實現下面的 1 對 1 的對映關係,實現 級
聯查詢 , 通過 person 可以獲取到對應的 idencard 資訊
然後建立各自的javabean--->兩個表
然後我們就可以開始重頭戲了開始建立IdenCardMapper.java和IdenCardMapper.xml
public interface IdenCardMapper { //根據id獲取到身份證序列號 public IdenCard getIdenCardById(Integer id);
<!-- 1、設定/實現//根據id獲取到身份證序列號 2、public IdenCard getIdenCardById(Integer id); --> <select id="getIdenCardById" parameterType="Integer" resultType="IdenCard"> SELECT * FROM `idencard` WHERE `id` = #{id} </select>
//通過Person的id獲取到Person,包括這個Person關聯的IdenCard物件[級聯查詢] public Person getPersonById(Integer id);
<mapper namespace="com.hong.mapper.PersonMapper"> <!-- 1、設定/實現public Person getPersonById(Integer id); 2、完成通過Person的id獲取到Person,包括這個Person關聯的IdenCard物件[級聯查詢] 3. 為了讓小夥伴們理解的更加深刻一點,先用大家容易想到的方式-分析問題-解決問題 4. 看到如果設定成簡單 resultType="Person" 問題就是沒有實現級聯查詢 5. 自定義resultMap 搞定 對映返回的結果 6. 因為 getPersonById 最終返回的是 Person物件[只是有級聯的物件屬性], type仍然設定"Person" --> <resultMap id="PersonResultMap" type="Person"> <!--<result property="id" column="id"/>--> <!--id – 一個 ID 結果;標記出作為 ID 的結果可以幫助提高整體效能 1.property="id" 表示person 屬性 id ,通常是主鍵 2.column="id" 表示對應表的欄位 --> <id property="id" column="id"/> <result property="name" column="name"/> <!--association – 一個複雜型別的關聯 1. property="card" 表示 Person物件的 card 屬性 2. javaType="IdenCard" 表示card 屬性 的型別 3. column="id" 是從我們的 下面這個語句查詢後返回的欄位 SELECT * FROM `person`,`idencard` WHERE `person`.id=1 AND `person`.card_id = `idencard`.id --> <association property="card" javaType="IdenCard"> <result property="id" column="id"/> <result property="card_sn" column="card_sn"/> </association> </resultMap> <select id="getPersonById" parameterType="Integer" resultMap="PersonResultMap"> SELECT * FROM `person`,`idencard` WHERE `person`.id = #{id} AND `person`.card_id = `idencard`.id </select> </mapper>
1. 修改 PersonMapper.java 和 PersonMapper.xml 使用第 2 種對映方式 , 完成 1 對 1 對映 關係
//通過Person的id獲取到Person,包括這個Person關聯的IdenCard物件,方式2 public Person getPersonById2(Integer id); //編寫方法,通過card_id 查詢得到person物件/資料 public Person getPersonByCardId(Integer cardId);
<!-- 1、通過Person的id獲取到Person,包括這個Person關聯的IdenCard物件,方式2 2、public Person getPersonById2(Integer id); 3. 這裡的方式和前面不同. 1) 先通過 SELECT * FROM `person` WHERE `id` = #{id} 返回 person資訊 2) 再通過 返回的card_id 值,再執行操作,得到IdenCard 資料 --> <resultMap id="PersonResultMap2" type="Person"> <id property="id" column="id"/> <result property="name" column="name"/> <association property="card" column="card_id" select="com.hong.mapper.IdenCardMapper.getIdenCardById" /> </resultMap> <select id="getPersonById2" parameterType="Integer" resultMap="PersonResultMap2"> SELECT * FROM `person` WHERE `id` = #{id} </select> </mapper>
1. mybatis第二種方式核心思想: 將這個多表聯查,分解成單表操作 , 這樣簡潔,而且易於維護 ,推薦
2. 而且可以複用你已經寫好的方法 -組合
3. property="card": 表示 Person物件的 card 屬性
4. column="card_id" 這個是
SELECT * FROM `person` WHERE `id` = #{id} 返回的 欄位 card_id 資訊/資料
5. 返回的 欄位 card_id 資訊/資料 作為getIdenCardById入參, 來執行
先執行下面的select語句,然後將執行的結果中的card_id傳參給getIdenCardById,這個時候我們就直接返回的就是確定這個值的IdenCard的值了。
好,現在我們試著來說明一下啥叫將多表級聯變成現在的單表操作。
就是我們先來思考一下MySQL中的多表查詢,是不是有一個子查詢,你要是知道這個就差不多理解了一半了。我們資料庫中的子查詢是先將一個查詢結果返回給另外一個SQL語句進行操作。那麼一對一對映其實本質也是一樣,我們先將一個結果作為引數然後傳入到一個方法中,這個方法就可以運用這個結果去執行他的操作。
public interface PersonMapperAnnotation { //這裡註解實現方法 //說明: 註解的形式就是對前面xml設定方式的體現 //這裡同學們可以結合前面講解的xml設定時,加入的註釋來理解 @Select("SELECT * FROM `person` WHERE `id` = #{id}") @Results({ @Result(id = true, property = "id", column = "id"), @Result(property = "name", column = "name"), @Result(property = "card", column = "card_id", one = @One(select = "com.hong.mapper.IdenCardMapper.getIdenCardById")) }) public Person getPersonById(Integer id); }
註解的方式也就是xml形式的另外一種體現
public class PersonMapperAnnotationTest { //屬性 private SqlSession sqlSession; private PersonMapperAnnotation personMapperAnnotation; //初始化 @Before public void init() { //獲取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); personMapperAnnotation = sqlSession.getMapper(PersonMapperAnnotation.class); } @Test public void getPersonById() { Person person = personMapperAnnotation.getPersonById(1); System.out.println("person----" + person); if(sqlSession != null) { sqlSession.close(); } } }
1. 表是否設定外來鍵 , 對 MyBatis 進行物件 / 級聯對映沒有影響
2. 舉例 : 去掉 person 表的外來鍵 , 進行測試 , 依然可以獲取相應的級聯物件
1. 專案中多對 1 的關係是一個基本的對映關係 , 多對 1, 也可以理解成是 1 對多 .
2. User --- Pet : 一個使用者可以養多隻寵物
3. Dep ---Emp : 一個部門可以有多個員工
1. 我們直接講 雙向的多對一的關係 ,單向的多對一比雙向的多對一簡單。
2. 在實際的專案開發中 , 要求會使用雙向的多對一的對映關係
3. 說明:什麼是 雙向的多對一 的關係 : 比如通過 User 可以查詢到對應的 Pet, 反過 來,通過 Pet 也可以級聯查詢到對應的 User 資訊 .
4. 多對多的關係,是在多對 1 的基礎上擴充套件即可
1. 方式 1 :通過設定 XxxMapper.xml 實現多對 1 2.
方式 2 :通過註解的方式實現 多對 1
CREATE TABLE mybatis_user (id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(32) NOT NULL DEFAULT '' )CHARSET=utf8 ; CREATE TABLE mybatis_pet (id INT PRIMARY KEY AUTO_INCREMENT, nickname VARCHAR(32) NOT NULL DEFAULT '', user_id INT , FOREIGN KEY (user_id) REFERENCES mybatis_user(id) )CHARSET=utf8 ; INSERT INTO mybatis_user VALUES(NULL,'宋江'),(NULL,'張飛'); INSERT INTO mybatis_pet VALUES(1,'黑背',1),(2,'小哈',1); INSERT INTO mybatis_pet VALUES(3,'波斯貓',2),(4,'貴妃貓',2); SELECT * FROM mybatis_user; SELECT * FROM mybatis_pet;
<mapper namespace="com.hong.mapper.UserMapper"> <!--解讀 1、一定要想一想我們前面1-1是如何實現 2、設定/實現 public User getUserById(Integer id); 3、思路(1) 先通過user-id 查詢得到user資訊 (2) 再根據user-id查詢對應的pet資訊 並對映到User-List<Pet> pets --> <resultMap id="UserResultMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <!--解讀:因為pets屬性是集合,因此這裡需要是collection標籤來處理 1. ofType="Pet" 指定返回的集合中存放的資料型別Pet 2. collection 表示 pets 是一個集合 3. property="pets" 是返回的user物件的屬性 pets 4. column="id" SELECT * FROM `mybatis_user` WHERE `id` = #{id} 返回的id欄位對應的值 --> <collection property="pets" column="id" ofType="Pet" select="com.hong.mapper.PetMapper.getPetByUserId"/> </resultMap> <select id="getUserById" parameterType="Integer" resultMap="UserResultMap"> SELECT * FROM `mybatis_user` WHERE `id` = #{id} </select> </mapper>
<mapper namespace="com.hong.mapper.PetMapper"> <!-- 1、通過User的id來獲取pet物件,可能有多個,因此使用List接收 2、public List<Pet> getPetByUserId(Integer userId); 3. 完成的思路和前面大體相同. --> <resultMap id="PetResultMap" type="Pet"> <id property="id" column="id"/> <result property="nickname" column="nickname"/> <association property="user" column="user_id" select="com.hong.mapper.UserMapper.getUserById" /> </resultMap> <select id="getPetByUserId" parameterType="Integer" resultMap="PetResultMap"> SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId} </select> <!--說明 1. 注意體會resultMap帶來好處, 直接複用 2. 實現/設定public Pet getPetById(Integer id); 3. 通過pet的id獲取Pet物件 --> <select id="getPetById" parameterType="Integer" resultMap="PetResultMap"> SELECT * FROM `mybatis_pet` WHERE `id` = #{id} </select> </mapper>
需求說明 : 通過註解的方式來實現下面的多對 1 的對映關係,實現級聯查詢 , 完成前面完成 的任務,通過 User-->Pet 也可 Pet->User , 在實際開發中 推薦使用設定方式來 做
public interface UserMapperAnnotation { //通過id獲取User物件 /** * 1. 註解的設定就是對應的Mapper.xml檔案設定的,改寫 * 2. * 1、一定要想一想我們前面1-1是如何實現 * 2、設定/實現 public User getUserById(Integer id); * 3、思路(1) 先通過user-id 查詢得到user資訊 (2) 再根據user-id查詢對應的pet資訊 * 並對映到User-List<Pet> pets * <resultMap id="UserResultMap" type="User"> * <id property="id" column="id"/> * <result property="name" column="name"/> * 1. ofType="Pet" 指定返回的集合中存放的資料型別Pet * 2. collection 表示 pets 是一個集合 * 3. property="pets" 是返回的user物件的屬性 pets * 4. column="id" SELECT * FROM `mybatis_user` WHERE `id` = #{id} 返回的id欄位對應的值 * --> * <collection property="pets" column="id" ofType="Pet" * select="com.hong.mapper.PetMapper.getPetByUserId"/> * </resultMap> * <select id="getUserById" parameterType="Integer" resultMap="UserResultMap"> * SELECT * FROM `mybatis_user` WHERE `id` = #{id} * </select> */ @Select("SELECT * FROM `mybatis_user` WHERE `id` = #{id}") @Results({ @Result(id = true, property = "id", column = "id"), @Result(property = "name", column = "name"), //這裡請小夥伴注意,pets屬性對應的是集合 @Result(property = "pets", column = "id", many = @Many(select = "com.hong.mapper.PetMapperAnnotation.getPetByUserId")) }) public User getUserById(Integer id); }
public interface PersonMapperAnnotation { //這裡註解實現方法 //說明: 註解的形式就是對前面xml設定方式的體現 //這裡同學們可以結合前面老師講解的xml設定時,加入的註釋來理解 @Select("SELECT * FROM `person` WHERE `id` = #{id}") @Results({ @Result(id = true, property = "id", column = "id"), @Result(property = "name", column = "name"), @Result(property = "card", column = "card_id", one = @One(select = "com.hong.mapper.IdenCardMapper.getIdenCardById")) }) public Person getPersonById(Integer id); }
public interface PetMapperAnnotation { //通過User的id來獲取pet物件,可能有多個,因此使用List接收 /** * 1、通過User的id來獲取pet物件,可能有多個,因此使用List接收 * 2、public List<Pet> getPetByUserId(Integer userId); * 3. 完成的思路和前面大體相同. * <resultMap id="PetResultMap" type="Pet"> * <id property="id" column="id"/> * <result property="nickname" column="nickname"/> * <association property="user" column="user_id" * select="com.hong.mapper.UserMapper.getUserById" /> * </resultMap> * <select id="getPetByUserId" parameterType="Integer" resultMap="PetResultMap"> * SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId} * </select> */ //id = "PetResultMap" 就是給我們的Results[Result Map] 指定一個名字 //,目的是為了後面複用 @Select("SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId}") @Results(id = "PetResultMap", value = { @Result(id = true, property = "id", column = "id"), @Result(property = "nickname", column = "nickname"), @Result(property = "user", column = "user_id", one = @One(select = "com.hong.mapper.UserMapperAnnotation.getUserById")) }) public List<Pet> getPetByUserId(Integer userId); //通過pet的id獲取Pet物件, 同時會查詢到pet物件關聯的user物件 /** * <select id="getPetById" * parameterType="Integer" * resultMap="PetResultMap"> * SELECT * FROM `mybatis_pet` WHERE `id` = #{id} * </select> * * @ResultMap("PetResultMap") 使用/參照我們上面定義的 Results[ResultMap] */ @Select("SELECT * FROM `mybatis_pet` WHERE `id` = #{id}") @ResultMap("PetResultMap") public Pet getPetById(Integer id); }
一對多的思路:
1.首先我們通過id="getUserById"的select查詢獲取到user-id對應的所有資料
2.之後也可以通過user-id獲取到pet是的資訊
3.之後我們也可以通過User的id來獲取pet物件,可能有多個,因此使用List接收
簡而言之:
就是我們可以通過主人的id查詢到寵物的資訊,同時也可以通過寵物的資訊查詢到主人。
一對一是我先查詢一個id,在通過這個id查詢到一個資訊,而這個資訊是可以查詢到另外一個表的資訊的。而一對多是我通過一個欄位查詢到這個欄位在這個資訊裡面的所相關的內容(就像一個id可以查詢到主人對應的寵物資訊),當然是存放在集合之中的。
到此這篇關於MyBatis對映關係的文章就介紹到這了,更多相關MyBatis對映關係內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45