【SSH快速进阶】——Hibernate一对一映射(one-to-one)——主键关联映射

简介:  现实生活中,有很多场景需要用到一对一映射,比如每个学生只有一个学生证,每个公民只有一张身份证等。这里用公民-身份证来举例说明。

 现实生活中,有很多场景需要用到一对一映射,比如每个学生只有一个学生证,每个公民只有一张身份证等。这里用公民-身份证来举例说明。

43.png


 在Hibernate中实现一对一映射,有两种实现方式:1、主键关联;2、唯一外键关联,这里先说一下主键关联映射。


 主键关联映射:其中一个表的主键依赖于另一张表的主键而建立起的一对一的关系,这两张互相关联的表的主键一致。


 关联映射又可细分为单向关联映射和双向关联映射。



一对一单向关联映射


 一对一单向关联映射,即一个对象依赖另一个对象,比如根据人能找到他的身份证:


44.png



  Po对象:

  IdCard .java


public class IdCard {
    private int id;
    private String cardNo;  
    //getter、setter
}


 Person.java

public class Person {
    private int id;
    private String name;
    private IdCard idCard;
    //getter、setter
}


  映射文件:

  IdCard.hbm.xml


<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.IdCard" table="t_idCard">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="cardNo"/>
    </class>
</hibernate-mapping>


  Person.hbm.xml

<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.Person" table="t_person">
        <id name="id" type="int">
            <generator class="foreign">
                <param name="property">idCard</param>
            </generator>
        </id>
        <one-to-one name="idCard" constrained="true"/>
        <property name="name"/>
    </class>
</hibernate-mapping>


 上述配置文件中<one-to-one name="idCard" constrained="true"/>是配置一对一关联的核心,表示一个Person对应一个IdCard。constrained=”true”表示t_person表的主键上同时有个外键指向被关联的表(t_idCard)的主键,会对表t_person创建约束,约束t_person的id只能跟idCard的主键一样。


 运行程序,实际执行的sql语句如下,除了创建两张表,还为t_person表创建了约束:


alter table t_person drop foreign key FK785BED803EEB3F3E
drop table if exists t_idCard
drop table if exists t_person
create table t_idCard (id integer not null auto_increment, cardNo varchar(255), primary key (id))
create table t_person (id integer not null, name varchar(255), primary key (id))
alter table t_person add index FK785BED803EEB3F3E (id), add constraint FK785BED803EEB3F3E foreign key (id) references t_idCard (id)


 插入测试

session.beginTransaction();
IdCard idCard=new IdCard();
idCard.setCardNo("123456789");
Person person=new Person();
person.setName("danny");
person.setIdCard(idCard);
session.save(person);
session.getTransaction().commit();

 测试中,先定义idCard,person.setIdCard(idCard)之后,直接保存person,虽然session没有直接save(idCard),但是由于一对一主键关联映射的特性,必须先保存关联对象idCard,才可以保存person。所以在执行session.save(person)时,先保存的是idCard。


 可以发现执行的sql语句为:


insert into t_idCard (cardNo) values (?)
insert into t_person (name, id) values (?, ?)



  查询测试

Person person=(Person)session.load(Person.class, 1);
System.out.println("person的name:"+person.getName());
System.out.println("person的cardNo:"+person.getIdCard().getCardNo());


 实际执行的sql语句:

select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=?
select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idCard idcard0_ where idcard0_.id=?


  执行结果

person的name:danny
person的cardNo:123456789


一对一双向关联映射


  一对一双向关联映射,即两个对象互相依赖,根据人也能找到他的身份证,根据某人的身份证也能找到这个人:

45.png


  在上面的一对一单向关联映射中,根据Person可以查到IdCard,但只根据IdCard不能查询到Person,要想根据IdCard也能查询到Person,IdCard的po和配置文件也可以这么写:


  IdCard.java

public class IdCard {
    private int id;
    private String cardNo;  
    private Person person;
}


  IdCard.hbm.xml

<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.IdCard" table="t_idCard">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="cardNo"/>
        <one-to-one name="person" fetch="join"/><!-- fetch值为select时,可以实现懒加载 -->
    </class>
</hibernate-mapping>


  

IdCard.hbm.xml


<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.IdCard" table="t_idCard">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="cardNo"/>
        <one-to-one name="person" fetch="join"/><!-- fetch值为select时,可以实现懒加载 -->
    </class>
</hibernate-mapping>


  这里标签不能加constrained=”true”的原因是:如果加上后,t_person主键既依赖于t_idCard的主键,t_idCard的主键也依赖于t_person的主键,您想想,是不是就“死循环”了?

  这样在查询IdCard时,就可以顺便查出person

IdCard idCard=(IdCard)session.load(IdCard.class, 1);
System.out.println("person的cardNo:"+idCard.getCardNo());
System.out.println("person的name:"+idCard.getPerson().getName());


  执行结果:

person的cardNo:123456789
person的name:danny


  查询执行的sql语句:

select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idCard idcard0_ where idcard0_.id=?
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=?


  但是标签只影响查询,并不影响保存。比如执行下列保存时:


session.beginTransaction();
Person person=new Person();
person.setName("danny");
IdCard idCard=new IdCard();
idCard.setCardNo("123456789");          
idCard.setPerson(person);
session.getTransaction().commit();


  只会保存idCard,而不会保存person。

相关文章
|
网络安全
ssh(Spring+Spring mvc+hibernate)——DeptDaoImpl.java
ssh(Spring+Spring mvc+hibernate)——DeptDaoImpl.java
|
网络安全
ssh(Spring+Spring mvc+hibernate)——BaseDaoImpl.java
ssh(Spring+Spring mvc+hibernate)——BaseDaoImpl.java
|
存储 Java 应用服务中间件
SSH开发模式——Struts2进阶
SSH开发模式——Struts2进阶
|
网络安全
ssh(Spring+Spring mvc+hibernate)——Dept.java
ssh(Spring+Spring mvc+hibernate)——Dept.java
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
468 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
网络安全
ssh(Spring+Spring mvc+hibernate)——showDept.jsp
ssh(Spring+Spring mvc+hibernate)——showDept.jsp
|
网络安全
ssh(Spring+Spring mvc+hibernate)——applicationContext.xml
ssh(Spring+Spring mvc+hibernate)——applicationContext.xml
|
网络安全
ssh(Spring+Spring mvc+hibernate)——EmpController
ssh(Spring+Spring mvc+hibernate)——EmpController
|
前端开发 Java 网络安全
ssh(Spring+Spring mvc+hibernate)简单增删改查案例
ssh(Spring+Spring mvc+hibernate)简单增删改查案例
|
安全 网络安全 数据安全/隐私保护
wsl---ssh远程连接、ip映射及服务自启详细配置
在初步体验了wsl后,我们都想通过一些类似xshell的工具来进行连接,因为cmd真的是不太友好。 在多次反复操作后发现,网上很多千篇一律的教程在有些地方,真的是误导像我这种小白,因此,本片文章经历过多次修改以保让我等小白不被带偏。
1193 0