Hibernate的一对一映射(八)

简介: Hibernate的一对一映射(八)

一. Hibernate的一对一映射的使用范围


在Hibernate开发中,一对一的映射虽然使用的少,不如一对多和多对多运用的多,但还是有使用的。 如,如果用户的个人资料太多,可以将用户的重要资料放在一起,私人资料放在一起,即将个人资料进行拆分,而重要资料与私人资料是要进行一对一的关联的。如,用户与个人的住址方式也是一对一的,用户与银行卡也是一对一的,(有一个用户表,银行卡表,这两个表之间也是一对一的),还有最常用举例的,用户与身份证号也是一对一的。


其中一对一映射,有两种方式,一种是共用同一个Id,另外一种是外键映射。


二. 共用Id映射详细步骤


这是简单的使用,用户与身份证号进行相应的举例。按照第一章的方式

的创建相应的工程,搭建Hibernate开发的环境。为User类和IdCard类


二.一 User类和User.hbm.xml的创建


User.java


package com.yjl.pojo;
/**
 @author: yuejl
 @date: 2018年10月21日 下午12:40:04
 @Description 类的相关描述
*/
public class User {
  /**
   * @param id 标识符Id
   * @param userName 用户名
   * @param password 密码
   * @param description 描述
   */
  private Integer id;
  private String userName;
  private String password;
  private String description;
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
}


User.hbm.xml


<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入相应的约束 -->
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.yjl.pojo" >
  <!-- 具体的实体类 -->
  <class name="User" table="user" lazy="true">
    <!-- 主键 -->
    <id name="id" column="id">
      <generator class="native"></generator>  
    </id>
    <!-- 其余属性 -->
    <property name="userName"></property>
    <property name="password"></property>
    <property name="description"></property>
  </class>
</hibernate-mapping>


二. IdCard类和IdCard.hbm.xml的创建


IdCard.java


package com.yjl.pojo;
/**
 @author: yuejl
 @date: 2018年10月21日 下午12:41:47
 @Description 类的相关描述
*/
public class IdCard {
  /**
   * @param uid 身份证唯一标识符
   * @param idNum 身份证标识符
   */
  private Integer uid;
  private String idNum;
  public Integer getUid() {
    return uid;
  }
  public void setUid(Integer uid) {
    this.uid = uid;
  }
  public String getIdNum() {
    return idNum;
  }
  public void setIdNum(String idNum) {
    this.idNum = idNum;
  }
}


IdCard.hbm.xml


<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入相应的约束 -->
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.yjl.pojo" >
  <!-- 具体的实体类 -->
  <class name="IdCard" table="idCard">
    <!-- 主键 -->
    <id name="uid" column="uid">
      <!--这里应该是外键映射-->
      <generator class="native"></generator>  
    </id>
    <!-- 其余属性 -->
    <property name="idNum"></property>
  </class>
</hibernate-mapping>


二.三 在类中添加属性映射


在User.java类中,需要有一个属性来包括IdCard类的对象,即在User.java中添加一个IdCard对象的引用。是一对一的引用。


User.java中添加:


//添加IdCard的一对一的引用
  private IdCard card;
  public IdCard getCard() {
    return card;
  }
  public void setCard(IdCard card) {
    this.card = card;
  }


二.四 在User.hbm.xml中添加相对应的属性映射


    <!-- 添加与IdCard的一对一映射 -->
    <one-to-one name="card" class="com.yjl.pojo.IdCard"></one-to-one>


二.五 在IdCard类中添加User对象引用


//添加对User对象的引用
  private User user;
  public User getUser() {
    return user;
  }
  public void setUser(User user) {
    this.user = user;
  }


二.六 在IdCard.hbm.xml中修改主键生成策略为外键,添加一对一映射


<hibernate-mapping package="com.yjl.pojo" >
  <!-- 具体的实体类 -->
  <class name="IdCard" table="idCard">
    <!-- 主键 -->
    <id name="uid" column="uid">
      <!--添加外键-->
      <generator class="foreign">
        <param name="property">user</param>
      </generator>  
    </id>
    <!-- 其余属性 -->
    <property name="idNum"></property>
    <!-- 添加User对象的一对一的引用   修改constrained 约束为true-->
    <one-to-one name="user" class="com.yjl.pojo.User" constrained="true"></one-to-one>
  </class>
</hibernate-mapping>


二.七 在hibernate.cfg.xml中添加这两个约束文件


<!-- 引入相应的约束文件  ctrl点击时可以正确进入-->
    <mapping resource="com/yjl/pojo/User.hbm.xml"/>
    <mapping resource="com/yjl/pojo/IdCard.hbm.xml"/>


二.八 测试插入


@Test
  public void saveTest(){
    //1  得到Session对象
    Session session=HibernateUtil.getSession();
    //2 打开事务
    Transaction tran=session.beginTransaction();
    //3 实例化User对象
    User user=new User();
    user.setUserName("两个蝴蝶飞");
    user.setDescription("一个简单的程序员");
    //4 实际化IdCard对象
    IdCard idCard=new IdCard();
    idCard.setIdNum("411421**********");
    //5 设置对应关系
    user.setCard(idCard);
    idCard.setUser(user);
    //6 保存对象
    session.save(idCard);
    session.save(user);
    //7 提交事务
    tran.commit();
    //8 关闭session
    session.close();
  }


20181020195217475.png


20181021132619898.png


添加约束:


20181021132646964.png


后面就是两条插入语句,insert 语句.

生成的数据表中均有两个数据:


2018102113275640.png


20181021132812695.png


两者的Id是相同的。


二.九 由用户查询身份证测试


