hibernate 一對一

public class Person {

    private Integer pid;
    private String name;
    private Address address;
    ...
}
----------------------------------------
public class Address {
    private Integer aid;
    private String name;
    private Person person;
    ...

}

 

1.0 基于外鍵的一對一


<?xml version="1.0" encoding="UTF-8"?>
<!-- Person.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
    <class name="Person" table="t_Person"  >
    
        <id name="pid" column="pid">
            <generator class="native"></generator>
        </id>
        <property name="name"></property>

        <many-to-one name="address" class="Address" column="aid" unique="true"></many-to-one>
    </class>

</hibernate-mapping>




<?xml version="1.0" encoding="UTF-8"?>
<!-- Address.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
    <class name="Address" table="t_Address"  >
    
        <id name="aid" column="aid">
            <generator class="native"></generator>
        </id>
        <property name="name"></property>

        <!-- property-ref指定關聯(lián)類的一個屬性,來對應自己,意思是:person的address指向我 -->
        <one-to-one name="person" property-ref="address" class="Person"/>
    </class>

</hibernate-mapping>


mysql> show create table t_person;
+----------+--------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------+
| Table    | Create Table
                                   |
+----------+--------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------+
| t_person | CREATE TABLE `t_person` (
  `pid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `aid` int(11) DEFAULT NULL,
  PRIMARY KEY (`pid`),
  UNIQUE KEY `aid` (`aid`),
  KEY `FK41C0D9A019FE94E7` (`aid`),
  CONSTRAINT `FK41C0D9A019FE94E7` FOREIGN KEY (`aid`) REFERENCES `t_address` (`a
id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+--------------------------------------------------------------------

說白了,其實是一種特殊的一對多,多個person對一個address,但是person必須不重復

1.1添加


@Test
    public void add(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Person p=new Person("好人劉強東");
        
        Address a=new Address("中關村"); 
        
        p.setAddress(a);
        

        session.save(p);
        session.save(a);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
            
    }

1.2查找

    @Test
    public void find(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Person p=(Person) session.get(Person.class, 1);
        
//      System.out.println(p.getAddress());
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
        
    
    }

這里主要的問題是,他不級聯(lián)查

Hibernate: 
    select
        person0_.pid as pid1_0_,
        person0_.name as name1_0_,
        person0_.aid as aid1_0_ 
    from
        t_Person person0_ 
    where
        person0_.pid=?

通過另一端address來查,

    @Test
    public void findByAddress(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Address a=(Address) session.get(Address.class, 1);
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
        
    }

Hibernate: 
    select
        address0_.aid as aid0_1_,
        address0_.name as name0_1_,
        person1_.pid as pid1_0_,
        person1_.name as name1_0_,
        person1_.aid as aid1_0_ 
    from
        t_Address address0_ 
    left outer join
        t_Person person1_ 
            on address0_.aid=person1_.aid 
    where
        address0_.aid=?

結(jié)論: one-to-one 標簽修飾后,他是主動選擇每次查詢都用join的,這里因為一對一不需要考慮數(shù)據(jù)集太大的問題;


@Test
    public void update(){

        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Address a=(Address) session.get(Address.class, 1);
        a.getPerson().setName("劉強東");
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
    
    }

Hibernate: 
    select
        address0_.aid as aid0_1_,
        address0_.name as name0_1_,
        person1_.pid as pid1_0_,
        person1_.name as name1_0_,
        person1_.aid as aid1_0_ 
    from
        t_Address address0_ 
    left outer join
        t_Person person1_ 
            on address0_.aid=person1_.aid 
    where
        address0_.aid=?
Hibernate: 
    update
        t_Person 
    set
        name=?,
        aid=? 
    where
        pid=?

1.3刪除

    @Test
    public void deleteByAddress(){

        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Address a=(Address) session.get(Address.class, 1);
        
        session.delete(a);
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
    
    }

這里會出錯,正確的方法:

@Test
    public void deleteByPerson(){

        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Person p=(Person)session.get(Person.class, 1);
        
        session.delete(p);
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
    
    }
    

主要是因為:

2.0 同步主鍵式的一對一


<?xml version="1.0" encoding="UTF-8"?>
<!-- Address.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
    <class name="Address" table="t_Address"  >
    
        <id name="aid" column="aid">
            <generator class="foreign">
                <!-- 主鍵根據(jù)哪個一屬性對應的表來生成,這里是屬性名,切記 -->
                <param name="property">person</param>
            </generator>
        </id>
        <property name="name"></property>
        <!--
            constrained: 約束
            name:依然是屬性名
         -->
        <one-to-one name="person" constrained="true"/>
    </class>

</hibernate-mapping>


<?xml version="1.0" encoding="UTF-8"?>
<!-- Person.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
    <class name="Person" table="t_Person"  >
    
        <id name="pid" column="pid">
            <!-- 由這里提供主鍵 -->
            <generator class="native"></generator>
        </id>
        <property name="name"></property>

        <one-to-one name="address"/>
    </class>

</hibernate-mapping>

2.1 添加


@Test
    public void add(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Person p=new Person("好人劉強東");
        
        Address a=new Address("中關村"); 
        
        a.setPerson(p);
        p.setAddress(a);
        
        session.save(p);
        session.save(a);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
            
    }

結(jié)果:

Hibernate: 
    insert 
    into
        t_Person
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_Address
        (name, aid) 
    values
        (?, ?)

2.2.1級聯(lián)添加

        <one-to-one name="address" cascade="all"/>
    @Test
    public void add(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Person p=new Person("好人劉強東");
        
        Address a=new Address("中關村"); 
        
        a.setPerson(p);
        p.setAddress(a);
        
        session.save(p);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
            
    }

Hibernate: 
    insert 
    into
        t_Person
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_Address
        (name, aid) 
    values
        (?, ?)

2.2 更新

刪掉級聯(lián),繼續(xù)
考慮更新

    @Test
    public void updateByAddress(){

        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Address a=(Address) session.get(Address.class, 1);
        a.getPerson().setName("劉強東");
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
    
    }
    
Hibernate: 
    select
        address0_.aid as aid0_0_,
        address0_.name as name0_0_ 
    from
        t_Address address0_ 
    where
        address0_.aid=?
Hibernate: 
    select
        person0_.pid as pid1_1_,
        person0_.name as name1_1_,
        address1_.aid as aid0_0_,
        address1_.name as name0_0_ 
    from
        t_Person person0_ 
    left outer join
        t_Address address1_ 
            on person0_.pid=address1_.aid 
    where
        person0_.pid=?
Hibernate: 
    update
        t_Person 
    set
        name=? 
    where
        pid=?

2.3 刪除

    @Test
    public void deleteByAddress(){

        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Address a=(Address) session.get(Address.class, 1);
        
        session.delete(a);
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
    
    }

結(jié)果只刪除了address,因為沒有設級聯(lián)

2.3.1 級聯(lián)刪除

添加級聯(lián)

<!--person-->
        <one-to-one name="address" cascade="all"/>
public void deleteByPerson(){

        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Person p=(Person)session.get(Person.class, 1);
        
        session.delete(p);
        
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
    
    }
Hibernate: 
    select
        person0_.pid as pid1_1_,
        person0_.name as name1_1_,
        address1_.aid as aid0_0_,
        address1_.name as name0_0_ 
    from
        t_Person person0_ 
    left outer join
        t_Address address1_ 
            on person0_.pid=address1_.aid 
    where
        person0_.pid=?
Hibernate: 
    delete 
    from
        t_Address 
    where
        aid=?
Hibernate: 
    delete 
    from
        t_Person 
    where
        pid=?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容