hibernate學習(三)

突然感覺接觸到了流幣的知識,完全不懂。數(shù)據(jù)庫方面的很多東西以前都沒接觸過召烂。等今年開課在認真學一遍吧,暫時按照教程把我學到的東西整理下垄懂。

第一節(jié) 一對多映射列表(XML)

對于沒有系統(tǒng)學習過數(shù)據(jù)庫的我而言一開始并不明白這是什么意思骑晶。教程給的例子使用的聯(lián)系人痛垛,感覺還是很好理解的。一個客戶可以擁有多個用戶桶蛔,客戶就是一聯(lián)系人就是多匙头,即一對多。

  • 創(chuàng)建用戶實體類 Customer.java
package cn.lkangle.entity;

import java.util.HashSet;
import java.util.Set;

public class Customer {
    private Integer cid;
    private String name;
    private String attr;
    
    // 將聯(lián)系人保存于set集合中
    private Set<LinkMan> linkMans = new HashSet<LinkMan>();
    ...
}
  • 創(chuàng)建聯(lián)系人實體類 LinkMan.java
package cn.lkangle.entity;

public class LinkMan {
    private Integer lid;
    private String name;
    private String tel;

    // 用于保存所屬客戶
    private Customer customer;
    ...
}
  • XML映射配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
          
<hibernate-mapping>
     <!-- 一對多的客戶映射配置 -->
    <class name="cn.lkangle.entity.Customer" table="t_customer">
        <id name="cid" column="cid">
            <generator class="native"></generator>
        </id>
        <property name="name" column="cname"></property>
        <property name="attr" column="cattr"></property>
        
        <set name="linkMans" cascade="save-update,delete">
            <key column="clid"></key>
            <one-to-many class="cn.lkangle.entity.LinkMan"></one-to-many>
        </set>
    </class>
    
    <!-- 一對多的聯(lián)系人映射配置 -->
    <class name="cn.lkangle.entity.LinkMan" table="t_linkman">
        <id name="lid" column="lid">
            <generator class="native"></generator>
        </id>
        <property name="name" column="lname"></property>
        <property name="tel" column="ltel"></property>
        
        <many-to-one name="customer" class="cn.lkangle.entity.Customer" column="clid" cascade="save-update"></many-to-one>
    </class>
</hibernate-mapping>

客戶的set標簽與聯(lián)系人的many-to-one標簽是配置一對多的關鍵仔雷,其中的cascade屬性設置級聯(lián)操作蹂析。
級聯(lián)具有方向性,在客戶中添加只有在對客戶進行操作時才會產生級聯(lián)碟婆,在聯(lián)系人中添加只有對聯(lián)系人進行操作時才產生級聯(lián)

cascade屬性取值:

  • update-save 在更新和保存時進行級聯(lián)
  • delete 在刪除時進行級聯(lián)
  • all 任何操作都進行級聯(lián)
  • 一對多級聯(lián)的CRUD操作
package cn.lkangle.threeday;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.lkangle.entity.Customer;
import cn.lkangle.entity.LinkMan;
import cn.lkangle.util.HbmUtil;

public class OnetoManyTest {
    /**
     * 雙重級聯(lián)效果 配置文件中客戶和聯(lián)系人都要設置級聯(lián)屬性 只是試試
     */
    @Test
    public void testSave2() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            
            Customer customer = new Customer();
            customer.setName("客戶一");
            customer.setAttr("北京");
            
            LinkMan linkMan = new LinkMan();
            linkMan.setName("聯(lián)系人一");
            linkMan.setTel("3333333333");
            LinkMan linkMan2= new LinkMan();
            linkMan2.setName("聯(lián)系人二");
            linkMan2.setTel("865432222");
            
            customer.getLinkMans().add(linkMan);
            customer.getLinkMans().add(linkMan2);
            linkMan.setCustomer(customer);
            linkMan2.setCustomer(customer);
            
            session.save(linkMan);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 級聯(lián)查詢操作
     */
    @Test
    public void testSelect() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            
//          Customer customer = session.get(Customer.class, 9);
//          System.out.println(customer);
//          Set<LinkMan> linkMans = customer.getLinkMans();
//          for (LinkMan linkMan : linkMans) {
//              System.err.println(linkMan);
//          }
            LinkMan linkMan = session.get(LinkMan.class, 2);
            System.out.println(linkMan);
            System.out.println(linkMan.getCustomer());

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 級聯(lián)刪除
     */
    @Test
    public void testDelete() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
                        
//          LinkMan linkMan = session.get(LinkMan.class, 6);
//          session.delete(linkMan);

