本文为原创,如需转载,请注明作者和出处,谢谢!
上一篇: eclipse + JBoss 5 + EJB3开发指南(6):编写第一个实体Bean程序
一对一映射是很常用的。在一般情况下,一个主表通过外键和从表形成一对一的关系。在EJB3中使用@OneToOne注释来映射。一对一关系除了使用外键进行关联外,也可以采用共享主键的方式连接两个表。先看看如下两个表的结构:
从上面的代码可以看出,getReferee方法使用了@OneToOne进行设置。在装载Customer对象的同时,Referee对象会被同时装载,而默认的外键字段就是Customer类中的referee属性名 + "_" + id,也就是referee_id。下面看一下与t_referees表对应的实体Bean代码:
Referee类使用了customer属性映射了Customer对象,实际上,这是一个双向的one-to-one映射。这时,在Referee类的customer属性的getter方法的@OneToOne注释中,需要使用mappedBy属性来指定主表(Customer)中的映射从表的属性名(referee)。
我们可以使用下面的代码进行测试:
1. 修改Customer类中的referee属性的getter和setter方法为getReferee1和setReferee1,并将Referee类中mappedBy属性的值修改成referee1。
2. 使用@JoinColumn注释设置新的外键名,这种方法只需要修改Customer类的getReferee方法上面注释即可,代码如下:
one-to-one关系还可以共享主键,也就是一个表的主键的值依赖于另一个表的主键的值。因此,在这种情况下,就不再需要t_customers表中的referee_id字段了。由于t_referees表的id字段值依赖于t_customers表的id字段值,因此,需要将t_referees表中的id字段值的自增类型去掉。
在EJB3中使用@PrimaryKeyJoinColumn注释来实现主键的共享。首先需要修改Customer类的getReferee方法上方的注释,修改后的代码如下:
另外还要注意一点,由于t_referees表的id的自增类型已经去掉,而且该值依赖于t_customers表的id字段值,因此,就不能直接持久化Referee对象了,而在持久化Customer对象的同时,EJB3容器会自动将Referee持久化的。
下一篇: eclipse + JBoss 5 + EJB3开发指南(8):实现Entity Bean的一对多(one-to-many)映射
国内最棒的Google Android技术社区(eoeandroid),欢迎访问!
《银河系列原创教程》 发布
《Java Web开发速学宝典》 出版,欢迎定购
上一篇: eclipse + JBoss 5 + EJB3开发指南(6):编写第一个实体Bean程序
一对一映射是很常用的。在一般情况下,一个主表通过外键和从表形成一对一的关系。在EJB3中使用@OneToOne注释来映射。一对一关系除了使用外键进行关联外,也可以采用共享主键的方式连接两个表。先看看如下两个表的结构:
图1 t_customers
图2 t_referees
t_customers和t_referees表形成了一对一的关系。t_customers表通过referee_id与t_referees表相连。与t_customers表对应的实体Bean的代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
entity;
import java.util.Collection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = " t_customers " )
public class Customer
{
private int id;
private Stringname;
private Refereereferee;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId()
{
return id;
}
public void setId( int id)
{
this .id = id;
}
public StringgetName()
{
return name;
}
public void setName(Stringname)
{
this .name = name;
}
@OneToOne
public RefereegetReferee()
{
return referee;
}
public void setReferee(Refereereferee)
{
this .referee = referee;
}
}
import java.util.Collection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = " t_customers " )
public class Customer
{
private int id;
private Stringname;
private Refereereferee;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId()
{
return id;
}
public void setId( int id)
{
this .id = id;
}
public StringgetName()
{
return name;
}
public void setName(Stringname)
{
this .name = name;
}
@OneToOne
public RefereegetReferee()
{
return referee;
}
public void setReferee(Refereereferee)
{
this .referee = referee;
}
}
从上面的代码可以看出,getReferee方法使用了@OneToOne进行设置。在装载Customer对象的同时,Referee对象会被同时装载,而默认的外键字段就是Customer类中的referee属性名 + "_" + id,也就是referee_id。下面看一下与t_referees表对应的实体Bean代码:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = " t_referees " )
public class Referee
{
private int id;
private Stringname;
private Customercustomer;
@OneToOne(mappedBy = " referee " )
public CustomergetCustomer()
{
return customer;
}
public void setCustomer(Customercustomer)
{
this .customer = customer;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId()
{
return id;
}
public void setId( int id)
{
this .id = id;
}
public StringgetName()
{
return name;
}
public void setName(Stringname)
{
this .name = name;
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = " t_referees " )
public class Referee
{
private int id;
private Stringname;
private Customercustomer;
@OneToOne(mappedBy = " referee " )
public CustomergetCustomer()
{
return customer;
}
public void setCustomer(Customercustomer)
{
this .customer = customer;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId()
{
return id;
}
public void setId( int id)
{
this .id = id;
}
public StringgetName()
{
return name;
}
public void setName(Stringname)
{
this .name = name;
}
}
Referee类使用了customer属性映射了Customer对象,实际上,这是一个双向的one-to-one映射。这时,在Referee类的customer属性的getter方法的@OneToOne注释中,需要使用mappedBy属性来指定主表(Customer)中的映射从表的属性名(referee)。
我们可以使用下面的代码进行测试:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
System.out.println(em.find(Referee.
class
,
1
).getCustomer().getName());
Customercustomer = new Customer();
customer.setName( " 微软 " );
Refereereferee = new Referee();
referee.setName( " 赵军 " );
em.persist(referee);
customer.setReferee(referee);
em.persist(customer);
如果要覆盖默认的名键名,例如,外键名为referee1_id,可以两种方法使EJB3容器使用新的外键:
Customercustomer = new Customer();
customer.setName( " 微软 " );
Refereereferee = new Referee();
referee.setName( " 赵军 " );
em.persist(referee);
customer.setReferee(referee);
em.persist(customer);
1. 修改Customer类中的referee属性的getter和setter方法为getReferee1和setReferee1,并将Referee类中mappedBy属性的值修改成referee1。
2. 使用@JoinColumn注释设置新的外键名,这种方法只需要修改Customer类的getReferee方法上面注释即可,代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
@OneToOne
@JoinColumn(name = " referee1_id " )
public RefereegetReferee()
{
return referee;
}
@JoinColumn(name = " referee1_id " )
public RefereegetReferee()
{
return referee;
}
one-to-one关系还可以共享主键,也就是一个表的主键的值依赖于另一个表的主键的值。因此,在这种情况下,就不再需要t_customers表中的referee_id字段了。由于t_referees表的id字段值依赖于t_customers表的id字段值,因此,需要将t_referees表中的id字段值的自增类型去掉。
在EJB3中使用@PrimaryKeyJoinColumn注释来实现主键的共享。首先需要修改Customer类的getReferee方法上方的注释,修改后的代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
@OneToOne(cascade
=
CascadeType.ALL)
@PrimaryKeyJoinColumn
public RefereegetReferee()
{
return referee;
}
然后要修改Referee类中的getCustomer和getId方法上方的注释,修改后的代码如下:
@PrimaryKeyJoinColumn
public RefereegetReferee()
{
return referee;
}
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
@OneToOne
@PrimaryKeyJoinColumn
public CustomergetCustomer()
{
return customer;
}
@Id
@GeneratedValue(generator = " pkGenerator " )
@GenericGenerator(name = " pkGenerator " ,strategy = " foreign " ,
parameters = @Parameter(name = " property " ,value = " customer " ))
public int getId()
{
return id;
}
其中@GenericGenerator注释表示这个id属性是外键,并且依赖于customer属性对应的实体Bean的id属性值(主键值)。
@PrimaryKeyJoinColumn
public CustomergetCustomer()
{
return customer;
}
@Id
@GeneratedValue(generator = " pkGenerator " )
@GenericGenerator(name = " pkGenerator " ,strategy = " foreign " ,
parameters = @Parameter(name = " property " ,value = " customer " ))
public int getId()
{
return id;
}
另外还要注意一点,由于t_referees表的id的自增类型已经去掉,而且该值依赖于t_customers表的id字段值,因此,就不能直接持久化Referee对象了,而在持久化Customer对象的同时,EJB3容器会自动将Referee持久化的。
下一篇: eclipse + JBoss 5 + EJB3开发指南(8):实现Entity Bean的一对多(one-to-many)映射
国内最棒的Google Android技术社区(eoeandroid),欢迎访问!
《银河系列原创教程》 发布
《Java Web开发速学宝典》 出版,欢迎定购
eclipse + JBoss 5 + EJB3开发指南(7):实现Entity Bean的一对一(one-to-one)映射