您的位置:首页 > 其它

Hibernate对应关系详解

2008-08-07 12:42 363 查看
many-to-one节点有以下属性(摘自Hibernate文档):
(1) name: 属性名。

(2) column (可选): 字段名。

(3) class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。

(4) cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。

(5) outer-join(外连接) (可选 - 默认为 自动): 当设置hibernate.use_outer_join的时候,对这个关联允许外连接抓取。

(6) update, insert (可选 - defaults to true) 指定对应的字段是否在用于UPDATE 和/或 INSERT的SQL语句中包含。如果二者都是false,则这是一个纯粹的“外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到的,或者通过trigger(除法器),或者是其他程序。

(7) property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。

(8) access (可选 - 默认是 property): Hibernate用来访问属性的策略。

cascade 属性允许下列值: all, save-update, delete, none。设置除了none以外的其它值会传播特定的操作到关联的(子)对象中。参见后面的“Lifecycle Objects(自动管理生命周期的对象)”。

outer-join参数允许下列三个不同值:

auto (默认) 使用外连接抓取关联(对象),如果被关联的对象没有代理(proxy)

true 一直使用外连接来抓取关联

false 永远不使用外连接来抓取关联

Hibernate 一对一连接表双向关联

一、模型介绍

一个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Person11tab_sx {
private int personid;
private String name;
private int age;
private Address11tab_sx address11tab_sx;

public class Address11tab_sx {
private int addressid;
private String addressdetail;
private Person11tab_sx person11tab_sx;

三、表模型

person_11tab_sx;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

join_11tab_sx;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| addressid | int(11) | NO | UNI | | |
| personid | int(11) | NO | PRI | | |
+-----------+---------+------+-----+---------+-------+

address_11tab_sx;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.sx._1_1_tab.Person11tab_sx" table="PERSON_11tab_sx">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<join table="join_11tab_sx"
optional="true">
<key column="personid"
unique="true"/>
<many-to-one name="address11tab_sx"
column="addressid"
not-null="true"
unique="true"/>
</join>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.sx._1_1_tab.Address11tab_sx" table="ADDRESS_11tab_sx">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
<join table="join_11tab_sx"
optional="true"
inverse="true">
<key column="addressid"
unique="true"/>
<many-to-one name="person11tab_sx" column="personid"
not-null="true" unique="true"/>
</join>
</class>
</hibernate-mapping>

五、测试方法

public class Test_11tab_sx {
public static void main(String[] args){
Address11tab_sx add = new Address11tab_sx();
Person11tab_sx p = new Person11tab_sx();

add.setAddressdetail("。。。。。");
p.setAge(12);
p.setName("。。。。。");

add.setPerson11tab_sx(p);
p.setAddress11tab_sx(add);

Session session = HibernateUtil.getCurrentSession();
Transaction tx = session.beginTransaction();
session.saveOrUpdate(p);
session.saveOrUpdate(add);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存.
session.saveOrUpdate(p);
session.saveOrUpdate(add);

Hibernate: insert into PERSON_11tab_sx (name, age) values (?, ?)
Hibernate: insert into ADDRESS_11tab_sx (addressdetail) values (?)
Hibernate: insert into join_11tab_sx (addressid, personid) values (?, ?)

Hibernate 一对一主键双向关联

一、模型介绍

一个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Person11pk_sx {
private int personid;
private String name;
private int age;
private Address11pk_sx address11pk_sx;

public class Address11pk_sx {
private int addressid;
private String addressdetail;
private Person11pk_sx person11pk_sx;

三、表模型

person_11pk_sx;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

address_11pk_sx;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| addressid | int(11) | NO | PRI | | |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.sx._1_1_pk.Person11pk_sx" table="PERSON_11pk_sx">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<one-to-one name="address11pk_sx" cascade="all"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.sx._1_1_pk.Address11pk_sx" table="ADDRESS_11pk_sx">
<id name="addressid">
<generator class="foreign">
<param name="property">person11pk_sx</param>
</generator>
</id>
<property name="addressdetail"/>
<!--表明主键由关联属性生成-->
<one-to-one name="person11pk_sx" cascade="all" constrained="true"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_11pk_sx {
public static void main(String[] args){
Address11pk_sx add = new Address11pk_sx();
Person11pk_sx p = new Person11pk_sx();

add.setAddressdetail("。。。。。");
p.setAge(12);
p.setName("。。。。。");

add.setPerson11pk_sx(p);
p.setAddress11pk_sx(add);

Session session = HibernateUtil.getCurrentSession();
Transaction tx = session.beginTransaction();
session.save(p);
// session.save(add);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存.
session.save(p);
// session.save(add);

Hibernate: insert into PERSON_11pk_sx (name, age) values (?, ?)
Hibernate: insert into ADDRESS_11pk_sx (addressdetail, addressid) values (?, ?)

Hibernate 一对一外键双向关联

一、模型介绍

一个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Person11fk_sx {
private int personid;
private String name;
private int age;
private Address11fk_sx address11fk_sx;

public class Address11fk_sx {
private int addressid;
private String addressdetail;
private Person11fk_sx person11fk_sx;

三、表模型

person_11fk_sx;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
address_11fk_sx;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
| person11fk_sx | int(11) | YES | UNI | NULL | |
+---------------+--------------+------+-----+---------+----------------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.sx._1_1_fk.Person11fk_sx" table="PERSON_11fk_sx">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<one-to-one name="address11fk_sx"
cascade="all"
property-ref="person11fk_sx"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.sx._1_1_fk.Address11fk_sx" table="ADDRESS_11fk_sx">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
<!--unique="true"表示本实体是"1"-->
<many-to-one name="person11fk_sx" unique="true"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_11fk_sx {
public static void main(String[] args) {
Address11fk_sx add = new Address11fk_sx();
Person11fk_sx p = new Person11fk_sx();

add.setAddressdetail("。。。。。");
p.setAge(12);
p.setName("。。。。。");

add.setPerson11fk_sx(p);
p.setAddress11fk_sx(add);

Session session = HibernateUtil.getCurrentSession();
Transaction tx = session.beginTransaction();
session.save(p);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存.
session.save(p);

Hibernate: insert into PERSON_11fk_sx (name, age) values (?, ?)
Hibernate: insert into ADDRESS_11fk_sx (addressdetail, person11fk_sx) values (?, ?)

Hibernate 多对多单向关联

一、模型介绍

多个人(Person)对应多个地址(Address)。
一个人可对应多个地址,一个地址也可以对应多个人。
二、实体(省略getter、setter方法)

public class Personnn {
private int personid;
private String name;
private int age;
private Set addresses=new HashSet();

public class Addressnn {
private int addressid;
private String addressdetail;

三、表模型

person_nn;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

join_nn;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| personid | int(11) | NO | PRI | | |
| addressid | int(11) | NO | PRI | | |
+-----------+---------+------+-----+---------+-------+

person_nn;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.dx._n_n.Personnn" table="PERSON_nn">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--映射集合属性,join_1ntab是连接表表名-->
<set name="addresses"
table="join_nn"
>
<!--“column="personid"”确定PERSON_1ntab表关联到连接表的外键列名-->
<key column="personid"/>
<!--“column="addressid"”关联PERSON_1ntab表的Address1ntab对象的id在连接表中的列名-->
<many-to-many
column="addressid"
class="com.lavasoft.dx._n_n.Addressnn"/>
</set>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._n_n.Addressnn" table="ADDRESS_nn">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_nn {
public static void main(String[] args){
Addressnn add1=new Addressnn();
Addressnn add2=new Addressnn();
Addressnn add3=new Addressnn();
Personnn p1=new Personnn();
Personnn p2=new Personnn();

add1.setAddressdetail("。。。。。");
add2.setAddressdetail("。。。。。");
add3.setAddressdetail("。。。。。");
p1.setName("。。。。。");
p1.setAge(30);
p2.setName("。。。。。");
p2.setAge(50);

p1.getAddresses().add(add1);
p1.getAddresses().add(add2);
p2.getAddresses().add(add2);
p2.getAddresses().add(add3);

Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(add2);
session.save(add3);
session.save(p1);
session.save(p2);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存.
session.save(add1);
session.save(add2);
session.save(add3);
session.save(p1);
session.save(p2);

Hibernate: insert into ADDRESS_nn (addressdetail) values (?)
Hibernate: insert into ADDRESS_nn (addressdetail) values (?)
Hibernate: insert into ADDRESS_nn (addressdetail) values (?)
Hibernate: insert into PERSON_nn (name, age) values (?, ?)
Hibernate: insert into PERSON_nn (name, age) values (?, ?)
Hibernate: insert into join_nn (personid, addressid) values (?, ?)
Hibernate: insert into join_nn (personid, addressid) values (?, ?)
Hibernate: insert into join_nn (personid, addressid) values (?, ?)
Hibernate: insert into join_nn (personid, addressid) values (?, ?)

Hibernate 多对一连接表单向关联

一、模型介绍

多个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Personn1tab {
private int personid;
private String name;
private int age;
private Addressn1tab addressn1tab;

public class Addressn1tab {
private int addressid;
private String addressdetail;

三、表模型

address_n1tab;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

join_n1tab;
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| personid | int(11) | NO | PRI | | |
| addressn1tab | int(11) | YES | MUL | NULL | |
+------------+---------+------+-----+---------+-------+

person_n1tab;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.dx._n_1_tab.Personn1tab" table="PERSON_n1tab">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--使用join元素显式确定链接表-->
<join table="join_n1tab">
<!--映射关联所用的外键-->
<key column="personid"/>
<many-to-one name="addressn1tab"/>
</join>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._n_1_tab.Addressn1tab" table="ADDRESS_n1tab">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_n1tab {
public static void main(String[] args){
Personn1tab p1=new Personn1tab();
Personn1tab p2=new Personn1tab();

p1.setAge(21);
p1.setName("p1");

p2.setAge(23);
p2.setName("p2");

Addressn1tab add=new Addressn1tab();
add.setAddressdetail("。。。。。");

p1.setAddressn1tab(add);
p2.setAddressn1tab(add);

Session session=HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add);
session.save(p1);
session.save(p2);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存. 推荐这么干!

session.save(p1);
session.save(p2);

Hibernate: insert into ADDRESS_n1tab (addressdetail) values (?)
Hibernate: insert into PERSON_n1tab (name, age) values (?, ?)
Hibernate: insert into join_n1tab (address11fk, personid) values (?, ?)
Hibernate: insert into PERSON_n1tab (name, age) values (?, ?)
Hibernate: insert into join_n1tab (address11fk, personid) values (?, ?)

2) :正常保存.
session.save(p1);
session.save(p2);
session.save(add);

Hibernate: insert into PERSON_n1tab (name, age) values (?, ?)
Hibernate: insert into join_n1tab (address11fk, personid) values (?, ?)
Hibernate: insert into PERSON_n1tab (name, age) values (?, ?)
Hibernate: insert into join_n1tab (address11fk, personid) values (?, ?)

Hibernate 多对一外键单向关联

一、模型介绍

多个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Personn1fk {
private int personid;
private String name;
private int age;
private Addressn1fk addressn1fk;

public class Addressn1fk {
private int addressid;
private String addressdetail;

三、表模型

address_n1kf;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

person_n1kf;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| addressId | int(11) | YES | MUL | NULL | |
+-----------+--------------+------+-----+---------+----------------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.dx._n_1_fk.Personn1fk" table="PERSON_n1fk">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--用来映射关联PO column是Address在该表中的外键列名-->
<many-to-one name="addressn1fk" column="addressId"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._n_1_fk.Addressn1fk" table="ADDRESS_n1fk">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_n1fk {
public static void main(String[] args){
Personn1fk p1=new Personn1fk();
Personn1fk p2=new Personn1fk();

p1.setAge(21);
p1.setName("p1");

p2.setAge(23);
p2.setName("p2");

Addressn1fk add=new Addressn1fk();
add.setAddressdetail("。。。。。");

p1.setAddressn1fk(add);
p2.setAddressn1fk(add);

Session session=HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add);
session.save(p1);
session.save(p2);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存. 推荐这么干!

session.save(p1);
session.save(p2);

Hibernate: insert into ADDRESS_n1kf (addressdetail) values (?)
Hibernate: insert into PERSON_n1kf (name, age, addressId) values (?, ?, ?)
Hibernate: insert into PERSON_n1kf (name, age, addressId) values (?, ?, ?)

2) :正常保存.
session.save(p1);
session.save(p2);
session.save(add);

Hibernate: insert into PERSON_n1kf (name, age, addressId) values (?, ?, ?)
Hibernate: insert into PERSON_n1kf (name, age, addressId) values (?, ?, ?)
Hibernate: insert into ADDRESS_n1kf (addressdetail) values (?)
Hibernate: update PERSON_n1kf set name=?, age=?, addressId=? where personid=?
Hibernate: update PERSON_n1kf set name=?, age=?, addressId=? where personid=?

3) :正常保存.
session.save(add);
// session.save(p1);
// session.save(p2);

Hibernate: insert into ADDRESS_n1kf (addressdetail) values (?)

4) : 发生异常,不能保存.
// session.save(add);
session.save(p1);
session.save(p2);
Hibernate: insert into PERSON_n1kf (name, age, addressId) values (?, ?, ?)
Hibernate: insert into PERSON_n1kf (name, age, addressId) values (?, ?, ?)
Exception in thread "main" org.hibernate.TransientObjectException: com.lavasoft.dx._n_1_

Hibernate 一对多连接表单向关联

一、模型介绍

一个人(Person)对应多个地址(Address),比如家庭地址、公司地址。

二、实体(省略getter、setter方法)

public class Person1ntab {
private int personid;
private String name;
private int age;
private Set addresses=new HashSet();

public class Address1nfk implements Serializable {
private int addressid;
private String addressdetail;

三、表模型

join_1ntab;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| personid | int(11) | NO | PRI | | |
| addressid | int(11) | NO | PRI | | |
+-----------+---------+------+-----+---------+-------+

person_1ntab;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

address_1ntab;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

四、映射方法

<hibernate-mapping>
<class name="com.lavasoft.dx._1_n_tab.Person1ntab" table="PERSON_1ntab">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--映射集合属性,join_1ntab是连接表表名-->
<set name="addresses"
table="join_1ntab"
>
<!--“column="personid"”确定PERSON_1ntab表关联到连接表的外键列名-->
<key column="personid"/>
<!--“column="addressid"”关联PERSON_1ntab表的Address1ntab对象的id在连接表中的列名-->
<!--“unique="true"表示1-N,Person1ntab是1,Address1ntab是多”-->
<many-to-many
column="addressid"
unique="true"
class="com.lavasoft.dx._1_n_tab.Address1ntab"/>
</set>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_n_tab.Address1ntab" table="ADDRESS_1ntab">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

六、测试方法

public class Test_1ntab {
public static void main(String[] args){
Address1ntab add1=new Address1ntab();
Address1ntab add2=new Address1ntab();
Address1ntab add3=new Address1ntab();
Person1ntab p1=new Person1ntab();
Person1ntab p2=new Person1ntab();

add1.setAddressdetail("。。。。。");
add2.setAddressdetail("。。。。。");
add3.setAddressdetail("。。。。。");
p1.setName("。。。。。");
p1.setAge(30);
p2.setName("。。。。。");
p2.setAge(50);

p1.getAddresses().add(add1);
p1.getAddresses().add(add2);
//p2.getAddresses().add(add2);
p2.getAddresses().add(add3);

Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(add2);
session.save(add3);
session.save(p1);
session.save(p2);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存.
session.save(add1);
session.save(add2);
session.save(add3);
session.save(p1);
session.save(p2);
Hibernate: insert into PERSON_1nfk (name, age) values (?, ?)
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: update ADDRESS_1nfk set personid=? where addressid=?
Hibernate: update ADDRESS_1nfk set personid=? where addressid=?

Hibernate 一对多外键单向关联

这种情况很少见,但Hibernate同样允许采用连接表关联1-1.有连接表的1-1同样只需要将N-1的many-to-one元素增加unique="true"属性即可。

一、模型介绍

一个人(Person)对应多个地址(Address),比如家庭地址、公司地址。

二、实体(省略getter、setter方法)

public class Person1nfk implements Serializable {
private int personid;
private String name;
private int age;
private Set addresses=new HashSet();

public class Address1nfk implements Serializable {
private int addressid;
private String addressdetail;

三、表模型

address_1nfk;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
| personid | int(11) | YES | MUL | NULL | |
+---------------+--------------+------+-----+---------+----------------+

person_1nfk;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

四、映射方法:在实体类Person里面添加Address的集合,即可形成一对多关系。
<!--映射集合属性,关联到持久化类,inverse="false"表示主控端在Person1nfk端,lazy="false"表示不采用延迟加载-->
<set name="addresses"
table="ADDRESS_1nfk"
cascade="all"
>
<!--确定关联的外键列-->
<key column="personid"/>
<!--用以映射到关联类属性-->
<one-to-many class="com.lavasoft.dx._1_n_fk.Address1nfk"/>
</set>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_n_fk.Person1nfk" table="PERSON_1nfk">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--映射集合属性,关联到持久化类,inverse="false"表示主控端在Person1nfk端,lazy="false"表示不采用延迟加载-->
<set name="addresses"
table="ADDRESS_1nfk"
cascade="all"
>
<!--确定关联的外键列-->
<key column="personid"/>
<!--用以映射到关联类属性-->
<one-to-many class="com.lavasoft.dx._1_n_fk.Address1nfk"/>
</set>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_n_fk.Address1nfk" table="ADDRESS_1nfk">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_1nfk {
public static void main(String[] args){
Address1nfk add1=new Address1nfk();
Address1nfk add2=new Address1nfk();
Person1nfk p=new Person1nfk();

add1.setAddressdetail("。。。。。。");
add2.setAddressdetail("。。。。。。");
p.setName("。。。。。");
p.setAge(30);
p.getAddresses().add(add1);
p.getAddresses().add(add2);

Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(add2);
session.save(p);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存.
// session.save(add1);
// session.save(add2);
session.save(p);
Hibernate: insert into PERSON_1nfk (name, age) values (?, ?)
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: update ADDRESS_1nfk set personid=? where addressid=?
Hibernate: update ADDRESS_1nfk set personid=? where addressid=?

2) :正常保存.
session.save(add1);
session.save(add2);
session.save(p);
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: insert into PERSON_1nfk (name, age) values (?, ?)
Hibernate: update ADDRESS_1nfk set personid=? where addressid=?
Hibernate: update ADDRESS_1nfk set personid=? where addressid=?

3) :正常保存.
session.save(add1);
session.save(add2);
// session.save(p);
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)
Hibernate: insert into ADDRESS_1nfk (addressdetail) values (?)

Hibernate 一对一连接表单向关联

这种情况很少见,但Hibernate同样允许采用连接表关联1-1.有连接表的1-1同样只需要将N-1的many-to-one元素增加unique="true"属性即可。

一、模型介绍

一个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Person11tab {
private int personid;
private String name;
private int age;
private Address11tab address11tab;

public class Address11tab {
private int addressid;
private String addressdetail;

三、表模型

address_11tab;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

join_11tab;
+--------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+-------+
| personid | int(11) | NO | PRI | | |
| address11tab | int(11) | YES | UNI | NULL | |
+--------------+---------+------+-----+---------+-------+

person_11tab;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+

四、映射方法:在Person中添加Address属性,映射配置为:
<!--使用join元素显式确定链接表-->
<join table="join_11tab">
<key column="personid"/>
<!--映射1-1关联属性,其中unique=“true”属性确定为“1-1”-->
<many-to-one name="address11tab" unique="true"/>
</join>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_1_tab.Person11tab" table="PERSON_11tab">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--使用join元素显式确定链接表-->
<join table="join_11tab">
<key column="personid"/>
<!--映射1-1关联属性,其中unique=“true”属性确定为“1-1”-->
<many-to-one name="address11tab" unique="true"/>
</join>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_1_tab.Address11tab" table="ADDRESS_11tab">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_11tab {
public static void main(String[] args){
Person11tab p1=new Person11tab();

p1.setAge(21);
p1.setName("p1");

Address11tab add1=new Address11tab();
add1.setAddressdetail("。。。。。");

p1.setAddress11tab(add1);

Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(p1);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存. 推荐这么干!
session.save(add1);
session.save(p1);

Hibernate: insert into ADDRESS_11tab (addressdetail) values (?)
Hibernate: insert into PERSON_11tab (name, age) values (?, ?)
Hibernate: insert into join_11tab (address11tab, personid) values (?, ?)

2) :正常保存.
session.save(p1);
session.save(add1);

Hibernate: insert into PERSON_11tab (name, age) values (?, ?)
Hibernate: insert into join_11tab (address11tab, personid) values (?, ?)
Hibernate: insert into ADDRESS_11tab (addressdetail) values (?)
Hibernate: update join_11tab set address11tab=? where personid=?

3) :正常保存.
// session.save(p1);
session.save(add1);

Hibernate: insert into ADDRESS_11tab (addressdetail) values (?)

4) : 发生异常,不能保存.
session.save(p1);
// session.save(add1);

Hibernate: insert into PERSON_11tab (name, age) values (?, ?)
Hibernate: insert into join_11tab (address11tab, personid) values (?, ?)
Exception in thread "main" org.hibernate.TransientObjectException: com.lavasoft.dx._1_1_

Hibernate 一对一主键单向关联

1-1的关联可以基于主键关联,但基于主键关联的持久化类不能拥有自己的主键生成策略,它的主键由关联类负责生成。另外,另外,增加one-to-one元素来关联属性,必须为one-to-one元素增加constrained="true"属性,表明该类主键由关联类生成。

一、模型介绍

一个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Person11pk {
private int personid;
private String name;
private int age;
private Address11pk address11pk;

public class Address11pk {
private int addressid;
private String addressdetail;

三、表模型

address_11pk;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

person_11pk;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| personid | int(11) | NO | PRI | | |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+

四、映射方法:在Person中配置id生成策略为:

<id name="personid">
<!--基于主键关联时,主键生成策略是foreign,表明根据关联类生成主键-->
<generator class="foreign">
<!--关联持久化类的属性名-->
<param name="property">address11pk</param>
</generator>
</id>
......
<!--用于映射1-1关联-->
<one-to-one name="address11pk" constrained="true"/>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_1_pk.Person11pk" table="PERSON_11pk">
<id name="personid" column="presonid">
<!--基于主键关联时,主键生成策略是foreign,表明根据关联类生成主键-->
<generator class="foreign">
<!--关联持久化类的属性名-->
<param name="property">address11pk</param>
</generator>
</id>
<property name="name"/>
<property name="age"/>
<!--用于映射1-1关联-->
<one-to-one name="address11pk" constrained="true"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_1_pk.Address11pk" table="ADDRESS_11pk">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_11pk {
public static void main(String[] args){
Person11pk p1=new Person11pk();

p1.setAge(21);
p1.setName("p1");

Address11pk add1=new Address11pk();
add1.setAddressdetail("。。。。。");

p1.setAddress11pk(add1);

Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(p1);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存. 推荐这么干!
session.save(add1);
session.save(p1);

Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)

2) :正常保存.
session.save(p1);
session.save(add1);

Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
Hibernate: update PERSON_11fk set name=?, age=?, addressId=? where personid=?

3) :正常保存.
// session.save(p1);
session.save(add1);

Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)

4) : 发生异常,不能保存.
session.save(p1);
// session.save(add1);

Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
Exception in thread "main" org.hibernate.TransientObjectException: com.lavasoft.dx._1_1_

Hibernate 一对一外键单向关联

事实上,单向1-1与N-1的实质是相同的,1-1是N-1的特例,单向1-1与N-1的映射配置也非常相似。只需要将原来的many-to-one元素增加unique="true"属性,用于表示N的一端也必须是唯一的,在N的一端增加了唯一的约束,即成为单向1-1。基于外键的单向1-1的配置将与无连接表N-1关联的many-to-one增加unique="true"属性即可。

一、模型介绍

一个人(Person)对应一个地址(Address)。

二、实体(省略getter、setter方法)

public class Person11fk {
private int personid;
private String name;
private int age;
private Address11fk address11fk;

public class Address11fk {
private int addressid;
private String addressdetail;

三、表模型

address_11fk;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+

person_11fk;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| addressId | int(11) | YES | UNI | NULL | |
+-----------+--------------+------+-----+---------+----------------+

四、映射方法:

在Person中添加Address属性,映射配置为:
<!--用来映射关联PO column是Address在该表中的外键列名,增加unique变成“1-1”-->
<many-to-one name="address11fk" column="addressId" unique="true"/>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_1_fk.Address11fk" table="ADDRESS_11fk">
<id name="addressid">
<generator class="identity"/>
</id>
<property name="addressdetail"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<class name="com.lavasoft.dx._1_1_fk.Person11fk" table="PERSON_11fk">
<id name="personid">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="age"/>
<!--用来映射关联PO column是Address在该表中的外键列名,增加unique变成“1-1”-->
<many-to-one name="address11fk" column="addressId" unique="true"/>
</class>
</hibernate-mapping>

五、测试方法

public class Test_11fk {
public static void main(String[] args){
Person11fk p1=new Person11fk();

p1.setAge(21);
p1.setName("p1");

Address11fk add1=new Address11fk();
add1.setAddressdetail("。。。。。");

p1.setAddress11fk(add1);

Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(p1);
tx.commit();
HibernateUtil.closeSession();
}
}

六、测试结果

1) :正常保存. 推荐这么干!
session.save(add1);
session.save(p1);

Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)

2) :正常保存.
session.save(p1);
session.save(add1);

Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
Hibernate: update PERSON_11fk set name=?, age=?, addressId=? where personid=?

3) :正常保存.
// session.save(p1);
session.save(add1);

Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)

4) : 发生异常,不能保存.
session.save(p1);
// session.save(add1);

Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
Exception in thread "main" org.hibernate.TransientObjectException: com.lavasoft.dx._1_1_fk.Address11fk

Hibernate关联关系映射实例速查

Hibernate的映射关系很多,也比较复杂,也很容易忘记。这个基本上占据了Hibernate学习的七成时间。熟悉这些映射模型,需要大量的实践才能掌握。下面是我对Hibernate关联关系映射的一个总结,放到blog上一是自己查看方便,二来也可以和更多Hibernate开发人员交流分享。希望各位多多留言哦:)。
本文主要参考夏昕翻译的“Hibernate参考文档 V3.12”,也在附件中给出了。

本文的模块较多,映射关系部分分为一下模块:

Hibernate关联关系映射目录

├─单向关联
│ ├─ 一对一外键单向关联
│ ├─ 一对一主键单向关联
│ ├─ 一对一连接表单向关联
│ ├─ 一对多外键单向关联
│ ├─ 一对多连接表单向关联
│ ├─ 多对一外键单向关联
│ ├─ 多对一连接表单向关联
│ └─ 多对多单向关联
└─双向关联
├─ 一对一外键双向关联
├─ 一对一主键双向关联
├─ 一对一连接表双向关联
├─ 一对多外键双向关联
├─ 一对多连接表双向关联
└─ 多对多双向关联

比如:类A和类B,其中B继承A。那么在a.hbm.xml可以这么写:
[code:1] <class name="A" table="a">
<id name="A_id" column="a_id" type="long">
<generator class="assigned"/>
</id>
<property name="A_property"/>
<joined-subclass name="B" table="b">
<key column="a_id"/>
<property name="B_property" />
</joined-subclass>
</class>[/code:1]
即:Class A {A_id, A_property}
Class B {B_property}(实际上还有从A继承二来的A_id, A_property)
表模式: table A ==> a_id, a_property
table B ==> a_id, b_property
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: