【hibernate框架】如何配置联合主键-XML与Annotation样例剖析

前端之家收集整理的这篇文章主要介绍了【hibernate框架】如何配置联合主键-XML与Annotation样例剖析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

首先看看什么是联合主键:

联合主键一般以表中的两个或两个以上的元素作为主键。


一般的联合主键,在数据库中设置就可以了。但是,如果你想用hibernate对主键做映射的话,则需要用面向对象的方法去操作它。


那么,如何用面向对象的方法去得到它呢?而又如何以面向对象的方式分配主键呢?


有两种方式:
XML配置联合主键和Annotation配置联合主键。

XML配置联合主键:

操作方式:
把多个主键封装在一个类中。
如Student类,如果以id和name为主键,那么就写一个类(StudentPK),将id和name作为成员变量(private),设置getter和setter方法


在Student.hbm.xml中设置联合主键:

  1. <!--设置联合主键-->
  2. <composite-id name="pk" class="cn.edu.hpu.model.StudentPK">
  3. <key-property name="id"></key-property>
  4. <key-property name="name"></key-property>
  5. </composite-id>
  6. <property name="name"></property>
  7. <property name="age"></property>
方法要继承implements java.io.Serializable接口,实现序列化。
序列化是干什么的?序列化是可以把对象写到硬盘上,或可以通过网络传输对象。
为什么要实现序列化呢?
1、Student在数据库表中可能存在多条记录,这多条记录放在内存中就是多个Student对象,每一个对象都有一个PK联合主键。如果以后系统要做集群,好多服务器要同时对外提供服务,某台服务器出问题了,可以把这台服务器的对象传给另外一个服务器,这时候要实现序列化。
2、加入内存满了,可以使用虚拟内存,就是把硬盘上的一部分空间作为内存来使用。这个时候要把内存放在硬盘中,就要实现序列化。




联合主键类(StudentPK):
  1. package cn.edu.hpu.model;
  2.  
  3.  
  4. public class StudentPK implements java.io.Serializable{
  5. private int id;
  6. private String name;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. //联合主键的实体类一定要重写Object类的equals()和hsahCode()方法
  20. //一系列对象放到内存中,是要做区分的,所以为了保证唯一性,要重写equals()和hsahCode()方法
  21. //下面是改写的方法
  22. @Override
  23. public boolean equals(Object obj) {
  24. if(obj instanceof StudentPK){
  25. StudentPK o=(StudentPK)obj;
  26. if(this.id==o.getId()&&this.name.equals(o.getName())){
  27. return true;
  28. }
  29. }
  30. return false;
  31. }
  32. //为什么要改写hashCode?hashCode是干嘛的?
  33. //如果说我们这个对象被装在内存的哈希表里面,查内容是否相同的时候首先查它的哈希表
  34. //哈希表底层是由数组(往往是链表)实现的。
  35. //如果哈希码相同,对象会被装在同一个位置。
  36. /*假如我们将来写了一个程序,我们要把一系列
  37. * 的Student对象装到哈希表里,这个时候我们要计算Student的哈希码才能
  38. * 装到哈希表里。我不会直接计算Student的哈希码,因为数据库是以主键
  39. * 来区分对象的,所以我应该把主键的哈希码计算出来。
  40. * 假设哈希码为2,我们把对象存到为2的位置。当我们找Student
  41. * 的时候,在找哈希码为2的学生,并找里面equals的对象
  42. * */
  43. @Override
  44. public int hashCode() {
  45. return this.name.hashCode();
  46. }
  47. }

Annotation配置联合主键:

下面是定义联合主键的几种方法
1.将组件类注解为@Embeddable,并将组件的属性注解为@Id。
2.将组件的属性注解为@EmbeddedId。
3.将类注解为@IdClass,并将该实体中所有属于主键的属性都注解为@Id。


