hibernate one to many

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中


@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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值