Hibernate一对一关联关系的使用

以主键关联

         关联的两个实体共享一个主键。给一个表(Student)设定主键,另个一表(Certificate)使用的是学生表的主键,即主键的foreign生成机制。

Student.hbm.xml

<class name="model.Student" table="student" lazy="true"><!--把类和数表关联起来-->

       <id name="id" unsaved-value="null"><!--id的产生方式是uuid.hex-->

           <generator class="uuid.hex" />

       </id>

       <property name="cardId" type="string" /><!--映射号-->

       <property name="name" type="string" /><!--映射学生名-->

       <property name="age" type="int" /><!--映射学生岁数-->

       <one-to-one name="cer"

           class="model.Certificate" 

           fetch="join"

           cascade="all" 

        /><!--映射对应的身分证对象-->

    </class>

Certificate.hbm.xml

<class name="model.Certificate" table="certificate" lazy="true">

       <id name="id">

       <!-- 外键生成机制,引用stu对象的主键作为certificate数据表的外键和主键 -->

           <generator class="foreign"><!-- 以主键关联 -->

              <param name="property">stu</param>

           </generator>

       </id>

       <!-- 下面的column属性加上了引号,是因为describemysql的关键字 -->

       <property name="describe" column="`describe`" type="string" />

       <one-to-one name="stu"

            class="model.Student"

            fetch="select"

            constrained="true"

            cascade="none"

       />

       <!--constrained="true" 表示certificate应用了stu的主键作为外键 -->

    </class>

一对一的关系是通过主键值得以关联的,而主键id在配置文件中已经设置过了,hibernate找到student,通过一对一关系找到certificate.hbm.xml,该配置文件中没有设置主键的列名,则默认列名为id,再去取得certificate的响应id的对象。

 

测试类:

Student stu = new Student();

      stu.setName("spark");

      stu.setCardId("200211332");

      stu.setAge(33);

 

      Certificate cer=new Certificate();

      cer.setDescribe("spark");

 

      stu.setCer(cer);

      cer.setStu(stu);

    

      StudentDAO.saveObj(stu);

控制台输出:

Hibernate: insert into student (cardId, name, age, id) values (?, ?, ?, ?)

Hibernate: insert into certificate (`describe`, id) values (?, ?)

 

以外键关联

         重点是两个实体各有不相同的主键,其中一个实体有一个外键应用了另一个实体的主键。

Student.hbm.xml

<class name="model.Student" table="student" lazy="true"><!--把类和数表关联起来-->

       <id name="id" unsaved-value="null"><!--id的产生方式是uuid.hex-->

           <generator class="uuid.hex" />

       </id>

       <property name="cardId" type="string" /><!--映射号-->

       <property name="name" type="string" /><!--映射学生名-->

       <property name="age" type="int" /><!--映射学生岁数-->

       <one-to-one name="cer" class="model.Certificate"  fetch="join" cascade="all"  /><!--映射对应的身分证对象-->

    </class>

Certificate.hbm.xml

<class name="model.Certificate" table="certificate" lazy="true">

       <id name="id">

           <generator class="uuid.hex" />

       </id>

       <property name="describe" column="`describe`" type="string" />

       <many-to-one name="stu"

           class="model.Student" 

           unique="true" <!—唯一的多对一,也就成了一对一-->

           column="stu_id"

       />

    </class>

测试类:

Student stu = new Student();

      stu.setName("spark");

      stu.setCardId("200211332");

      stu.setAge(33);

 

      Certificate cer=new Certificate();

      cer.setDescribe("spark");

 

      stu.setCer(cer);

      cer.setStu(stu);

    

      StudentDAO.saveObj(stu);

控制台输出:

Hibernate: insert into student (cardId, name, age, id) values (?, ?, ?, ?)

Hibernate: insert into certificate (`describe`, id) values (?, ?)

 

默认的级联关系:

one-to-one关联默认的级联关系是预先抓取,而一对多,多对多的默认加载策略是立即记载。

 

 

延迟加载:

one-to-one关系进行延迟加载和其他关系相比稍微不同。Many-to-one的延迟加载是在配置文件的class标签设置lazy=true”,one-to-manymany-to-many的延迟加载是在set标签中设置lazy=true”,而one-to-one不仅要在class标签设置lazy=true”,而且要在one-to-one标签中设置constrained=true

Student.hbm.xml

<class name="model.Student" table="student" ><!--把类和数表关联起来-->

       <id name="id" unsaved-value="null"><!--id的产生方式是uuid.hex-->

           <generator class="uuid.hex" />

       </id>

       <property name="cardId" type="string" /><!--映射号-->

       <property name="name" type="string" /><!--映射学生名-->

       <property name="age" type="int" /><!--映射学生岁数-->

       <one-to-one name="cer"

           class="model.Certificate"  

           cascade="all" 

       /><!--映射对应的身分证对象-->

    </class>

Certificate.hbm.xml

<class name="model.Certificate" table="certificate" lazy="true">

       <id name="id">

           <generator class="uuid.hex" />

       </id>

       <property name="describe" column="`describe`" type="string" />

       <many-to-one name="stu"

           class="model.Student" 

           unique="true"

           column="stu_id"

       />

         </class>

测试类:

StudentDAO.getById(Student.class,"5abfa70605c5356f0105c535730e0001");

控制台输出:

Hibernate: select student0_.id as id0_1_, student0_.cardId as cardId0_1_, student0_.name as name0_1_, student0_.age as age0_1_, certificat1_.id as id1_0_, certificat1_.`describe` as describe2_1_0_, certificat1_.stu_id as stu3_1_0_ from student student0_ left outer join certificate certificat1_ on student0_.id=certificat1_.id where student0_.id=?

此时在certificateclass标签中设置了lazy=true”,但是没有在studentone-to-one标签中设置constrained=true”,所以延迟加载不起作用,而是使用了默认的预先抓取策略。

 

在原来的student.hbm.xml文件做一点小改动,

    <class name="model.Student" table="student" ><!--把类和数表关联起来-->

       <id name="id" unsaved-value="null"><!--id的产生方式是uuid.hex-->

           <generator class="uuid.hex" />

       </id>

       <property name="cardId" type="string" /><!--映射号-->

       <property name="name" type="string" /><!--映射学生名-->

       <property name="age" type="int" /><!--映射学生岁数-->

       <one-to-one name="cer"

           class="model.Certificate"  

           constrained="true"

           cascade="all" 

       /><!--映射对应的身分证对象-->

    </class>

控制台输出:

Hibernate: select student0_.id as id0_0_, student0_.cardId as cardId0_0_, student0_.name as name0_0_,

student0_.age as age0_0_

from student student0_ where student0_.id=?

one-to-one关系,constrained=true 附属类的lazy=true才能实现延迟加载,并且将忽略默认的预先抓取策略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值