1. Unidirectional with join table
参考例子
[url=http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html]http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html[/url]
2. Unidirectional with foreign key
PERSON
PERSON_ID
PERSON_NAME
ADDRESS
ADDRESS_ID
ADDRESS_NAME
P_ID
P_ID 字段在ADDRESS表中,但其定义在PERSON entity中
插入数据时,hibernate会生成如下sql
Hibernate: insert into PERSON (PERSON_ID, PERSON_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?)
Hibernate: update ADDRESS set P_ID=? where ADDRESS_ID=?
Hibernate: update ADDRESS set P_ID=? where ADDRESS_ID=?
hibernate doc不建议使用此中连接,参考
[url=http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517]http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517[/url]
3. bidirectional
表结构
PERSON
PERSON_ID
PERSON_NAME
ADDRESS
ADDRESS_ID
ADDRESS_NAME
P_ID
A. many to one 端是owner
B. one to many 端是owner
注意address 中joincolumn 的insertable 和updatable 为false
测试
1. 插入Person及关联的Address, hibernate 生成的的sql 语句为
many to one 端为owner时
one to many 端为owner时
2. 删除Address时,
many to one 端为owner时
one to many 端为owner时
3. 删除Person同删除Address相同
显然,one to many 端为owner时,会生成更多sql, 故hibernate doc有如下说明:
[quote]This solution is obviously not optimized from the number of needed statements[/quote]
参考:
[url]http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e949[/url]
参考例子
[url=http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html]http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html[/url]
2. Unidirectional with foreign key
PERSON
PERSON_ID
PERSON_NAME
ADDRESS
ADDRESS_ID
ADDRESS_NAME
P_ID
P_ID 字段在ADDRESS表中,但其定义在PERSON entity中
@Entity
@Table(name = "PERSON")
public class Person {
private Integer id;
private String name;
private Set<Address> addressSet = new HashSet<Address>(0);
public Person() {
}
public Person(String name, Set<Address> addSet) {
this.name = name;
this.addressSet = addSet;
}
@Id
@GeneratedValue
@Column(name = "PERSON_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "PERSON_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "P_ID")
public Set<Address> getAddressSet() {
return addressSet;
}
public void setAddressSet(Set<Address> addressSet) {
this.addressSet = addressSet;
}
@Override
public String toString() {
return this.id + "\t" + this.name;
}
}
@Entity
@Table(name = "ADDRESS")
public class Address {
private Integer addressId;
private String name;
public Address()
{
}
public Address(String name)
{
this.name = name;
}
@Id
@GeneratedValue
@Column(name = "ADDRESS_ID")
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
@Column(name = "ADDRESS_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return this.addressId + "\t" + this.name;
}
}
插入数据时,hibernate会生成如下sql
Hibernate: insert into PERSON (PERSON_ID, PERSON_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?)
Hibernate: update ADDRESS set P_ID=? where ADDRESS_ID=?
Hibernate: update ADDRESS set P_ID=? where ADDRESS_ID=?
hibernate doc不建议使用此中连接,参考
[url=http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517]http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517[/url]
3. bidirectional
表结构
PERSON
PERSON_ID
PERSON_NAME
ADDRESS
ADDRESS_ID
ADDRESS_NAME
P_ID
A. many to one 端是owner
@Entity
@Table(name = "PERSON")
public class Person {
private Integer id;
private String name;
private Set<Address> addressSet = new HashSet<Address>(0);
public Person() {
}
public Person(String name, Set<Address> addSet) {
this.name = name;
this.addressSet = addSet;
}
@Id
@GeneratedValue
@Column(name = "PERSON_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "PERSON_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, [color=red]mappedBy = "person"[/color])
public Set<Address> getAddressSet() {
return addressSet;
}
public void setAddressSet(Set<Address> addressSet) {
this.addressSet = addressSet;
}
@Override
public String toString() {
return this.id + "\t" + this.name;
}
}
@Entity
@Table(name = "ADDRESS")
public class Address {
private Integer addressId;
private String name;
private Person person;
public Address()
{
}
public Address(String name)
{
this.name = name;
}
@Id
@GeneratedValue
@Column(name = "ADDRESS_ID")
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
@Column(name = "ADDRESS_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "P_ID")
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return this.addressId + "\t" + this.name;
}
}
B. one to many 端是owner
注意address 中joincolumn 的insertable 和updatable 为false
@Entity
@Table(name = "PERSON")
public class Person {
private Integer id;
private String name;
private Set<Address> addressSet = new HashSet<Address>(0);
public Person() {
}
public Person(String name, Set<Address> addSet) {
this.name = name;
this.addressSet = addSet;
}
@Id
@GeneratedValue
@Column(name = "PERSON_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "PERSON_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "P_ID")
public Set<Address> getAddressSet() {
return addressSet;
}
public void setAddressSet(Set<Address> addressSet) {
this.addressSet = addressSet;
}
@Override
public String toString() {
return this.id + "\t" + this.name;
}
}
@Entity
@Table(name = "ADDRESS")
public class Address {
private Integer addressId;
private String name;
private Person person;
public Address()
{
}
public Address(String name)
{
this.name = name;
}
@Id
@GeneratedValue
@Column(name = "ADDRESS_ID")
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
@Column(name = "ADDRESS_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "person_fk", insertable=false, updatable=false)
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return this.addressId + "\t" + this.name;
}
}
测试
1. 插入Person及关联的Address, hibernate 生成的的sql 语句为
many to one 端为owner时
Hibernate: insert into PERSON (PERSON_ID, PERSON_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME, person_fk) values (null, ?, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME, person_fk) values (null, ?, ?)
one to many 端为owner时
Hibernate: insert into PERSON (PERSON_ID, PERSON_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?)
Hibernate: insert into ADDRESS (ADDRESS_ID, ADDRESS_NAME) values (null, ?)
Hibernate: update ADDRESS set person_fk=? where ADDRESS_ID=?
Hibernate: update ADDRESS set person_fk=? where ADDRESS_ID=?
2. 删除Address时,
many to one 端为owner时
Hibernate: delete from ADDRESS where ADDRESS_ID=?
Hibernate: delete from ADDRESS where ADDRESS_ID=?
Hibernate: delete from PERSON where PERSON_ID=?
one to many 端为owner时
Hibernate: update ADDRESS set person_fk=null where person_fk=?
Hibernate: delete from ADDRESS where ADDRESS_ID=?
Hibernate: delete from ADDRESS where ADDRESS_ID=?
Hibernate: delete from PERSON where PERSON_ID=?
3. 删除Person同删除Address相同
显然,one to many 端为owner时,会生成更多sql, 故hibernate doc有如下说明:
[quote]This solution is obviously not optimized from the number of needed statements[/quote]
参考:
[url]http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e949[/url]