Heim >Datenbank >MySQL-Tutorial >Hibernate一对一双向关联(外键关联)用法小结

Hibernate一对一双向关联(外键关联)用法小结

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOriginal
2016-06-07 16:12:271039Durchsuche

这几天在改一个项目源码,遇到一个问题坑了很久。场景如下(注:此处是借鉴网络上的例子,并不是自己的实验环境): 一夫一妻制——比如夫妻关系的两张数据表,一个是wif表,一个是husban表,其数据表信息如下: CREATE TABLE `wife` ( `id` int(11) NOT NUL

这几天在改一个项目源码,遇到一个问题坑了很久。场景如下(注:此处是借鉴网络上的例子,并不是自己的实验环境):

一夫一妻制——比如夫妻关系的两张数据表,一个是wif表,一个是husban表,其数据表信息如下:

CREATE TABLE `wife` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8

CREATE TABLE `husband` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `wifeid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_wife` (`wifeid`),
  CONSTRAINT `fk_wife` FOREIGN KEY (`wifeid`) REFERENCES `wife` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8

即一个wife表和一个husband表,这里wife表为基表,husband表中的wifeid依赖于wife的主键id。

下面是相应的POJO:

Wife:  
1.	package com.linys.model;  
2.	  
3.	/** 
4.	 * Wife entity. @author MyEclipse Persistence Tools 
5.	 */  
6.	  
7.	public class Wife implements java.io.Serializable {  
8.	  
9.	    // Fields  
10.	  
11.	    /** 
12.	     *  
13.	     */  
14.	    private static final long serialVersionUID = 1L;  
15.	    private Integer id;  
16.	    private String name;  
17.	    private Husband husband;  
18.	    // Constructors  
19.	  
20.	    /** default constructor */  
21.	    public Wife() {  
22.	    }  
23.	  
24.	    /** minimal constructor */  
25.	    public Wife(String name) {  
26.	        this.name = name;  
27.	    }  
28.	  
29.	  
30.	    // Property accessors  
31.	  
32.	    public Integer getId() {  
33.	        return this.id;  
34.	    }  
35.	  
36.	    public void setId(Integer id) {  
37.	        this.id = id;  
38.	    }  
39.	  
40.	    public String getName() {  
41.	        return this.name;  
42.	    }  
43.	  
44.	    public void setName(String name) {  
45.	        this.name = name;  
46.	    }  
47.	  
48.	    public Husband getHusband() {  
49.	        return husband;  
50.	    }  
51.	  
52.	    public void setHusband(Husband husband) {  
53.	        this.husband = husband;  
54.	    }  
55.	  
56.	  
57.	}  
 
 Husband:
   
1.	package com.linys.model;  
2.	  
3.	/** 
4.	 * Husband entity. @author MyEclipse Persistence Tools 
5.	 */  
6.	  
7.	public class Husband implements java.io.Serializable {  
8.	  
9.	    // Fields  
10.	  
11.	    /** 
12.	     *  
13.	     */  
14.	    private static final long serialVersionUID = 1L;  
15.	    private Integer id;  
16.	    private Wife wife;  
17.	    private String name;  
18.	  
19.	    // Constructors  
20.	  
21.	    /** default constructor */  
22.	    public Husband() {  
23.	    }  
24.	  
25.	    /** minimal constructor */  
26.	    public Husband(String name) {  
27.	        this.name = name;  
28.	    }  
29.	  
30.	    /** full constructor */  
31.	    public Husband(Wife wife, String name) {  
32.	        this.wife = wife;  
33.	        this.name = name;  
34.	    }  
35.	  
36.	    // Property accessors  
37.	  
38.	    public Integer getId() {  
39.	        return this.id;  
40.	    }  
41.	  
42.	    public void setId(Integer id) {  
43.	        this.id = id;  
44.	    }  
45.	  
46.	    public Wife getWife() {  
47.	        return this.wife;  
48.	    }  
49.	  
50.	    public void setWife(Wife wife) {  
51.	        this.wife = wife;  
52.	    }  
53.	  
54.	    public String getName() {  
55.	        return this.name;  
56.	    }  
57.	  
58.	    public void setName(String name) {  
59.	        this.name = name;  
60.	    }  
61.	  
62.	}  

以上是基本的数据表映射。这时候假设我们需要一对一双向关联,即在保存或者更新时,可以根据一个husband实例可以获得其wife实例,也可根据wife实例去获得一个husband实例。

一对一双向关联比较特殊,不像单向关联,在hbm配置文件中仅仅使用one-to-one配置即可,这种情况下需要使用may-to-one和one-to-one来模拟一一对应,既然是一一对应,所以在many-to-one的一段,要加上unique=true属性,从而保证其唯一性。不要问我为什么,这是Hibernate的机制吧,其实说到这里,我对于Hibernate还不是很了解,如果有大神读到希望可以指点一二。从项目经验来看,如果不这么做,在同时修改了这两个实体,然后保存到库中时,总是报错,错误信息为session无法同步,或者外键id为NULL。使用了这样的配置后,就没有问题了。下面看二者的配置文件:

Wife.hbm.xml
 
Java代码   
1.	<?xml version="1.0" encoding="utf-8"?>  
2.	<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
3.	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
4.	<!--   
5.	    Mapping file autogenerated by MyEclipse Persistence Tools  
6.	-->  
7.	<hibernate-mapping>  
8.	    <class name="com.linys.model.Wife" table="wife">  
9.	        <id name="id" type="java.lang.Integer">  
10.	            <column name="id" />  
11.	            <generator class="native" />  
12.	        </id>  
13.	        <property name="name" type="java.lang.String">  
14.	            <column name="name" length="50" not-null="true" />  
15.	        </property>  
16.	       <one-to-one name="husband" class="com.linys.model.Husband" property-ref="wife" cascade="all"/> 
17.	    </class>  
18.	</hibernate-mapping>  
 Husband.hbm.xml:
1.	<?xml version="1.0" encoding="utf-8"?>  
2.	<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
3.	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
4.	<!--   
5.	    Mapping file autogenerated by MyEclipse Persistence Tools  
6.	-->  
7.	<hibernate-mapping>  
8.	    <class name="com.linys.model.Husband" table="husband">  
9.	        <id name="id" type="java.lang.Integer">  
10.	            <column name="id" />  
11.	            <generator class="native" />  
12.	        </id>  
13.	        <property name="name" type="java.lang.String">  
14.	            <column name="name" length="50" not-null="true" />  
15.	        </property>  
16.	        <may-to-one name="wife" class="com.linys.model.Wife" fetch="select"/>
17.	             <column name="wifeid" unique="true" not-null="true" />  
18.	        </many-to-one>  
19.	    </class>  
20.	</hibernate-mapping>  

外键所依赖的那个表的配置文件(wife)使用one-to-one,外键所在的表(husband)用many-to-one,但是要指定unique为true从而保证其唯一性。注意many这一端中的colum,配置的应该是外键所在表的外键列名,对应这里也就是husband表中的“wifeid”,需要与数据库中的数据表表中一致,切勿弄错。

one-to-one:指定在Wife这个类中用于双向关联的属性husband

property-ref: 在关联对象中用于与本对象关联的属性。

注意:property-ref="wife"不能少,否则会造成查询时关联查询失败!

以上是实际经验的总结,如有错误,欢迎指正。



Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn