Hibernate表联系关系-one-to-one
三种实现方式,已顾客与房间的关系为例:
0. DB代码:
DROP TABLE IF EXISTS 'Customer';
CREATE TABLE 'Customer' (
'id int ( 11 ) NOT NULL auto_increment,
'name' varchar(255 ) NOT NULL,
PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS 'Room';
CREATE TABLE 'Room' (
'id' int ( 11 ) NOT NULL auto_increment,
'name' varchar(255 ) NOT NULL,
'customer_id' int ( 11 ) ,
foreign key (' customer _id') references customer('id'),
PRIMARY KEY ('id') ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1. 实体代码:
public class Customer implements java.io.Serializable {
private Integer id;
private String name;
private Room room;
//省略构造函数,get/set方法
}
public class Room implements java.io.Serializable {
private Integer id;
private String name;
private Customer customer ;
//省略构造函数,get/set方法
}
2. 通过外键方式实现:
Room.hbm.xml:
<hibernate-mapping>
<class name= "com.domain.Customer" table= "Customer" catalog= "Temp" >
< id name="id" type= "java.lang.Integer" >
<column name="id" />
<generator class = "native" />
</id>
<property name="name" type= "java.lang.String>
<column name="name" not- null = "true" />
</property>
<!-- class 可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 -->
<one-to-one cascade="all" name= "customer" class = "com.domain.Customer"
property-ref= " customer " >
</one-to-one>
</class >
</hibernate-mapping>
Customer.hbm.xml:
<hibernate-mapping>
<class name= "com.domain.Customer" table= "Customer" catalog= "Temp" >
<id name="id" type= "java.lang.Integer" >
<column name="id" />
<generator class = "native" />
</id>
<property name="name" type= "java.lang.String" >
<column name="name" not- null = "true" />
</property>
<!-- many开头的是代表该表持有外键 -->
<many-to-one name="rom" class = "com.domain.Room" unique= "true">
<column name=" customer _id" />
</many-to-one>
</class >
</hibernate-mapping>
3. 通过主键方式,即一个表的主键有另一个表的主键决定,本例中Customer表的主键由Room表决定:
Room.hbm.xml:
<hibernate-mapping>
<class name= "com.domain.Customer" table= "Customer" catalog= "Temp" >
< id name="id" type= "java.lang.Integer" >
<column name="id" />
<generator class = "native" />
</id>
<property name="name" type= "java.lang.String>
<column name="name" not- null = "true" />
</property>
<!-- class 可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 -->
<!--
<one-to-one cascade="all" name= "customer" class = "com.domain.Customer"
property-ref= " customer " >
</one-to-one>
-->
<one-to-one name="customer" class = "com.domain.Customer" cascade="all" >
</class >
</hibernate-mapping>
Customer.hbm.xml:
<hibernate-mapping>
<class name= "com.domain.Customer" table= "Customer" catalog= "Temp" >
<id name="id" type= "java.lang.Integer" >
<column name="id" />
<!--
<generator class = "native" cascade="all" />
-->
<!--Customer的主键由Room的主键决定,可以看成是外键-->
<generator class = "foreign" >
<param name="property" >room</param>
</generator>
<!--或者使用下面的方式-->
<generator class="increment"></generator>
</id>
<property name="name" type= "java.lang.String" >
<column name="name" not- null = "true" />
</property>
<!-- many开头的是代表该表持有外键 -->
<!--
<many-to-one name="rom" class = "com.domain.Room" unique= "true">
<column name=" customer _id" />
</many-to-one>
-->
<one-to-one name="rom" class = "com.domain.Room" />
<!--或者使用下面的方式-->
<one-to-one name="rom" class = "com.domain.Room" constrained="true" />
</class >
</hibernate-mapping>
4. 通过关系表实现:
create table room_cust(
room_id int not null ,
cust_id int not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
配置文件:
<!--optional= "true" 的意思是只有当room_id 和 cust_id 都不为空时才在关系表里插入。这样也会插入 2 遍,
所以需要inverse= "true" 把一方设置为虚的。即不让插入到关系表中-->
<join table=" room_cus t" optional= "true" inverse= "true" >
<key column="cust_id" />
<many-to-one name="room" column= "room_id" unique= "true" />
</join>