Hibernate映射关系解析(二)--Unidirectional associations--one-to-one

来源:互联网 发布:守望先锋a卡优化 编辑:程序博客网 时间:2024/05/21 21:38

8.2.2  一对一(one-to-one)

基于外键的单向一对一(one-to-one)关联与单向多对一关联几乎是一样的。唯一的不同是单向一对一关联中外键字段具有 unique 约束。

<class name="Person">    <id name="id" column="personId">        <generator class="native"/>    </id>    <many-to-one name="address"         column="addressId"         unique="true"        not-null="true"/></class><class name="Address">    <id name="id" column="addressId">        <generator class="native"/>    </id></class>
create table Person ( personId bigint not null primary key, addressId bigint not null unique )create table Address ( addressId bigint not null primary key )

-----------------------------------

自己具体说明如下,仍然使用上一个例子,本例中一个人只能对应一个地址。

Address类、Person类、Address.hbm.xml文件与上一例子中全部相同,只需要如下修改Person.hbm.xml文件:

<hibernate-mapping package="com.hibernate.domain"><class name="Person" table="person"><id name="id" column="personid" type="java.lang.Integer"><generator class="native"/></id><property name="personName" type="java.lang.String"><column name="personName" length="64" not-null="true"/></property><!-- 配置many-to-one属性  --><!-- 其中name为Person类中“private Address address”中的address属性 --><!-- 这里需要增加unique约束   (这里是重点)--><many-to-one name="address" column="addressId" unique="true" not-null="true"/></class></hibernate-mapping>

测试结果如下:

//从数据中取出数据Person person = (Person) session.load(Person.class, 2);//向数据库中添加数据Address add = new Address();add.setAddressName("beijing");Person p1 = new Person();p1.setPersonName("Hibernate01");p1.setAddress(add);Person p2 = new Person();p2.setPersonName("hibernate02");p2.setAddress(add);session.save(add);session.save(p1);session.save(p2);
如果还像上例这样添加数据的话,就会报错:Duplicate entry '1' for key 'UK_ggbkwpl67fgfv0qtwb6cfque8' ,因为现在一个Person只能对应唯一一个Address。

此时两个表已经建立好了,只不过两张表都为空,没有数据,数据已经回滚。


正确的添加数据的情况如下:

//向数据库中添加数据Address add1 = new Address();add1.setAddressName("beijing");Address add2 = new Address();add2.setAddressName("天津");Person p1 = new Person();p1.setPersonName("Hibernate01");p1.setAddress(add1);Person p2 = new Person();p2.setPersonName("hibernate02");p2.setAddress(add2);session.save(add1);session.save(add2);session.save(p1);session.save(p2);
运行成功后,通过查询数据,结果如下:

Person和Address均正确,且一一对应。查询的话此处不再赘述。


----------------------------------------------------------

基于主键的单向一对一关联通常使用一个特定的id generator。然而,在这个例子中,我们翻转了关联的方向。

<class name="Person">    <id name="id" column="personId">        <generator class="native"/>    </id></class><class name="Address">    <id name="id" column="personId">        <generator class="foreign">            <param name="property">person</param>        </generator>    </id>    <one-to-one name="person" constrained="true"/></class>
create table Person ( personId bigint not null primary key )create table Address ( personId bigint not null primary key )

--------------------------------------------

自己的实践案例如下:

Person类:

public class Person implements Serializable {private static final long serialVersionUID = 1L;private Integer id;private String personName;public Person() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getPersonName() {return personName;}public void setPersonName(String personName) {this.personName = personName;}}

Address类:

public class Address implements Serializable{private static final long serialVersionUID = 1L;private Integer id;private String addressName;private Person person; //由于Address的主键要通过Person来映射,因此Address类必须加上该属性(这点重要)public Address() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getAddressName() {return addressName;}public void setAddressName(String addressName) {this.addressName = addressName;}public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}}

Person.hbm.xml文件(该文件正常配置即可):

<hibernate-mapping package="com.hibernate.domain"><class name="Person" table="person"><id name="id" column="personid" type="java.lang.Integer"><generator class="native"/></id><property name="personName" type="java.lang.String"><column name="personName" length="64" not-null="true"/></property></class></hibernate-mapping>


Address.hbm.xml文件配置:

<hibernate-mapping package="com.hibernate.domain"><class name="Address" table="address"><id name="id" column="addressId" type="java.lang.Integer"><!-- 因为是基于逐渐的one-to-one,所以我们使用外键策略(重要) --><generator class="foreign"><!-- 这里的值,是指定要跟哪个属性one-to-one (重要)--><!-- 具体到该例,是与 private Person person属性对应 --><param name="property">person</param></generator></id><property name="addressName" type="java.lang.String"><column name="addressName" length="128" not-null="true"/></property><!-- 这里配置Address和person属性是一对一的关系(重要) --><one-to-one name="person" constrained="true"/></class></hibernate-mapping>

进行代码测试如下:

<span style="white-space:pre"></span>Person p1 = new Person();p1.setPersonName("Hibernate01");Address add = new Address();add.setAddressName("beijing");add.setPerson(p1); //需要放入Personsession.save(p1);session.save(add);

通过 show create table address,可以看到 address的主键同时也是外键。




Address添加成功,Person添加成功,两者的id也相同。





0 0
原创粉丝点击