hibernate映射之一对一映射

转自: http://blog.csdn.net/a19881029/article/details/17481749

2张表之间通过主键形成一对一映射关系,如一个人只能有一张身份证:

t_identity_card表建表语句:

[sql] view plain copy
  1. CREATE TABLE `t_identity_card` (  
  2.   `id` int(11) NOT NULL,  
  3.   `identity` int(11) NOT NULL,  
  4.   PRIMARY KEY (`id`)  
  5. ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;  

t_person表建表语句:

[sql] view plain copy
  1. CREATE TABLE `t_person` (  
  2.   `id` int(11) NOT NULL,  
  3.   `namevarchar(255) NOT NULL,  
  4.   `age` int(11) NOT NULL,  
  5.   PRIMARY KEY (`id`),  
  6.   CONSTRAINT `FK_ID` FOREIGN KEY (`id`) REFERENCES `t_identity_card` (`id`)  
  7. ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;  

hibernate.cfg.xml:

[html] view plain copy
  1. <?xml version='1.0' encoding='utf-8'?>  
  2. <!DOCTYPE hibernate-configuration PUBLIC  
  3.     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  5. <hibernate-configuration>  
  6.     <session-factory>  
  7.         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  8.         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
  9.         <property name="connection.url">jdbc:mysql://localhost:3306/mydb</property>  
  10.         <property name="connection.username">root</property>  
  11.         <property name="connection.password">196428</property>  
  12.           
  13.         <property name="hibernate.show_sql">true</property>  
  14.           
  15.         <mapping resource="com/po/IdentityCard.hbm.xml" />  
  16.         <mapping resource="com/po/Person.hbm.xml" />  
  17.     </session-factory>  
  18. </hibernate-configuration>  

单向一对一主键关联:

t_identity_card表:

[java] view plain copy
  1. public class IdentityCard implements Serializable {  
  2.     private static final long serialVersionUID = 1L;  
  3.     private int id;  
  4.     private int identity;  
  5.     private Person person;  
  6.       
  7.     public int getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(int id) {  
  11.         this.id = id;  
  12.     }  
  13.     public int getIdentity() {  
  14.         return identity;  
  15.     }  
  16.     public void setIdentity(int identity) {  
  17.         this.identity = identity;  
  18.     }  
  19.     public Person getPerson() {  
  20.         return person;  
  21.     }  
  22.     public void setPerson(Person person) {  
  23.         this.person = person;  
  24.     }  
  25. }  

由于t_identity_card表使用foreign主键生成策略,故在t_identity_card表的配置文件中必须配置主键生成表t_person,这样在向t_identity_card表中插入数据时才能找到所需的主键值,所以单向一对一主键关联中只有t_person<-t_identity_card,没有t_person->t_identity_card

[html] view plain copy
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  5. <hibernate-mapping>  
  6.     <class name="com.po.IdentityCard" table="t_identity_card">  
  7.         <id name="id" column="id" type="integer">  
  8.             <generator class="foreign">  
  9.                 <param name="property">person</param>  
  10.             </generator>  
  11.         </id>  
  12.         <property name="identity" column="identity" type="integer"/>  
  13.         <one-to-one name="person" class="com.po.Person"/>  
  14.     </class>  
  15. </hibernate-mapping>  

t_person表:

[java] view plain copy
  1. public class Person implements Serializable {  
  2.     private static final long serialVersionUID = 1L;  
  3.     private int id;  
  4.     private String name;  
  5.     private int age;  
  6.       
  7.     public int getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(int id) {  
  11.         this.id = id;  
  12.     }  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.     public int getAge() {  
  20.         return age;  
  21.     }  
  22.     public void setAge(int age) {  
  23.         this.age = age;  
  24.     }  
  25. }  
[html] view plain copy
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  5. <hibernate-mapping>  
  6.     <class name="com.po.Person" table="t_person">  
  7.         <id name="id" column="id" type="integer">  
  8.             <generator class="assigned"/>  
  9.         </id>  
  10.         <property name="name" column="name" type="string"/>  
  11.         <property name="age" column="age" type="integer"/>  
  12.     </class>  
  13. </hibernate-mapping>  

测试一下:

[java] view plain copy
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         Configuration conf = new Configuration();  
  4.         SessionFactory sessionFactory = conf.configure().buildSessionFactory();  
  5.         Session session = sessionFactory.openSession();  
  6.           
  7.         IdentityCard identityCard = new IdentityCard();  
  8.         identityCard.setIdentity(123456);  
  9.         Person person = new Person();  
  10.         person.setId(1);  
  11.         person.setName("sean");  
  12.         person.setAge(25);  
  13.         identityCard.setPerson(person);  
  14.           
  15.         Transaction tran = session.beginTransaction();  
  16.         session.save(identityCard);  
  17.         tran.commit();  
  18.           
  19.         IdentityCard identityCard2 = (IdentityCard)session.get(IdentityCard.class1);  
  20.         Person person2 = identityCard2.getPerson();  
  21.         System.out.println(person2.getName());  
  22.           
  23.         session.close();  
  24.     }  
  25. }  

测试结果为:

[plain] view plain copy
  1. Hibernate: insert into t_identity_card (identity, id) values (?, ?)  
  2. sean  

只向t_identity_card表中插入了数据,t_person表为空,由于没有设置关联关系的cascade属性,在持久化一张表的时候,并不会级联的持久化另一张表

将t_identity_card表的映射文件中的关联关系修改为:<one-to-one name="person" class="com.po.Person"cascade="all" />

[plain] view plain copy
  1. Hibernate: select person_.id, person_.name as name1_, person_.age as age1_   
  2. from t_person person_ where person_.id=?  
  3. Hibernate: insert into t_identity_card (identity, id) values (?, ?)  
  4. Hibernate: insert into t_person (name, age, id) values (?, ?, ?)  
  5. sean  

双向一对一主键关联:

这时需要对t_person表的配置做一些修改:

[java] view plain copy
  1. public class Person implements Serializable {  
  2.     private static final long serialVersionUID = 1L;  
  3.     private int id;  
  4.     private String name;  
  5.     private int age;  
  6.     private IdentityCard identityCard;//新增  
  7.       
  8.     public int getId() {  
  9.         return id;  
  10.     }  
  11.     public void setId(int id) {  
  12.         this.id = id;  
  13.     }  
  14.     public String getName() {  
  15.         return name;  
  16.     }  
  17.     public void setName(String name) {  
  18.         this.name = name;  
  19.     }  
  20.     public int getAge() {  
  21.         return age;  
  22.     }  
  23.     public void setAge(int age) {  
  24.         this.age = age;  
  25.     }  
  26.     public IdentityCard getIdentityCard() {  
  27.         return identityCard;  
  28.     }  
  29.     public void setIdentityCard(IdentityCard identityCard) {  
  30.         this.identityCard = identityCard;  
  31.     }  
  32. }  
[html] view plain copy
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  5. <hibernate-mapping>  
  6.     <class name="com.po.Person" table="t_person">  
  7.         <id name="id" column="id" type="integer">  
  8.             <generator class="native"/>  
  9.         </id>  
  10.         <property name="name" column="name" type="string"/>  
  11.         <property name="age" column="age" type="integer"/>  
  12.         <!--新增-->  
  13.         <one-to-one name="identityCard" class="com.po.IdentityCard" cascade="all" />  
  14.     </class>  
  15. </hibernate-mapping>  

测试一下:

[java] view plain copy
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         Configuration conf = new Configuration();  
  4.         SessionFactory sessionFactory = conf.configure().buildSessionFactory();  
  5.         Session session = sessionFactory.openSession();  
  6.           
  7.         IdentityCard identityCard = new IdentityCard();  
  8.         identityCard.setIdentity(123456);  
  9.         Person person = new Person();  
  10.         person.setId(1);  
  11.         person.setName("sean");  
  12.         person.setAge(25);  
  13.           
  14.         identityCard.setPerson(person);  
  15.         person.setIdentityCard(identityCard);  
  16.           
  17.         Transaction tran = session.beginTransaction();  
  18.         session.save(identityCard);  
  19.         tran.commit();  
  20.           
  21.         Person person_tmp = (Person)session.get(Person.class1);  
  22.         IdentityCard id_card_tmp = person_tmp.getIdentityCard();  
  23.         System.out.println(id_card_tmp.getIdentity());  
  24.           
  25.         id_card_tmp = (IdentityCard)session.get(IdentityCard.class1);  
  26.         person_tmp = id_card_tmp.getPerson();  
  27.         System.out.println(person_tmp.getName());  
  28.           
  29.         session.close();  
  30.     }  
  31. }  

测试结果为:

[plain] view plain copy
  1. Hibernate: select person_.id, person_.name as name1_, person_.age   
  2. as age1_ from t_person person_ where person_.id=?  
  3. Hibernate: insert into t_identity_card (identity, id) values (?, ?)  
  4. Hibernate: insert into t_person (name, age, id) values (?, ?, ?)  
  5. 123456  
  6. sean  

Hibernate首先持久化了identityCard对象,将测试代码中的session.save(identityCard)修改为session.save(person),再次测试:

[plain] view plain copy
  1. Hibernate: insert into t_person (name, age, id) values (?, ?, ?)  
  2. Exception in thread "main" org.hibernate.exception.ConstraintViolationException:   
  3. Could not execute JDBC batch update  
  4. ......  
  5. Caused by: java.sql.BatchUpdateException: Cannot add or update a child row:  
  6. a foreign key constraint fails (`mydb`.`t_person`, CONSTRAINT `FK_ID`   
  7. FOREIGN KEY (`id`) REFERENCES `t_identity_card` (`id`))  
  8. ......  

Hibernate这次首先持久化了person对象,由于t_person表中的id字段建立了外键关系,故持久化失败,删除掉t_person表中id字段的外键关系之后,插入正常:

[plain] view plain copy
  1. Hibernate: insert into t_person (name, age, id) values (?, ?, ?)  
  2. Hibernate: insert into t_identity_card (identity, id) values (?, ?)  
  3. 123456  
  4. sean  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值