美文网首页
hibernate 一对一

hibernate 一对一

作者: siriusing | 来源:发表于2017-10-30 16:31 被阅读24次
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指定关联类的一个属性,来对应自己,意思是: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();
        
    
    }

这里主要的问题是,他不级联查

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=?

结论: one-to-one 标签修饰后,他是主动选择每次查询都用join的,这里因为一对一不需要考虑数据集太大的问题;


@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">
                <!-- 主键根据哪个一属性对应的表来生成,这里是属性名,切记 -->
                <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();
            
    }

结果:

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

2.2.1级联添加

        <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 更新

删掉级联,继续
考虑更新

    @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();
    
    }

结果只删除了address,因为没有设级联

2.3.1 级联删除

添加级联

<!--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=?

相关文章

  • hibernate笔记-关联关系

    hibernate 关联关系主要有一对一,一对多,多对多 一对一关联 一对一关联包括: 主键关联 唯一外键关联 主...

  • hibernateQuery

    hibernate中的对应关系 一对一对应关系 人与身份证之间的关系就是一对一关系 类中一对一关系的体现 hibe...

  • Hibernate One-To-One Mapping

    Hibernate 一对一映射关系(唯一外键映射) 用户基本信息与扩展信息的映射关系 我们先来看看这一对一映射可以...

  • hibernate 一对一

    1.0 基于外键的一对一 说白了,其实是一种特殊的一对多,多个person对一个address,但是person必...

  • Hibernate级联

    掌握级联的含义: *级联是对象之间的连锁操作,它只影响添加、删除和修改 hibernate一对一主键关联映射(单向...

  • mybatis的association以及collection的

    前言: 在项目中,某些实体类之间肯定有关键关系,比如一对一,一对多等。在hibernate 中用one to on...

  • Hibernate_6 一对一

    外键一对一 通俗上讲就是在一张表中设置一个外键对应另一张表的主键 实现方法 对于基于外键的1-1关联,其外键可以存...

  • 关于hibernate 3 配置one-to-one 单向关联出

    最近需要增加业务,需要增加一对一关联,由于系统采用hibernate3,而且使用了xml配置方式,所以就举例一下x...

  • Hibernate映射(一对多)

    Hibernate映射关系其实有很多种,包含一对一,一对多,多对一,多对多。其中,还有包含单向关联,多想关联。但是...

  • 【Java中级】5.0 SSH之Hibernate框架(一)——

    1.0 Hibernate框架学习路线 Hibernate入门包括Hibernate的环境搭建、Hibernate...

网友评论

      本文标题:hibernate 一对一

      本文链接:https://www.haomeiwen.com/subject/bpoppxtx.html