hibernate中使用组件作为标识符

 在数据库设计的时候,有时候难免会将主键设置为联合主键(即唯一标识某一实体的属性不止一个).那么在hibernate中将怎么处理组件作为主键呢?

 首先创建一个组件类,以Student为例,如果你想将学生的ID和Name作为联合主键,那么你的组件类应该这样写:

 1 import java.io.Serializable;
 2 
 3 @SuppressWarnings("serial")
 4 //组件类必须实现Serializable接口,并且要重写equals和hashcode方法
 5 //重写这两个方法的时候还不能直接使用父类的方法,其逻辑必须与数据中
 6 //存储数据的逻辑一致
 7 public class StudentPk implements Serializable{
 8     private int id;
 9     private String name;
10     
11     public int getId() {
12         return id;
13     }
14     public void setId(int id) {
15         this.id = id;
16     }
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     
24     @Override
25     public boolean equals(Object o){
26         if(o instanceof StudentPk){
27             StudentPk pk = (StudentPk)o;
28             if(this.id==pk.getId()&&this.name.equals(pk.getName())){
29                 return true;
30             }
31         }
32         return false;
33     }
34     
35     @Override
36     public int hashCode(){
37         return new StudentPk().hashCode();
38     }
39 }

 其次就是创建你的student类:

 1 import com.nenu.hibernate.StudentPk;
 2 
 3 public class Student {
 4     private StudentPk pk;
 5     private int age;
 6     private String phoneNumber;
 7     
 8     public StudentPk getPk() {
 9         return pk;
10     }
11     public void setPk(StudentPk pk) {
12         this.pk = pk;
13     }
14     public int getAge() {
15         return age;
16     }
17     public void setAge(int age) {
18         this.age = age;
19     }
20     public String getPhoneNumber() {
21         return phoneNumber;
22     }
23     public void setPhoneNumber(String phoneNumber) {
24         this.phoneNumber = phoneNumber;
25     }
26 }

 接下来,如果你要在XML进行配置,那么在Student.hbm.xml文件中就应该这样写:

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 5 
 6 <hibernate-mapping package="com.nenu.hibernate">
 7     <class name="Student" table="_student">
 8         <composite-id name="pk" class="com.nenu.hibernate.StudentPk">
 9             <key-property name="id" column="_id"></key-property>
10             <key-property name="name" column="_name"></key-property>
11         </composite-id>
12         
13         <property name="age" column="_age"></property>
14         <property name="phoneNumber" column="_phoneNumber"></property>
15     </class>
16 </hibernate-mapping>

 之后就是写一个测试类,如下:

 1 package com.nenu.hibernate;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.cfg.Configuration;
 6 import com.nenu.hibernate.StudentPk;
 7 import com.nenu.hibernate.Student;
 8 
 9 public class StudentTest {
10     public static void main(String[] args) {
11         StudentPk pk = new StudentPk();
12         pk.setId(1);
13         pk.setName("Dave");
14         
15         Student student = new Student();
16         student.setPk(pk);
17         student.setAge(15);
18         student.setPhoneNumber("123456789");
19         
20         SessionFactory sf = new Configuration().configure().buildSessionFactory();
21         Session session = sf.openSession();
22         session.beginTransaction();
23         session.save(student);
24         session.getTransaction().commit();
25         
26         session.close();
27         sf.close();
28     }
29 }

 运行之后;查询数据库就会有如下结果:

 

 如果是使用annotation,那么查阅hibernate--annotation的参考文档就可以知道,annotation提供了三种使用组件作为标识符的注解:

   

 下面就演示第一种方法(另外两种可以参考annotation的参考文档).首先将我的组件类(StudentPk)注解为@Embeddable:

 

 1 package com.nenu.hibernate;
 2 
 3 import java.io.Serializable;
 4 
 5 import javax.persistence.Embeddable;
 6 
 7 @SuppressWarnings("serial")
 8 @Embeddable
 9 public class StudentPk implements Serializable{
10     private int id;
11     private String name;
12     
13     public int getId() {
14         return id;
15     }
16     public void setId(int id) {
17         this.id = id;
18     }
19     public String getName() {
20         return name;
21     }
22     public void setName(String name) {
23         this.name = name;
24     }
25     
26     @Override
27     public boolean equals(Object o){
28         if(o instanceof StudentPk){
29             StudentPk pk = (StudentPk)o;
30             if(this.id==pk.getId()&&this.name.equals(pk.getName())){
31                 return true;
32             }
33         }
34         return false;
35     }
36     
37     @Override
38     public int hashCode(){
39         return new StudentPk().hashCode();
40     }
41 }

 然后将组件的属性注解为@id.

 1 package com.nenu.hibernate;
 2 
 3 import javax.persistence.Id;
 4 
 5 import com.nenu.hibernate.StudentPk;
 6 
 7 public class Student {
 8     private StudentPk pk;
 9     private int age;
10     private String phoneNumber;
11     
12     @Id
13     public StudentPk getPk() {
14         return pk;
15     }
16     public void setPk(StudentPk pk) {
17         this.pk = pk;
18     }
19     public int getAge() {
20         return age;
21     }
22     public void setAge(int age) {
23         this.age = age;
24     }
25     public String getPhoneNumber() {
26         return phoneNumber;
27     }
28     public void setPhoneNumber(String phoneNumber) {
29         this.phoneNumber = phoneNumber;
30     }
31 }

 最后就是创建测试类:

 1 import org.hibernate.Session;
 2 import org.hibernate.SessionFactory;
 3 import org.hibernate.cfg.AnnotationConfiguration;
 4 import org.junit.After;
 5 import org.junit.AfterClass;
 6 import org.junit.Before;
 7 import org.junit.BeforeClass;
 8 import org.junit.Test;
 9 
10 import com.nenu.hibernate.Student;
11 import com.nenu.hibernate.StudentPk;
12 
13 public class studentTest {
14     public static SessionFactory sf = null;
15     
16     @BeforeClass
17     public static void testBefore(){
18          sf = new AnnotationConfiguration().configure().buildSessionFactory();
19     }
20 
21     @Before
22     public void testBe(){
23         System.out.println("即将开始测试......");
24     }
25     
26     @Test
27     public void test() {
28         StudentPk pk =  new StudentPk();
29         pk.setId(1);
30         pk.setName("hibernate");
31 
32         Student student = new Student();
33         student.setPk(pk);
34         student.setAge(22);
35         student.setPhoneNumber("123456789");
36         
37         Session session = sf.openSession();
38         session.beginTransaction();
39         session.save(student);
40         session.getTransaction().commit();
41         session.close();
42     }
43     
44     @After
45     public void testAf(){
46         System.out.println("测试完毕......");
47     }
48     @AfterClass
49     public static void testAfter(){
50         sf.close();
51     }
52 }

 查询数据库;可以看到测试成功:

 可以看到,使用annotation的确方便许多.个人更加偏向于使用annotation.

hibernate中使用组件作为标识符,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。