<tbody id="d1jhg"></tbody><th id="d1jhg"><track id="d1jhg"></track></th>
    <nav id="d1jhg"></nav>
  • <em id="d1jhg"></em>
  • <th id="d1jhg"><pre id="d1jhg"><sup id="d1jhg"></sup></pre></th>

  • <em id="d1jhg"></em>
    <em id="d1jhg"><acronym id="d1jhg"></acronym></em><dd id="d1jhg"><noscript id="d1jhg"></noscript></dd>

    Hibernate(或其它ORM)里的inverse用法

    小編:管理員 43閱讀 2022.09.05

    Inverse的英文含義是反轉,在Hibernate中用來決定是由哪方來維護兩個業務實體類之間的關聯關系,具體而言,就是由哪方去設置這個被外鍵約束的字段值。

    它的默認值是false,也就是說,本端(比如inverse=false寫在學生端,那么本端是學生,另外一方是課程)不“反轉控制權”,這句別扭的話的另外一種說法是,本端維護關聯關系。如果兩邊都不寫,那么兩端都維護。這樣會造成問題,即新時因為兩端都控制關系,因此可能會導致重復更新。

    注意,inverse僅僅是指定由誰來設置外鍵值,而不是用來設置級聯操作,級聯操作的方式由cascade來負責,很多人會混淆它們的含義和用法。

    這個例子所用到的數據表是Person表和Card表,其中Person表里包含ID、Name和Phone字段,而Card表里包含了CardID、PersonID、Bank和balance四個字段。

    在hibernate.cfg.xml文件里,通過mapping resource來指定對應的映射文件,其中關鍵的代碼如下:

    1	<!-- 添加實體類的映射文件-->
    2	<mapping resource="Model/Card.hbm.xml" />
    3	<mapping resource="Model/Person.hbm.xml" />
    復制

    在Person.hbm.xml里,用如下代碼來指定人(一方)和卡(多方)的關系,其中在人這一端,inverse是true。

    1	<set name="cards" cascade="save-update" inverse="true">
    2	<key column="PersonID"/>
    3	<one-to-many class="Card"/>
    4	</set>
    復制

    在HibernateMain.java里,通過如下關鍵代碼插入了一個人的信息。

    1	//創建一張卡
    2	Card card1 = new Card();
    3	        card1.setCardID("Card123");
    4	        card1.setPersonID("Person123");
    5	        card1.setBank("Citi");
    6	        card1.setBalance(100f);
    7	//初始化一個人
    8	        Person person = new Person();
    9	        person.setID("Person123");
    10	        person.setName("Peter");
    11	        person.setPhone("123456");
    12	//在cards這個set里加入card1
    13	        Set<Card> cards = new HashSet<Card>();
    14	        cards.add(card1);
    15	        person.setCards(cards);
    16	//保存人的信息
    17	        session.save(person);
    18	        session.flush();
    復制

    運行后,在輸出信息里能看到如下兩條相關的插入語句:一條是插入Person信息,另一條是插入card信息。

    1     Hibernate: insert into Person (Name, Phone, ID) values (?, ?, ?)

    2     Hibernate: insert into Card (PersonID, Bank, Balance, Person, CardID) values (?, ?, ?, ?, ?)

    當把person.hbm.xml里的inverse設置成false時,能看到相關的語句里會多出一句update語句。

    1     Hibernate: insert into Person (Name, Phone, ID) values (?, ?, ?)

    2     Hibernate: insert into Card (PersonID, Bank, Balance, Person, CardID) values (?, ?, ?, ?, ?)

    3     Hibernate: update Card set PersonID=? where CardID=?

    原因是,當設置inverse為true時,Person這一端反轉外鍵控制權,也就是由Card這端來管理外鍵,而在代碼里我們僅僅是插入了Person,沒有插入Card,所以就沒有更新兩個外鍵(PersonID和CardID)的操作。相反,當inverse為false時,管理外鍵控制權是在Person端,那么當插入Person時,Hibernate就需要額外的一句update語句來管理外鍵了。

    在一對多的例子里,inverse不論取什么值,對結果都沒有影響,所以很容易讓人忽視它的作用。

    在一對多的例子里,一般是讓多方來管理外鍵控制權,比如一個人有100張開,那么如果由Person方來管理的話,無形中可能會多出100個update操作,效率上就不大好了。

    如果在一對多案例中,inverse只是影響效率的話,那么在多對多的例子中,inverse的設置就可能影響到數據。

    我們再來看個多對多的學生選課案例,其中一個學生可以選多門課,而一門課里可以有多個學生。在Student.hbm.xml里,描述多對多關系的語句里可加上inverse=“true”的語句。

    1	<set name="courses" table="students_courses" inverse= "true" cascade="save-update">
    2	<key column="student_id"></key>
    3	<many-to-many class="Model.Course" column="course_id"></many-to-many>
    4	</set>
    復制

    在Course.hbm.xml里,不加任何關于inverse的語句,也就是說,在Student端反轉外鍵控制權,把控制權交到Course端。

    在HibernateMain這個類里,通過如下代碼讓s1學生選修計算機課程。

    1	        //設置一個學生,學號是1
    2	Student s1 = new Student();
    3	        s1.setStudentID("1");
    4	        s1.setStudentName("Peter");
    5	//設置多個課程
    6	        Course c1 = new Course();
    7	        c1.setCourseID("c1");
    8	        c1.setCourseName("Math");
    9	        Course c2 = new Course();
    10	        c2.setCourseID("c2");
    11	        c2.setCourseName("Java");
    12	        Course c3 = new Course();
    13	        c3.setCourseID("c3");
    14	        c3.setCourseName("C#");
    15	//設置計算機課程這個Set
    16	        Set<Course> computerCourses = new HashSet<Course>();
    17	        computerCourses.add(c2);
    18	        computerCourses.add(c3);
    19	//讓s1這個學生選修計算機課程(也就是c2和c3課程)
    20	        s1.setCourses(computerCourses);
    21	//保存s1
    22	        session.save(s1);
    23	        session.flush();
    復制

    執行結果是,雖然能在Student和Course表里看到相關的學生和課程的記錄,但在關鍵的描述學生選課關聯表(students_courses)里,看不到任何關聯記錄。原因是已經通過設置inverse把外鍵管理權交給Course方了,這里僅僅是保存學生,并沒有保存課程,所以沒有插入外鍵的動作。如果要在students_courses表里插入外鍵關聯,就需要在person.hbm.xml里設置inverse的值為false。

    所以,在多對多關聯里,設置錯了inverse值會導致結果出錯,請大家根據具體項目的情況適當設值。

    關聯標簽:
    国产亚洲无线码在软件线,国产女人18毛一级毛片,亚洲中文综合手机版在线,国产另类综合一区导航,亚洲va韩国va欧美va久久下载,久久先锋男人资源网站
    费县咖啡有限公司 遂昌县果仁有限公司 龙游县花木有限公司 泰顺县餐饮有限公司 阳谷县坚果有限公司 汶上县干草有限公司
    五莲县牲畜有限公司 安康市干草有限公司 广汉市花木有限公司 长兴县藤苇有限公司 淳安县藤苇有限公司 宁阳县设计有限公司
    天水市木炭有限公司 龙泉市花木有限公司 桐庐县木炭有限公司 榆林市藤苇有限公司 曹县牲畜有限公司 华蓥市藤苇有限公司