            Customer customer = session.get(Customer.class, 6);
            session.delete(customer);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 級聯(lián)修改 直接操作實體類就可以
     */
    @Test
    public void testUpdate() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            /**
             * 在這里如果設置了雙向級聯(lián)修改時會出現(xiàn)對外鍵進行兩次修改电抚,這是雙向維護外鍵導致的,這樣的效率就不高 
             * 推薦在客戶中設置inverse="true"讓其放棄對外鍵的維護竖共,解決修改時會修改兩次外鍵 
             */
            Customer customer = session.get(Customer.class, 9);
            
            LinkMan linkMan = session.get(LinkMan.class, 2);
            LinkMan linkMan2 = session.get(LinkMan.class, 7);
            // 因為放棄了客戶對外鍵的維護 這里要更新聯(lián)系人
            linkMan.setCustomer(customer);          
            linkMan2.setCustomer(customer);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 級聯(lián)保存
     */
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            
            Customer customer = new Customer();
            customer.setName("客戶一");
            customer.setAttr("地址");
            
            LinkMan linkMan = new LinkMan();
            linkMan.setName("聯(lián)系人一");
            linkMan.setTel("55555555");
            LinkMan linkMan2= new LinkMan();
            linkMan2.setName("聯(lián)系人二");
            linkMan2.setTel("9999999999");
            
            customer.getLinkMans().add(linkMan);
            customer.getLinkMans().add(linkMan2);
            
            session.save(customer); // 客戶要設置級聯(lián)屬性為save-update才能成功保存
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
}

XMl配置中set標簽的inverse屬性值
?? inverse="false" 默認 不放棄級聯(lián)
?? inverse="true" 放棄級聯(lián)
好處在進行update操作時可以提高效率減少一次數(shù)據(jù)庫操作

第二節(jié) 多對多映射列表(XML)

多對多使用的人和角色的關系舉例蝙叛,即一個人可以同時有多個角色,一個角色同時可以是多個人的公给。

  • 創(chuàng)建人實體類 Man.java
package cn.lkangle.entity;

import java.util.HashSet;
import java.util.Set;

public class Man {
    private Integer man_id;
    private String man_name;
    private String man_attr;
    
    private Set<Role> roles = new HashSet<>();
    ...
}
  • 創(chuàng)建角色實體類 Role.java
package cn.lkangle.entity;

import java.util.HashSet;
import java.util.Set;

public class Role {
    private Integer role_id;
    private String role_name;
    
    private Set<Man> mans = new HashSet<>();
    ...
}
  • XML映射配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
          
<hibernate-mapping>
    <!-- 多對多用戶映射配置 -->
    <class name="cn.lkangle.entity.Man" table="t_man">
        <id name="man_id" column="man_id">
            <generator class="native"></generator>
        </id>
        <property name="man_name" column="man_name"></property>
        <property name="man_attr" column="man_attr"></property>
        
        <set name="roles" table="mans_role" cascade="save-update,delete">
            <key column="man_id_3"></key>
            <many-to-many class="cn.lkangle.entity.Role" column="role_id_3"></many-to-many>
        </set>
    </class>
    
    <!-- 多對多角色映射配置 -->
    <class name="cn.lkangle.entity.Role" table="t_role">
        <id name="role_id" column="role_id">
            <generator class="native"></generator>
        </id>
        <property name="role_name"></property>
        
        <set name="mans" table="mans_role">
            <key column="role_id_3"></key>
            <many-to-many class="cn.lkangle.entity.Man" column="man_id_3"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
 set集合屬性 
         table: 第三個表的表名
         
         key屬性
         column: 本表外鍵在第三張表中的字段名
         
         many-to-many屬性
         class: 另一個實體類的路徑
         column: 另一個表外鍵在第三張表中的字段名

兩個實體類的配置對應關系如圖:

  • 多對多的CRUD操作
package cn.lkangle.threeday;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.lkangle.entity.Man;
import cn.lkangle.entity.Role;
import cn.lkangle.util.HbmUtil;

