`
haierboos
  • 浏览: 440140 次
文章分类
社区版块
存档分类
最新评论

eclipse + JBoss 5 + EJB3开发指南(7):实现Entity Bean的一对一(on

 
阅读更多

本文为原创,如需转载,请注明作者和出处,谢谢!

一对一映射是很常用的。在一般情况下,一个主表通过外键和从表形成一对一的关系。在EJB3中使用@OneToOne注释来映射。一对一关系除了使用外键进行关联外,也可以采用共享主键的方式连接两个表。先看看如下两个表的结构:

图1 t_customers

图2 t_referees

t_customers和t_referees表形成了一对一的关系。t_customers表通过referee_id与t_referees表相连。与t_customers表对应的实体Bean的代码如下:

Code:
  1. packageentity;
  2. importjava.util.Collection;
  3. importjavax.persistence.Entity;
  4. importjavax.persistence.FetchType;
  5. importjavax.persistence.GeneratedValue;
  6. importjavax.persistence.GenerationType;
  7. importjavax.persistence.Id;
  8. importjavax.persistence.JoinColumn;
  9. importjavax.persistence.OneToOne;
  10. importjavax.persistence.Table;
  11. @Entity
  12. @Table(name="t_customers")
  13. publicclassCustomer
  14. {
  15. privateintid;
  16. privateStringname;
  17. privateRefereereferee;
  18. @Id
  19. @GeneratedValue(strategy=GenerationType.IDENTITY)
  20. publicintgetId()
  21. {
  22. returnid;
  23. }
  24. publicvoidsetId(intid)
  25. {
  26. this.id=id;
  27. }
  28. publicStringgetName()
  29. {
  30. returnname;
  31. }
  32. publicvoidsetName(Stringname)
  33. {
  34. this.name=name;
  35. }
  36. @OneToOne
  37. publicRefereegetReferee()
  38. {
  39. returnreferee;
  40. }
  41. publicvoidsetReferee(Refereereferee)
  42. {
  43. this.referee=referee;
  44. }
  45. }

从上面的代码可以看出,getReferee方法使用了@OneToOne进行设置。在装载Customer对象的同时,Referee对象会被同时装 载,而默认的外键字段就是Customer类中的referee属性名 + "_" + id,也就是referee_id。下面看一下与t_referees表对应的实体Bean代码:

Code:
  1. packageentity;
  2. importjavax.persistence.Entity;
  3. importjavax.persistence.GeneratedValue;
  4. importjavax.persistence.GenerationType;
  5. importjavax.persistence.Id;
  6. importjavax.persistence.JoinColumn;
  7. importjavax.persistence.OneToOne;
  8. importjavax.persistence.Table;
  9. @Entity
  10. @Table(name="t_referees")
  11. publicclassReferee
  12. {
  13. privateintid;
  14. privateStringname;
  15. privateCustomercustomer;
  16. @OneToOne(mappedBy="referee")
  17. publicCustomergetCustomer()
  18. {
  19. returncustomer;
  20. }
  21. publicvoidsetCustomer(Customercustomer)
  22. {
  23. this.customer=customer;
  24. }
  25. @Id
  26. @GeneratedValue(strategy=GenerationType.IDENTITY)
  27. publicintgetId()
  28. {
  29. returnid;
  30. }
  31. publicvoidsetId(intid)
  32. {
  33. this.id=id;
  34. }
  35. publicStringgetName()
  36. {
  37. returnname;
  38. }
  39. publicvoidsetName(Stringname)
  40. {
  41. this.name=name;
  42. }
  43. }

Referee类使用了customer属性映射了Customer对象,实际上,这是一个双向的one-to-one映射。这时,在Referee类的 customer属性的getter方法的@OneToOne注释中,需要使用mappedBy属性来指定主表(Customer)中的映射从表的属性名 (referee)。
我们可以使用下面的代码进行测试:

Code:
  1. System.out.println(em.find(Referee.class,1).getCustomer().getName());
  2. Customercustomer=newCustomer();
  3. customer.setName("微软");
  4. Refereereferee=newReferee();
  5. referee.setName("赵军");
  6. em.persist(referee);
  7. customer.setReferee(referee);
  8. em.persist(customer);

如果要覆盖默认的名键名,例如,外键名为referee1_id,可以两种方法使EJB3容器使用新的外键:
1. 修改Customer类中的referee属性的getter和setter方法为getReferee1和setReferee1,并将Referee类中mappedBy属性的值修改成referee1。
2. 使用@JoinColumn注释设置新的外键名,这种方法只需要修改Customer类的getReferee方法上面注释即可,代码如下:

Code:
  1. @OneToOne
  2. @JoinColumn(name="referee1_id")
  3. publicRefereegetReferee()
  4. {
  5. returnreferee;
  6. }

one-to-one关系还可以共享主键,也就是一个表的主键的值依赖于另一个表的主键的值。因此,在这种情况下,就不再需要t_customers表中 的referee_id字段了。由于t_referees表的id字段值依赖于t_customers表的id字段值,因此,需要将t_referees 表中的id字段值的自增类型去掉。
在EJB3中使用@PrimaryKeyJoinColumn注释来实现主键的共享。首先需要修改Customer类的getReferee方法上方的注释,修改后的代码如下:

Code:
  1. @OneToOne(cascade=CascadeType.ALL)
  2. @PrimaryKeyJoinColumn
  3. publicRefereegetReferee()
  4. {
  5. returnreferee;
  6. }


然后要修改Referee类中的getCustomer和getId方法上方的注释,修改后的代码如下:

Code:
  1. @OneToOne
  2. @PrimaryKeyJoinColumn
  3. publicCustomergetCustomer()
  4. {
  5. returncustomer;
  6. }
  7. @Id
  8. @GeneratedValue(generator="pkGenerator")
  9. @GenericGenerator(name="pkGenerator",strategy="foreign",
  10. parameters=@Parameter(name="property",value="customer"))
  11. publicintgetId()
  12. {
  13. returnid;
  14. }

其中@GenericGenerator注释表示这个id属性是外键,并且依赖于customer属性对应的实体Bean的id属性值(主键值)。
另外还要注意一点,由于t_referees表的id的自增类型已经去掉,而且该值依赖于t_customers表的id字段值,因此,就不能直接持久化Referee对象了,而在持久化Customer对象的同时,EJB3容器会自动将Referee持久化的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics