一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

2020-05-18 12:26zhang_xinxiu JAVA教程

Hibernate想要實(shí)現(xiàn)雙向的關(guān)聯(lián)就必須在映射文件的兩端同時(shí)配置,另外還要在主映射的一端采用foreign外鍵關(guān)聯(lián)屬性,下面我們就一起來看一下Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)方法:

一、雙向主鍵關(guān)聯(lián)
雙向的主鍵關(guān)聯(lián)其實(shí)是單向一對(duì)一主鍵關(guān)聯(lián)的一種特殊情況,只不過要在關(guān)聯(lián)對(duì)象的兩端的映射文件中都要進(jìn)行<one-to-one>的配置,另外還要在主映射的主鍵一端采用foreign外鍵關(guān)聯(lián)屬性。
這里同樣使用Person和IdCard來討論,一個(gè)人對(duì)應(yīng)著一個(gè)唯一的身份證,而且一個(gè)身份證也唯一映射著一個(gè)人,所以這就產(chǎn)生了雙向的關(guān)聯(lián)關(guān)系,Person的主鍵同樣也是IdCard的主鍵,分別是主鍵的同時(shí)也是外鍵,這種關(guān)聯(lián)關(guān)系成為雙向一對(duì)一映射,表現(xiàn)到關(guān)系模型中可如下圖:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

圖中的兩個(gè)表采用了主鍵關(guān)聯(lián),person的主鍵是idCard的主鍵,所以它們之間構(gòu)成了朱外鍵的約束關(guān)系,并且保證唯一性,映射到對(duì)象模型中,轉(zhuǎn)變?yōu)閜erson類和idCard類的一對(duì)一關(guān)系,如下圖:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

這種一對(duì)一的關(guān)系上篇文章中也有講到用的是<one-to-one>標(biāo)簽,另外這種一對(duì)一映射又是雙向的,所以要在兩個(gè)對(duì)象之間同時(shí)配置<one-to-one>,首先來看idCard對(duì)應(yīng)的類代碼和映射文件代碼。

1、IdCard對(duì)應(yīng)的信息
IdCard.java類,IdCard類和Person類之間有一對(duì)一的關(guān)聯(lián)關(guān)系所以要在IdCard類中添加對(duì)應(yīng)的Person屬性,這是為了能在映射文件中的外鍵中添加對(duì)應(yīng)的屬性,設(shè)置對(duì)應(yīng)的外鍵關(guān)聯(lián)類。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.src.hibernate;
 
public class IdCard {
   
  //id屬性
  private int id;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
   
  //卡號(hào)屬性
  private String cardNo;
  public String getCardNo() {
    return cardNo;
  }
  public void setCardNo(String cardNo) {
    this.cardNo = cardNo;
  }
   
  //卡號(hào)對(duì)應(yīng)的人
  private Person person;
  public Person getPerson(){
    return person;
  }
  public void setPerson(Person person){
    this.person=person;
  }
}

IdCard.hbm.xml映射文件,在映射文件中添加外鍵屬性person,并添加對(duì)應(yīng)的<one-to-one>標(biāo)簽,目的是強(qiáng)制約束person類來實(shí)現(xiàn)一對(duì)一的映射關(guān)系,最后在映射中將constrained屬性設(shè)為true,保證強(qiáng)制約束關(guān)系。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
  <class name="com.src.hibernate.IdCard" table="IDCARD">
    <id name="id" type="int" column="personId">
      <generator class="foreign">
        <param name="property">person</param>
      </generator>
    </id>
     
    <property name="cardNo" type="string" column="cardno"></property>
    <one-to-one name="person" constrained="true"></one-to-one>
  </class>
</hibernate-mapping>

2、Person對(duì)應(yīng)的信息
Person.java類,在該類中除了添加基本的屬性外還要添加對(duì)應(yīng)的IdCard類作為屬性,因?yàn)樗鼈冎g是一對(duì)一的雙向關(guān)聯(lián)關(guān)系,所以在Person類中同樣要添加IdCard類,相同的道理IdCard類中同樣添加了Person類屬性。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.src.hibernate;
 
public class Person {
   
  //id號(hào)
  private int id;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
   
  //姓名
  private String name;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
   
  //idCard
  private IdCard idcard;
  public IdCard getIdcard() {
    return idcard;
  }
  public void setIdcard(IdCard idcard) {
    this.idcard = idcard;
  }
}

Person.hbm.xml映射文件,該文件中主鍵生成策略沒有特殊的要求,因?yàn)樗虸dCard類相互制約的關(guān)系,它的主鍵和外鍵都是IdCard的主鍵,另外因?yàn)槭且粚?duì)一關(guān)系所以要在映射文件中添加<one-to-one>標(biāo)簽來標(biāo)示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
  <class name="com.src.hibernate.Person" table="PERSON">
    <id name="id" type="int" column="personId">
      <generator class="native"></generator>
    </id>
     
    <property name="name" type="string" column="personName"></property>
  <!--
  one-to-one標(biāo)簽指示Hibernate如何加載其關(guān)聯(lián)對(duì)象,默認(rèn)根據(jù)主鍵加載,也就是拿到關(guān)系字段值,根據(jù)對(duì)端的主鍵來加載關(guān)聯(lián)對(duì)象
   -->
  <one-to-one name="idcard"></one-to-one>
  </class>
</hibernate-mapping>

3、Hibernate映射文件
上面的類和映射文件配置好后接下來要在Hibernate.cfg.xml中配置與數(shù)據(jù)庫映射的信息,需要將兩個(gè)配置文件添加到Hibernate配置文件中,這樣在生成對(duì)應(yīng)的數(shù)據(jù)庫時(shí)才能找到對(duì)應(yīng)的生成項(xiàng)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_one2one_pk1</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">1234</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
     
    <mapping resource="com/src/hibernate/Person.hbm.xml"/>
    <mapping resource="com/src/hibernate/IdCard.hbm.xml" ></mapping>
  </session-factory>
</hibernate-configuration>

 4、生成結(jié)果
配置完成后就可以將上面的內(nèi)容生成對(duì)應(yīng)的數(shù)據(jù)庫了,在數(shù)據(jù)庫中它會(huì)按照配置的內(nèi)容生成相應(yīng)的表結(jié)構(gòu),在表中有相應(yīng)的外鍵和主鍵字段。生成表結(jié)構(gòu)時(shí)Hibernate會(huì)在控制臺(tái)輸出相應(yīng)的SQL語句,如下:

?
1
2
3
4
5
6
alter table IDCARD drop foreign key FK806F76ABAC038CD8
drop table if exists IDCARD
drop table if exists PERSON
create table IDCARD (personId integer not null, cardno varchar(255), primary key (personId))
create table PERSON (personId integer not null auto_increment, personName varchar(255), primary key (personId))
alter table IDCARD add index FK806F76ABAC038CD8 (personId), add constraint FK806F76ABAC038CD8 foreign key (personId) references PERSON (personId)

生成的表結(jié)構(gòu)如下圖:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

在兩張表中同時(shí)生成了personId主鍵,并且也是相應(yīng)的外鍵,它同時(shí)限制約束了兩張表的主鍵相同且唯一。

5、寫入加載測(cè)試
生成表后測(cè)試下對(duì)表的寫入和從表中讀取數(shù)據(jù),編寫相應(yīng)的測(cè)試類,測(cè)試采用的是單元測(cè)試,編寫對(duì)應(yīng)的測(cè)試方法。
5.1 寫入測(cè)試
在寫入到數(shù)據(jù)庫時(shí)一定要注意寫入的兩個(gè)對(duì)象都要轉(zhuǎn)化到對(duì)應(yīng)的Trainent狀態(tài),否則會(huì)出現(xiàn)狀態(tài)轉(zhuǎn)化的錯(cuò)誤,測(cè)試代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void testSave1(){
  Session session=null;
  try{
    //創(chuàng)建一個(gè)會(huì)話對(duì)象
    session=HibernateUtils.getSession();
    //開啟會(huì)話事務(wù)
    session.beginTransaction();
     
    //創(chuàng)建person對(duì)象,并保存
    Person person=new Person();
    person.setName("zhangsan");
    session.save(person);
     
    //創(chuàng)建idCard對(duì)象,并保存
    IdCard idcard=new IdCard();
    idcard.setCardNo("1111111111111");
    idcard.setPerson(person);
    session.save(idcard);
     
    //提交事務(wù),修改數(shù)據(jù)庫
    session.getTransaction().commit();
     
  }catch(Exception e){
    //打印錯(cuò)誤信息
    e.printStackTrace();
    //業(yè)務(wù)回滾
    session.getTransaction().rollback();
  }finally{
    //關(guān)閉會(huì)話
    HibernateUtils.closeSession(session);
  }
}

插入的數(shù)據(jù)如下圖:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

5.2 加載測(cè)試
編寫加載方法,因?yàn)殛P(guān)聯(lián)關(guān)系是雙向的,所以相應(yīng)的加載操作應(yīng)該是通過一端加載另一端,也就是獲取對(duì)應(yīng)的Person類,并通過Person類來獲取對(duì)應(yīng)的IdCard信息,相反的也要成立,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public void testLoad1(){
  Session session=null;
  try{
    //創(chuàng)建一個(gè)會(huì)話對(duì)象
    session=HibernateUtils.getSession();
    //開啟會(huì)話事務(wù)
    session.beginTransaction();
     
    //獲取person對(duì)象,并保存
    Person person=(Person)session.load(Person.class,5);
    System.out.println("IdCard.Id: "+person.getIdcard().getId());
    System.out.println("IdCard.cardno: "+person.getIdcard().getCardNo());
     
    //創(chuàng)建idCard對(duì)象,并保存
    IdCard idcard=(IdCard)session.load(IdCard.class, 5);
    System.out.println("Person.Id: "+idcard.getPerson().getId());
    System.out.println("Person.name: "+idcard.getPerson().getName());
     
    //提交事務(wù),修改數(shù)據(jù)庫
    session.getTransaction().commit();
     
  }catch(Exception e){
    //打印錯(cuò)誤信息
    e.printStackTrace();
    //業(yè)務(wù)回滾
    session.getTransaction().rollback();
  }finally{
    //關(guān)閉會(huì)話
    HibernateUtils.closeSession(session);
  }
}

運(yùn)行上面的測(cè)試方法,在控制臺(tái)打印的相關(guān)內(nèi)容如下:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

 

二、雙向外鍵關(guān)聯(lián)
雙向的外鍵關(guān)聯(lián)可以理解為外鍵關(guān)聯(lián)的一種特殊情況,這種特殊主要是由于它是一種雙向的對(duì)應(yīng)關(guān)系,在前篇文章中提到如果想要在一張表中添加一個(gè)外鍵字段的話可以使用<many-to-one>標(biāo)簽,它會(huì)關(guān)系模型中生成對(duì)應(yīng)的外鍵列。這里想要實(shí)現(xiàn)雙向的外鍵關(guān)聯(lián)就必須使用該標(biāo)簽。
1、對(duì)象模型
先來看對(duì)象模型,人和身份證屬于一對(duì)一的關(guān)系,一個(gè)人對(duì)應(yīng)著一個(gè)身份,所以它們之間的多重性是一對(duì)一的,并且這種對(duì)應(yīng)關(guān)系是雙向的。所以它的對(duì)象模型同雙向主鍵一對(duì)一是相同的,如下圖:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

2、關(guān)系模型
對(duì)應(yīng)的關(guān)系模型會(huì)發(fā)生很大的變化,一對(duì)一的外鍵關(guān)聯(lián)關(guān)系會(huì)在一張表中生成對(duì)應(yīng)的外鍵,拿到人和身份證上來說也就是人的關(guān)系模型中會(huì)有一個(gè)身份證號(hào)的主鍵列,它們之間形成了雙向的一對(duì)一的情況,如下圖:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

它們之間的對(duì)應(yīng)關(guān)系就是上圖中看到的,person表中有idCard表的主鍵,形成了一對(duì)一的外鍵關(guān)聯(lián)關(guān)系,而且是雙向的,也就是說通過person能夠獲取到idCard,另外通過idCard也能獲取到person。
Person對(duì)象和IdCard對(duì)象內(nèi)的代碼同上篇文章中的對(duì)象代碼一致,不在做代碼羅列,唯一不同的是映射文件中的配置問題。
3、映射文件
idCard.hbm.xml映射文件,idCard表不是映射的主表,所以在做一對(duì)一的映射時(shí)需要使用的是<one-to-one>標(biāo)簽來配置,并且需要制定person關(guān)系模型中的外鍵屬性,具體代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2014-5-18 22:27:43 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
  <class name="com.src.hibernate.IdCard" table="IDCARD">
    <id name="id" type="int">
      <generator class="native" />
    </id>
    <property name="cardNo" type="java.lang.String">
      <column name="CARDNO" />
    </property>
     
    <one-to-one name="person" property-ref="idCard"></one-to-one>
  </class>
</hibernate-mapping>

Person.hbm.xml映射文件,person表是映射的主表,需要在該表中添加一個(gè)外鍵屬性列來標(biāo)示idCard表,所以這里需要使用<many-to-one>標(biāo)簽,在person對(duì)象中生成相應(yīng)的外鍵,并且還要使用unique標(biāo)明屬性唯一。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2014-5-18 22:27:43 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
  <class name="com.src.hibernate.Person" table="PERSON">
    <id name="id" type="int" column="personId">
      <generator class="native" />
    </id>
    <property name="name" type="java.lang.String">
      <column name="NAME" />
    </property>
     
    <many-to-one name="idCard" column="idCardNo" unique="true" not-null="true"></many-to-one>
  </class>
</hibernate-mapping>

對(duì)象的映射文件配置完成,接下來生成關(guān)系模型,SQL語句如下:

