Hibernate_复合主键的用法和关键

复合主键在表中有多个属性共同确定一个元素,对应到实体类中就有多个属性共同构成主键属性。可以把主键属性分离出来单独成一个类,也可以不分离。

如果不分离,那实体类也是主键类,关键点是主键类要实现Serializable接口,并且重写hashCode和equals方法。

下面的例子是将复合主键分离出来单独成一个类:

StudentKey.java:

 1 /**
 2  * 包含学生表格主键对应的属性,主键类
 3  * 
 4  * @author hanyuan
 5  * @time 2012-8-23 下午09:21:51
 6  */
 7 public class StudentKey implements Serializable {
 8     // 学生学号
 9     private long studentId;
10     // 学生姓名
11     private String name;
12 
13     public long getStudentId() {
14         return studentId;
15     }
16 
17     public void setStudentId(long studentId) {
18         this.studentId = studentId;
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28 
29     //重写hashCode和equals方法
30     @Override
31     public int hashCode() {
32         final int prime = 31;
33         int result = 1;
34         result = prime * result + ((name == null) ? 0 : name.hashCode());
35         result = prime * result + (int) (studentId ^ (studentId >>> 32));
36         return result;
37     }
38 
39     @Override
40     public boolean equals(Object obj) {
41         if (this == obj)
42             return true;
43         if (obj == null)
44             return false;
45         if (getClass() != obj.getClass())
46             return false;
47         StudentKey other = (StudentKey) obj;
48         if (name == null) {
49             if (other.name != null)
50                 return false;
51         }
52         else if (!name.equals(other.name))
53             return false;
54         if (studentId != other.studentId)
55             return false;
56         return true;
57     }
58 }

再在实体类Student中将主键类包含进来:

Student.java:

 1 /**
 2  * 对应于student表的实体类,表示学生
 3  * 
 4  * @author hanyuan
 5  * @time 2012-8-23 下午09:20:16
 6  */
 7 public class Student {
 8     private StudentKey studentKey;
 9     private int age;
10     private String address;
11 
12     public StudentKey getStudentKey() {
13         return studentKey;
14     }
15 
16     public void setStudentKey(StudentKey studentKey) {
17         this.studentKey = studentKey;
18     }
19 
20     public int getAge() {
21         return age;
22     }
23 
24     public void setAge(int age) {
25         this.age = age;
26     }
27 
28     public String getAddress() {
29         return address;
30     }
31 
32     public void setAddress(String address) {
33         this.address = address;
34     }
35 
36 }

实体类Student配置文件:

Student.hbm.xml:

 1 <hibernate-mapping>
 2     <class name="com.sunflower.entity.Student" table="student">
 3         <!-- 复合主键 -->
 4         <composite-id name="studentKey" class="com.sunflower.entity.StudentKey">
 5             <key-property name="studentId" type="long"></key-property>
 6             <key-property name="name" type="string"></key-property>
 7         </composite-id>
 8 
 9         <property name="age" type="integer"></property>
10         <property name="address" type="string"></property>
11     </class>
12 </hibernate-mapping>

第4行至第7行是复合主键的配置,如果没有将主键属性分离出来单独成一个主键类,那么就不用加 class="com.sunflower.entity.StudentKey".

Hibernate_根据配置文件反向生成表格 得到:

HibernateUtil.java:

 1 /**
 2  * 解析配置文件,创建session的工具类
 3  * 
 4  * @author hanyuan
 5  * @time 2012-8-23 下午09:42:35
 6  */
 7 public class HibernateUtil {
 8     private static SessionFactory factory;
 9 
10     static {
11         Configuration cfg = null;
12         // 解析配置文件
13         try {
14             cfg = new Configuration().configure();
15         }
16         catch (Exception e) {
17             e.printStackTrace();
18         }
19         factory = cfg.buildSessionFactory();
20     }
21 
22     /**
23      * 打开一个session
24      */
25     public static Session getSession() {
26         Session session = factory.openSession();
27         return session;
28     }
29 
30     /**
31      * 关闭session
32      */
33     public static void closeSession(Session session) {
34         if (null != session)
35             session.close();
36     }
37 }

 第26行中,刚开始写法:Session session = factory.getCurrentSession(), 结果程序报错:session is already closed.

进行测试:

Test.java:

 1 public class Test {
 2 //    // 保存测试
 3 //    public void save() {
 4 //        Session session = HibernateUtil.getSession();
 5 //        Transaction transaction = session.beginTransaction();
 6 //
 7 //        try {
 8 //            StudentKey studentKey = new StudentKey();
 9 //            studentKey.setStudentId(20090124);
10 //            studentKey.setName("任德华");
11 //
12 //            Student student = new Student();
13 //            student.setStudentKey(studentKey);
14 //            student.setAge(22);
15 //            student.setAddress("人民路22号");
16 //            session.save(student);
17 //            transaction.commit();
18 //        }
19 //        catch (Exception e) {
20 //            if (null != transaction)
21 //                transaction.rollback();
22 //            e.printStackTrace();
23 //        }
24 //        finally {
25 //            HibernateUtil.closeSession(session);
26 //        }
27 //    }
28 
29     // 查询测试
30     public void get() {
31         Session session = HibernateUtil.getSession();
32         Transaction transaction = session.beginTransaction();
33 
34         try {
35             StudentKey studentKey = new StudentKey();
36             studentKey.setStudentId(20090121);
37             studentKey.setName("令狐聪");
38 
39             Student student = (Student) session.get(Student.class, studentKey);
40             transaction.commit();
41             
42             System.out.println("name is:" + student.getStudentKey().getName() + "\n" + "address is:" + student.getAddress());
43         }
44         catch (Exception e) {
45             if (null != transaction)
46                 transaction.rollback();
47             e.printStackTrace();
48         }
49         finally {
50             HibernateUtil.closeSession(session);
51         }
52     }
53 
54     public static void main(String[] args) {
55         Test test = new Test();
56 //        test.save();
57         test.get();
58     }
59 }

 

一颗平常心,踏踏实实,平静对待一切
原文地址:https://www.cnblogs.com/hanyuan/p/2653411.html