public class ManyToMany {
    /**
     * 查詢
     */
    @Test
    public void testManySelect() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 2);
            System.out.println(man);
            
            Set<Role> roles = man.getRoles();
            for (Role role : roles) {
                System.out.println(role);
            }
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 修改 通過維護第三張表實現(xiàn)
     */
    @Test
    public void testManyUpdate() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 2);
            
            Role role = session.get(Role.class, 3);
            man.getRoles().add(role);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 直接性級聯(lián)刪除 不推薦
     */
    @Test
    public void testManyDelete0() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 1);
            
            session.delete(man);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 刪除 通過維護第三張表實現(xiàn)
     */
    @Test
    public void testManyDelete() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 1);
            Role role = session.get(Role.class, 1);
            
            man.getRoles().remove(role);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 多對多級聯(lián)保存
     */
    @Test
    public void testMany() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = new Man();
            man.setMan_name("嚴老");
            man.setMan_attr("兔斯基");
            Man man2 = new Man();
            man2.setMan_name("葉老");
            man2.setMan_attr("土耳其");
            
            Role role = new Role();
            role.setRole_name("老板");
            Role role2 = new Role();
            role2.setRole_name("秘書");
            Role role3 = new Role();
            role3.setRole_name("保安");
            
            man.getRoles().add(role);
            man.getRoles().add(role2);
            man2.getRoles().add(role);
            man2.getRoles().add(role3);
            
            session.save(man);
            session.save(man2);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
}

實話我還沒寫過用到相關操作的項目借帘、、淌铐、數(shù)據(jù)庫也沒系統(tǒng)學習過對此感覺很是生疏肺然,看過教程也就會這一些基礎的知識,更細節(jié)深入的知識還需要以后繼續(xù)學習~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末腿准,一起剝皮案震驚了整個濱河市际起,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吐葱,老刑警劉巖街望,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唇撬,居然都是意外死亡它匕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門窖认,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豫柬,“玉大人,你說我怎么就攤上這事扑浸∩崭” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵喝噪,是天一觀的道長础嫡。 經常有香客問我,道長,這世上最難降的妖魔是什么榴鼎? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任伯诬,我火速辦了婚禮,結果婚禮上巫财,老公的妹妹穿的比我還像新娘盗似。我一直安慰自己,他們只是感情好平项,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布赫舒。 她就那樣靜靜地躺著,像睡著了一般闽瓢。 火紅的嫁衣襯著肌膚如雪接癌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天扣讼,我揣著相機與錄音缺猛,去河邊找鬼。 笑死椭符,一個胖子當著我的面吹牛枯夜,可吹牛的內容都是我干的。 我是一名探鬼主播艰山,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咏闪!你這毒婦竟也來了曙搬?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤鸽嫂,失蹤者是張志新(化名)和其女友劉穎纵装,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體据某,經...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡橡娄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了癣籽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挽唉。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筷狼,靈堂內的尸體忽然破棺而出瓶籽,到底是詐尸還是另有隱情,我是刑警寧澤埂材,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布塑顺,位于F島的核電站,受9級特大地震影響俏险,放射性物質發(fā)生泄漏严拒。R本人自食惡果不足惜扬绪,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裤唠。 院中可真熱鬧挤牛,春花似錦、人聲如沸巧骚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劈彪。三九已至竣蹦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沧奴,已是汗流浹背痘括。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留滔吠,地道東北人纲菌。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像疮绷,于是被迫代替她去往敵國和親翰舌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理冬骚,服務發(fā)現(xiàn)椅贱,斷路器,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • (一)Struts舍悯、Spring航棱、Hibernate、Mybatis框技術 1.Struts2.0有幾種標簽庫 【...
    獨云閱讀 3,240評論 0 62
  • 1. Java基礎部分 基礎部分的順序:基本語法萌衬,類相關的語法丧诺,內部類的語法,繼承相關的語法奄薇,異常的語法驳阎,線程的語...
    子非魚_t_閱讀 31,624評論 18 399
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評論 6 342
  • C++基礎 重載 哪些運算符可以被重載:::,.,->,*,?:不能被重載 重載操作符的標志(operator) ...
    I踏雪尋梅閱讀 209評論 0 2