?
1
2
3
4
5
6
alter table PERSON drop foreign key FK8C768F55794A52CA
drop table if exists IDCARD
drop table if exists PERSON
create table IDCARD (id integer not null auto_increment, CARDNO varchar(255), primary key (id))
create table PERSON (personId integer not null auto_increment, NAME varchar(255), idCardNo integer not null unique, primary key (personId))
alter table PERSON add index FK8C768F55794A52CA (idCardNo), add constraint FK8C768F55794A52CA foreign key (idCardNo) references IDCARD (id)

生成的SQL語句首先是創(chuàng)建的表,在建表時(shí)指定了主鍵列,創(chuàng)建完成后修改了兩個(gè)表指定外鍵屬性,形成一對(duì)一的關(guān)系。

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

編寫測(cè)試方法,采用單元測(cè)試,加載兩個(gè)類的對(duì)象,并分別從對(duì)象的一端獲取另一個(gè)對(duì)象

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//加載對(duì)象,使用IdCard對(duì)象裝載person對(duì)象
public void testLoad1(){
  Session session=null;
   
  try{
    session=HibernateUtils.getSession();
    session.beginTransaction();
     
    //獲取IdCard對(duì)象,在IdCard中獲取與該對(duì)象唯一關(guān)聯(lián)的person對(duì)象
    IdCard idcard=(IdCard)session.load(IdCard.class,1);
    System.out.println("person.Id= "+idcard.getPerson().getId());
    System.out.println("idCard.person.name= "+idcard.getPerson().getName());
     
    //獲取Person對(duì)象,在Person對(duì)象中獲取與它唯一關(guān)聯(lián)的IdCard對(duì)象
    Person person=(Person)session.load(Person.class,1);
    System.out.println("idCard.id: "+person.getIdCard().getId());
    System.out.println("idCard.cardNo: "+person.getIdCard().getCardNo());
     
    //提交事務(wù)
    session.getTransaction().commit();
  }catch(Exception e){
    e.printStackTrace();
    session.getTransaction().rollback();
  }finally{
    HibernateUtils.closeSession(session);
  }
}

生成的內(nèi)容:

Java的Hibernate框架中的雙向主鍵關(guān)聯(lián)與雙向外鍵關(guān)聯(lián)

對(duì)比兩種映射關(guān)系,主鍵和外鍵兩種映射,都是雙向的映射關(guān)系,需要在對(duì)象的兩端同時(shí)配置映射關(guān)系,不同的是主鍵只需要使用<one-to-one>因?yàn)樗恍枰蓪傩粤校潜仨殞?duì)表的主鍵采用foreign的主鍵生成策略,并標(biāo)示外鍵對(duì)象;外鍵的生成策略則需要采用<many-to-one>標(biāo)簽來生成新的外鍵列。

結(jié)語
雙向關(guān)聯(lián)中的一對(duì)一映射至此已經(jīng)討論完成,兩篇文章主要討論了雙向關(guān)聯(lián)中的兩種用法,其實(shí)還是很簡(jiǎn)單的,記住一句話想要生成外鍵就使用<many-to-one>標(biāo)簽,如果唯一那就添加unique屬性,<one-to-one>標(biāo)簽只是指明了一對(duì)一的關(guān)系它只是指明一個(gè)對(duì)象如何加載另一個(gè)對(duì)象并不在關(guān)系模型中添加新列。下篇文章將會(huì)對(duì)一對(duì)多關(guān)聯(lián)展開討論。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 白丝校花好湿好紧 | 吃瓜视频在线观看 | 免费国产网站 | 探花国产 | 嫩草视频在线观看免费 | 亚洲第一成年免费网站 | 欧美男男xxx激情做受 | 成品人视频免费观看 | 免费岛国片| 免费在线公开视频 | yy6080久久国产伦理 | 亚洲视频免费 | 国内精品露脸在线视频播放 | 亚洲成人免费观看 | oneday日本在线观看完整版 | 第一福利在线视频 | 娇妻与公陈峰姚瑶最新版 | 亚洲福利电影一区二区? | 国产123区在线视频观看 | les在宿舍吃她奶 | 手机在线伦理片 | 国产精品免费拍拍拍 | 婷婷婷色| 嫩草影院永久入口在线观看 | 国产精品久久久久久影院 | 日本免费久久久久久久网站 | 精品国产免费第一区二区三区日韩 | 亚洲国产一区 | 强波多野结衣女教师 | 欧美日韩一区二区三区在线视频 | 亚洲大尺码| 暖暖在线精品日本中文 | 国人精品视频在线观看 | 无人在线视频高清免费观看动漫 | 精品久久久久久综合网 | 日韩一区二区三区不卡视频 | 午夜小视频网站 | 青视频在线 | 国语第一次处破女 | 欧美人交性视频在线香蕉 | 91久久福利国产成人精品 |