/**
   * 由用户查询相应的身份证
   */
  @Test
  public void selectTest1(){
    //1  得到Session对象
    Session session=HibernateUtil.getSession();
    //2 得到User对象
    User user=session.get(User.class,1);
    System.out.println("姓名为:"+user.getUserName());
    //3 得到关联的对象
    IdCard idCard=user.getCard();
    System.out.println("身份证为:"+idCard.getIdNum());
  }


先执行一条外键修改操作:


20181021133034133.png


再执行查询操作:


20181021133051734.png


二.十 由身份证查询用户


/**
   * 由身份证查询相应的相对应的用户
   */
  @Test
  public void selectTest2(){
    //1  得到Session对象
    Session session=HibernateUtil.getSession();
    //2 得到IdCard对象
    IdCard idCard=session.get(IdCard.class,1);
    System.out.println("身份证为:"+idCard.getIdNum());
    //3 得到关联的用户对象
    User user=idCard.getUser();
    System.out.println("姓名为:"+user.getUserName());
  }


这里,先修改外键,然后查询


20181021133343448.png


关联查询,查询出用户的信息


20181021133406312.png


这种方式,每次都要修改外键,造成效率低。而且,如果一旦修改id的话,如将IdCard表中的id进行修改的话,是没有任何现象可以查的。因为,生成的表,实际上是没有任何外键关联的。


20181021133607658.png


2018102113362722.png


这个外键,只是Hibernate自己进行相应的约束,并不是体现在真正的数据库表的。所以一般采用真正的外键约束,也就是第二种方式.


三. 外键约束的一对一详细配置


这种方式的一对一配置,实际上就是一对多的配置,只是多的这一方设置unique=“true”,即是唯一的。多的一方唯一,那么这是一对一了。


外键约束的一对一配置,与上面的基本是相同的,只是相应的配置不一样,即User.hbm.xml与IdCard.hbm.xml有一些不同而已。


将生成的user表与idcard表进行删除。


将User.hbm.xml进行修改为


<hibernate-mapping package="com.yjl.pojo" >
  <!-- 具体的实体类 -->
  <class name="User" table="user" lazy="true">
    <!-- 主键 -->
    <id name="id" column="id">
      <generator class="native"></generator>  
    </id>
    <!-- 其余属性 -->
    <property name="userName"></property>
    <property name="password"></property>
    <property name="description"></property>
    <!-- 添加与IdCard的一对一映射  添加unique为true-->
    <many-to-one name="card" class="com.yjl.pojo.IdCard" column="cardId" 
    unique="true"></many-to-one>
  </class>
</hibernate-mapping>


将IdCard.hbm.xml修改为:


<hibernate-mapping package="com.yjl.pojo" >
  <!-- 具体的实体类 -->
  <class name="IdCard" table="idCard">
    <!-- 主键 -->
    <id name="uid" column="cardId">
      <!--添加外键-->
      <generator class="native">
      </generator>  
    </id>
    <!-- 其余属性 -->
    <property name="idNum"></property>
    <!-- 添加User对象的一对一的引用  添加property-ref对应的是User类中的card属性-->
    <one-to-one name="user" class="com.yjl.pojo.User"
    property-ref="card"></one-to-one>
  </class>
</hibernate-mapping>


按照上面所给的saveTest()方法,selectTest1(),selectTest2()进行相应的测试。


saveTest()时,先进行两条创建表的操作,然后是,先删除唯一约束,然后添加唯一约束,最后添加外键。


20181021135635884.png


最后是两条插入的sql语句.


其中IdCard中没有约束,而user表中是存在着约束的:


20181021135835255.png


并且,会在user表中添加一个列,cardId的列


20181021135913369.png


selectTest1()与selectTest2(), 均可以正常的查询出来。


注意点: 有时候,只是在User.hbm.xml中添加相应的约束,而在IdCard.hbm.xml中不添加约束,即在IdCard.hbm.xml中删除这条语句


<!-- 添加User对象的一对一的引用   删除这条语句-->
    <one-to-one name="user" class="com.yjl.pojo.User"
    property-ref="card"></one-to-one>


这个时候,也是可以正确创建一对一的表的,user表中也存在着唯一索引,但是,这个时候,只能通过用户查询银行卡,即selectTest1()方法通过,是不能通过银行卡查找到相应的用户的,即selectTest2()方法不通过,会报空指向异常的。


建议,两个约束都写。


谢谢!!!

相关文章
|
11月前
|
SQL XML 存储
Hibernate框架【五】——基本映射——多对多映射
Hibernate框架【五】——基本映射——多对多映射
139 0
|
1月前
|
Java 数据库连接 数据库
Hibernate5中实体映射命名策略
Hibernate5中实体映射命名策略
62 0
|
1月前
|
SQL 存储 Java
Hibernate - 继承关联关系映射
Hibernate - 继承关联关系映射
46 0
|
1月前
|
SQL Java 数据库连接
Hibernate -双向一对一关联关系映射
Hibernate -双向一对一关联关系映射
30 0
|
11月前
|
XML 存储 Java
Hibernate框架【三】——基本映射——一对一映射
Hibernate框架【三】——基本映射——一对一映射
55 0
|
Java 数据库连接
mybatis-plus和hibernate 忽略映射字段
mybatis-plus和hibernate 忽略映射字段
254 1
|
SQL Java 数据库连接
《Hibernate上课笔记》-----class3----Hibernate的单实体映射
《Hibernate上课笔记》-----class3----Hibernate的单实体映射
100 0
|
XML Java 数据库连接
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
73 0
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
|
XML Java 数据库连接
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
53 0
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
|
存储 SQL Java
hibernate学习笔记之二(映射关系与懒加载)
hibernate学习笔记之二(映射关系与懒加载)
hibernate学习笔记之二(映射关系与懒加载)