hibernate一对一映射

hibernate一对一映射

一、建立两个对象:一个Person,一个身份证

这两个类是一对一的映射

二、建立实体之间的关系 :

1、首先从Person的角度,先看看这个人,要知道他的身分证号是什么,所以要持有一个身分证的引用。

反过来,拿到身分证的时候,要知道这个人。所以在 IdCard中要持有Person的引用。

所谓的单双向,是指从一个对象可以访问到另一个对象,从另一个对象访问不到它。而双向它们就可以互相访问了。

从Person可以看到IdCard,从IdCard可以看到Person.这叫做双向。

我们先看它的单向。

如果只看单向,则Person要持有IdCard的引用。Person IdCard这两个对象之间是有有关系的,所以有一个箭头连接两者。

所以表面看它们的关系和用户和组的关系似乎是一样的。所以必须通过映射标签才能区别两者。

hibernate一对一映射

 

2、一对一关联映射有两种:一种是主键关联,一种是外键关联。

主键关联就是我们的两个实体而生成的两个表的主键相同。也就是说,如果IdCard这个表里有一个主键是1,则Person这个表里也有一个主键是1.这样就不用加任何字段让主键一致。

主键关联不用增加字段,还是原来的字段就可以了。

因为person引用了idCard,所以idCard一定先有值。

hibernate一对一映射

 

 三、如何映射实现主键一致。

 

一、新建项目hibernate_one2one_pk_1:单向关联

二、建立实体类

1、IdCard类。

package com.bjsxt.hibernate;

public class IdCard {
 private int id;
 private String cardNo;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getCardNo() {
  return cardNo;
 }
 public void setCardNo(String cardNo) {
  this.cardNo = cardNo;
 }
 

}

2、Person.class

package com.bjsxt.hibernate;

public class Person {
 private int id;
 private String name;
 
 IdCard idCard;
 
 
 public IdCard getIdCard() {
  return idCard;
 }
 public void setIdCard(IdCard idCard) {
  this.idCard = idCard;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 

}
三、实体有了之后,要建立映射文件,将两者的关系建立起来

1、选建立简单的。就 是IdCard.hbm.xml文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.bjsxt.hibernate.IdCard" table="t_idcard" >
    <id name="id">
        <generator class="native"></generator>
    </id>
    <property name="cardNo"/>
   
 </class>
</hibernate-mapping>

 

2、映射Person,建立Person.hbm.xml文件

Person一端的主键来源于IdCard一端的主键。Person的主键以外键的形式参照IdCard的主键。

foreign主键生成策略,使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来用。Person会把IdCard的标识拿过来,它用。

<generator>

    <param name="property">idCard</pram>

</generaor>

上述含义是:在ForeignGenerator.class类中,有一个configure()方法,这个方法要读取“perperty"的值,然后再拿到值的id来用。所以name必须用property.

 <one-to-one>加载的含义是:将Person中的1与IdCard中的1对比,如果相同,则把IdCard的值拿过来。

 

 Person.hmbm.xml 文件内容如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.bjsxt.hibernate.Person"  table="t_person">
    <id name="id">
    <!--我们的应该一对一的映射,而且不能加外键
    所以主键的生成策略不能是native.因为这种方式是自 增的,就没有参照IdCard类的主键
    所以生成策略要改成foreign方式,就是参照外部的
    所以Person表的主键是不能自增的 -->
   
    <!-- 这种生成策略要加参数,名字就是peroperty.是固定的 -->
        <generator class="foreign">
            <!-- 标签中的值是指明标识来源于谁
            foreign方式,标识来源于关联对象的标识,
                             所以来源对象要指定
                             所以拿来Person类的属性idCard作为id的标识 -->
          <param name="property">idCard</param>
        </generator>
    </id>
    <property name="name"/>
   
    <!-- one-to-one指的是如何加载它的引用对象
    外键约束要设为true-->
   <one-to-one name="idCard" constrained="true"></one-to-one>
 </class>
</hibernate-mapping>

 

四、修改 hiberante.cfg.xml文件

<!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
 <session-factory >
      <!-- 数据库改成hibernate_session -->
  <property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_one2one_pk_1</property>
     <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
     <property name="hibernate.connection.username">root</property>
     <property name="hibernate.connection.password">root</property>
     <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
     <property name="hibernate.show_sql">true</property>
   
