• 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 }

     

    一颗平常心,踏踏实实,平静对待一切
  • 相关阅读:
    MySQL数据库表的设计和优化(上)
    MySQL性能优化最佳实践20条
    MySQL高性能优化指导思路
    MySQL 5.6 my.cnf优化后的标准配置(4核 16G Centos6.5 x64)
    MySQL优化之索引优化
    MySQL优化之SQL语句优化
    MySQL优化之配置参数调优
    Apache的ab测试
    FastCGI模式下安装Xcache
    除了用作缓存数据,Redis还可以做这些
  • 原文地址:https://www.cnblogs.com/hanyuan/p/2653411.html
Copyright © 2020-2023  润新知