方法1:
实体类Teacher:

  1. package cn.edu.hpu.model;
  2.  
  3.  
  4. import java.util.Date;
  5.  
  6.  
  7. import javax.persistence.Column;
  8. import javax.persistence.Entity;
  9. import javax.persistence.EnumType;
  10. import javax.persistence.Enumerated;
  11. import javax.persistence.GeneratedValue;
  12. import javax.persistence.GenerationType;
  13. import javax.persistence.Id;
  14. import javax.persistence.Table;
  15. import javax.persistence.Temporal;
  16. import javax.persistence.TemporalType;
  17.  
  18.  
  19. //‘@+语句’就叫做注解
  20. //@Entity表示这家伙是个实体类
  21.  
  22.  
  23. //@Table(name="_teacher")
  24. //指定实体类对应的表名(如果没有这个表hibernate会自动创建)
  25.  
  26.  
  27. @Entity
  28. @Table(name="_teacher")
  29. public class Teacher {
  30. private teacherPK PK;
  31. private String title;
  32. private Date brithday;
  33. private ZhiCheng zhicheng;
  34. @Id
  35. public teacherPK getPK() {
  36. return PK;
  37. }
  38. public void setPK(teacherPK pK) {
  39. PK = pK;
  40. }
  41. @Enumerated(EnumType.STRING)
  42. public ZhiCheng getZhicheng() {
  43. return zhicheng;
  44. }
  45. public void setZhicheng(ZhiCheng zhicheng) {
  46. this.zhicheng = zhicheng;
  47. }
  48. @Temporal(TemporalType.DATE)
  49. public Date getBrithday() {
  50. return brithday;
  51. }
  52. public void setBrithday(Date brithday) {
  53. this.brithday = brithday;
  54. }
  55. @Column(name="_title")
  56. public String getTitle() {
  57. return title;
  58. }
  59. public void setTitle(String title) {
  60. this.title = title;
  61. }
  62. }



//联合主键类teacherPK:
  1. package cn.edu.hpu.model;
  2.  
  3.  
  4. import javax.persistence.Embeddable;
  5.  
  6.  
  7. //@Embeddable表示是另外一个类的一部分
  8. @Embeddable
  9. public class teacherPK implements java.io.Serializable{
  10. private int id;
  11. private String name;
  12. public int getId() {
  13. return id;
  14. }
  15. public void setId(int id) {
  16. this.id = id;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. @Override
  25. public boolean equals(Object obj) {
  26. if(obj instanceof StudentPK){
  27. StudentPK o=(StudentPK)obj;
  28. if(this.id==o.getId()&&this.name.equals(o.getName())){
  29. return true;
  30. }
  31. }
  32. return false;
  33. }
  34. @Override
  35. public int hashCode() {
  36. return this.name.hashCode();
  37. }
  38. }

//运行测试类后,数据库自己去建立表,而且你会发现id和name都是主键






方法2:
只需要在实体类的主键get方法上加:@EmbeddedId
  1. package cn.edu.hpu.model;
  2.  
  3.  
  4. import java.util.Date;
  5.  
  6.  
  7. import javax.persistence.Column;
  8. import javax.persistence.EmbeddedId;
  9. import javax.persistence.Entity;
  10. import javax.persistence.EnumType;
  11. import javax.persistence.Enumerated;
  12. import javax.persistence.GeneratedValue;
  13. import javax.persistence.GenerationType;
  14. import javax.persistence.Id;
  15. import javax.persistence.Table;
  16. import javax.persistence.Temporal;
  17. import javax.persistence.TemporalType;
  18.  
  19.  
  20. @Entity
  21. @Table(name="_teacher")
  22. public class Teacher {
  23. private teacherPK PK;
  24. private String title;
  25. private Date brithday;
  26. private ZhiCheng zhicheng;
  27. @EmbeddedId
  28. public teacherPK getPK() {
  29. return PK;
  30. }
  31. public void setPK(teacherPK pK) {
  32. PK = pK;
  33. }
  34. @Enumerated(EnumType.STRING)
  35. public ZhiCheng getZhicheng() {
  36. return zhicheng;
  37. }
  38. public void setZhicheng(ZhiCheng zhicheng) {
  39. this.zhicheng = zhicheng;
  40. }
  41. @Temporal(TemporalType.DATE)
  42. public Date getBrithday() {
  43. return brithday;
  44. }
  45. public void setBrithday(Date brithday) {
  46. this.brithday = brithday;
  47. }
  48. @Column(name="_title")
  49. public String getTitle() {
  50. return title;
  51. }
  52. public void setTitle(String title) {
  53. this.title = title;
  54. }
  55. }



方法3:
在实体类上的主键get方法上注解@Id
  1. @Id
  2. public String getName() {
  3. return name;
  4. }
  5. public void setName(String name) {
  6. this.name = name;
  7. }
  8. @Id
  9. @GeneratedValue(strategy=GenerationType.AUTO)
  10. public int getId() {
  11. return id;
  12. }
  13. public void setId(int id) {
  14. this.id = id;
  15. }


在实体类的头来标示主键的类:
  1. @IdClass(value=teacherPK.class)
  2. public class Teacher {......

最常用的是第1和第二种方法


转载请注明出处http://blog.csdn.net/acmman

猜你在找的XML相关文章