     <mapping resource="com/bjsxt/hibernate/IdCard.hbm.xml"/>
       <mapping resource="com/bjsxt/hibernate/Person.hbm.xml"/>
 </session-factory>
</hibernate-configuration>

 

五、在MysqL 中创建数据库

create database hibernate_one2one_pk_1;

user hiberante_one2one_pk_1;

六、执行ExportDB.class 文件,将对象模型导出表

package com.bjsxt.hibernate;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

//这个类写完之后,以后就再也不用写了。
//这个类就是把hibernate的配置文件,转换成DDL。
public class ExportDB {
      public static void main(String[] args){
       //读取hibernate.cfg.xml文件
       Configuration cfg=new Configuration().configure(); //hibernate中的一个api,是Configuraton。引入时,将光标定位在Configuration上
                      //右击,选择"Source"命令的"Add Import"命令,找到hibernate的Configuration。
                      //它是用来读取hibernate中的配置文件的。即hibernate.cfg.xml文件。(相当于Struts中的
                      //ActionServlet)
                      //这样直接写 Configuration cfg=new Configuration();会有问题,因为
                    //hibernate有两个配置文件,一个是property类型的,一个是xml类型的,这样
              //new完,就会默认的读取property类型的配置文件,这样就会有问题。所以必须加上它的一个
                 //方法configure()。
         //hibernate中有一个工具类,叫SchemaExport,这个工具类需要传送configuration.
       //这个对象就把我们的类生成(导成)表出来。
       SchemaExport export=new SchemaExport(cfg);
          export.create(true, true);  //script是判断生成不生成,它实际是生成ddl.
                                            //这两个参数都设置成true就可以了。
                            //这个方法的具体含义可以直接看它的api。
                //或者关联上它的源代码,可以在create上,点击F3,
                  //选择"Attach Resource",选择“External File",
                 //再找到F:/java program/Hibernate相关资料/hibernate-3.2.0.ga,就关联上了。
                
                       //export.create(..)是拿到对象,直接生成就可以了。
         
     
     
      }                
}

控制台输出:

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))

//t_person中没有加入任何字段,还是原来的

alter table t_person add index FK785BED809AC0D5D6 (id), add constraint FK785BED809AC0D5D6 foreign key (id) references t_idcard (id)//这条语句是建立两者的关系。之所以生成这样的语句就是因为加上了constraint约束,加上这个约束后就加上了这条语句。

语句解释为:t_person 中的id 作为外键,参照了t_idCard中的id.

 

七、写单元测试类:

 package com.bjsxt.hibernate;

import org.hibernate.Session;

import junit.framework.TestCase;

public class One2OneTest extends TestCase {
 public void testSave1(){
  Session session=null;
  try{
   session=HibernateUtils.getSession();
   session.beginTransaction();
   
   IdCard idCard=new IdCard();
   idCard.setCardNo("8888888");
  
   Person person=new Person();
   person.setName("菜10");
   person.setIdCard(idCard);
   
   session.save(person);
   
   session.getTransaction().commit();
   
  }catch(Exception e){
   e.printStackTrace();
   session.getTransaction().rollback();
   
  }finally{
   HibernateUtils.closeSession(session);
  }
 }

}

控制台显示:

 insert into t_idcard (cardNo) values (?)

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


八、测试加载,看一下能不能将关系模型中的数据拿出来,然后放到对象里面。

OR映射的宗质就是像对象模型里面的东西存到关系模型里面。再将关系模型里面的东西拿出来放到对象里面。以前这些东西是我们自己做的,就像写的DAO一样的。hibernate一对一映射

one-to-one标签指的是如何加载关联对象或是引用对象。

原理就是先找到t_person表中主键为4的记录,然后到t_idcard 表,找主键为4的,然后将它的carNo  加上 来,放到IdCard 里面,所以可以看到正确的结果。

 测试代码 如下:

package com.bjsxt.hibernate;

 

import junit.framework.TestCase;

public class One2OneTest extends TestCase {
  
 public void testLoad(){
  Session session=null;
  try{
   session=HibernateUtils.getSession();
   session.beginTransaction();
   
   Person  person=(Person)session.get(Person.class,Integer.valueOf("4"));

   System.out.println("person.getName()="+person.getName());
   System.out.println("person.getIdCard().getCardNo="+person.getIdCard().getCardNo());
   
   session.getTransaction().commit();
   
  }catch(Exception e){
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally{
   HibernateUtils.closeSession(session);
  }
 }

}

结果:

select person0_.id as id1_0_, person0_.name as name1_0_ from t_person person0_ where person0_.id=?

person.getName()=菜10

select idcard0_.id as id0_0_, idcard0_.cardNo as cardNo0_0_ from t_idcard idcard0_ where idcard0_.id=?

person.getIdCard().getCardNo=8888888

 

 九、readme.txt文件

hibernate一对一主键关联映射(单向关联Person------>IdCard)

 一对一主键关联映射是让两个实体类对象的id保持相同。这样就可以避免
 多余的字段被创建
 具体映射:
 <id name="id">
    <!--person的主键来源于idCard,也就是共享 idCArd的主键-->
   。。。。。
  
   <!-- one-to-one 标签的含义,只是hiberante怎么加载它的关联对象,
   对于我们来说,就是idCard .默认根据主键加载
    constrained="true"  的含义表明当前主键上存在一个约束
    person的主键作为外键参照idCard.-->

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zylyueliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值