1.在应用中经常会有主键是由2个或多个字段组合而成的。比如成绩表:
第一种方式:把主键写为单独的类
2.类的设计:studentId,subjectId ,这两个主键是一个组件。所以可以采用组件映射的方式来完成。
主键写为单独类 ResultPk;
ResultPk.java
/** * *组合组件类必须实现序列化接口,只有实现了序列化才能使用 *session的get方法获取对象 */ public class ResultPk implements Serializable{ private int studentId; private int subjectId; public ResultPk() { } public ResultPk(int studentId, int subjectId) { super(); this.studentId = studentId; this.subjectId = subjectId; } public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public int getSubjectId() { return subjectId; } public void setSubjectId(int subjectId) { this.subjectId = subjectId; } }
Result.java
public class Result { private ResultPk pk; private int score; private Date examDate; public Result() { } public Result(ResultPk pk, int score, Date examDate) { super(); this.pk = pk; this.score = score; this.examDate = examDate; } public ResultPk getPk() { return pk; } public void setPk(ResultPk pk) { this.pk = pk; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public Date getExamDate() { return examDate; } public void setExamDate(Date examDate) { this.examDate = examDate; } }
3.映射文件
<hibernate-mapping package="cn.sxt.pojo"> <class name="Result" table="t_result"> <composite-id name="pk" class="ResultPk"> <key-property name="studentId"/> <key-property name="subjectId"/> </composite-id> <property name="score"/> <property name="examDate"/> </class> </hibernate-mapping>
4.测试
public class HibernateTest { /** * 生成数据库表的工具方法 * */ @Test public void testCreateDB(){ Configuration cfg = new Configuration().configure(); SchemaExport se = new SchemaExport(cfg); //第一个参数 是否打印sql脚本 //第二个参数 是否将脚本导出到数据库中执行 se.create(true, true); } /** * 初始化表数据 */ @Test public void testInit(){ Session session = null; Transaction tx = null; try { session = HibernateUtil.getSession(); tx = session.beginTransaction(); ResultPk pk1 = new ResultPk(1, 1); ResultPk pk2 = new ResultPk(1, 2); Result r1 = new Result(pk1, 90, new SimpleDateFormat("yyyy-MM-dd").parse("2016-09-12")); Result r2 = new Result(pk2, 83, new SimpleDateFormat("yyyy-MM-dd").parse("2016-09-22")); session.save(r1); session.save(r2); tx.commit(); } catch (Exception e) { if(tx!=null) tx.rollback(); }finally { HibernateUtil.close(); } } /** */ @Test public void testGetData(){ Session session = HibernateUtil.getSession(); ResultPk pk1 = new ResultPk(1, 1); Result result = (Result)session.get(Result.class, pk1); System.out.println(result.getScore()+"---"+result.getExamDate()); HibernateUtil.close(); } }
第二种方式:直接通过一个类来描述
5.组合主键的第二种实现方式,直接通过一个类来描述
类结构
/** * 在类中有组合主键那么必须实现Serializable接口 * */ public class Result implements Serializable{ private int studentId; private int subjectId; private int score; private Date examDate; public Result() { } public Result(int studentId, int subjectId) { super(); this.studentId = studentId; this.subjectId = subjectId; } public Result(int studentId, int subjectId, int score, Date examDate) { super(); this.studentId = studentId; this.subjectId = subjectId; this.score = score; this.examDate = examDate; } public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public int getSubjectId() { return subjectId; } public void setSubjectId(int subjectId) { this.subjectId = subjectId; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public Date getExamDate() { return examDate; } public void setExamDate(Date examDate) { this.examDate = examDate; } }
6.映射文件
<hibernate-mapping package="cn.sxt.pojo"> <class name="Result" table="t_result"> <!-- 复合主键的映射 --> <composite-id> <key-property name="studentId"/> <key-property name="subjectId"/> </composite-id> <property name="score"/> <property name="examDate"/> </class> </hibernate-mapping>
7.测试
public class HibernateTest { /** * 生成数据库表的工具方法 * */ @Test public void testCreateDB(){ Configuration cfg = new Configuration().configure(); SchemaExport se = new SchemaExport(cfg); //第一个参数 是否打印sql脚本 //第二个参数 是否将脚本导出到数据库中执行 se.create(true, true); } /** * 初始化表数据 */ @Test public void testInit(){ Session session = null; Transaction tx = null; try { session = HibernateUtil.getSession(); tx = session.beginTransaction(); Result r1 = new Result(1,1, 90, new SimpleDateFormat("yyyy-MM-dd").parse("2016-09-12")); Result r2 = new Result(1,2, 83, new SimpleDateFormat("yyyy-MM-dd").parse("2016-09-22")); session.save(r1); session.save(r2); tx.commit(); } catch (Exception e) { if(tx!=null) tx.rollback(); }finally { HibernateUtil.close(); } } /** */ @Test public void testGetData(){ Session session = HibernateUtil.getSession(); Result result = new Result(1, 1); result = (Result)session.get(Result.class, result); System.out.println(result.getScore()+"---"+result.getExamDate()); HibernateUtil.close(); } }
第三种方式:表结构不改变,但是组合主键代表的是外键
8.表结构不改变,但是组合主键代表的是外键
Student.java
public class Student implements Serializable{ private int id; private String name; private int age; public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Subject.java
public class Subject implements Serializable{ private int id; private String name; public Subject() { } public Subject(String name) { super(); this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Result.java
/** * 在类中有组合主键那么必须实现Serializable接口 * */ public class Result implements Serializable{ private Student student; private Subject subject; private int score; private Date examDate; public Result() { } public Result(Student student, Subject subject) { super(); this.student = student; this.subject = subject; } public Result(Student student, Subject subject, int score, Date examDate) { super(); this.student = student; this.subject = subject; this.score = score; this.examDate = examDate; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public Subject getSubject() { return subject; } public void setSubject(Subject subject) { this.subject = subject; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public Date getExamDate() { return examDate; } public void setExamDate(Date examDate) { this.examDate = examDate; } }
9.映射文件
Student.hbm.xml
<hibernate-mapping package="cn.sxt.pojo"> <class name="Student" table="t_student"> <id name="id"> <generator class="native"></generator> </id> <property name="name"/> <property name="age"/> </class> </hibernate-mapping>
Subject.hbm.xml
<hibernate-mapping package="cn.sxt.pojo"> <class name="Subject" table="t_subject"> <id name="id"> <generator class="native"></generator> </id> <property name="name"/> </class> </hibernate-mapping>
Result.hbm.xml
<hibernate-mapping package="cn.sxt.pojo"> <class name="Result" table="t_result"> <!-- 复合主键的映射 --> <composite-id> <key-many-to-one name="student" column="studentId"/> <key-many-to-one name="subject" column="subjectId"/> </composite-id> <property name="score"/> <property name="examDate"/> </class> </hibernate-mapping>
10.测试
public class HibernateTest { /** * 生成数据库表的工具方法 * */ @Test public void testCreateDB(){ Configuration cfg = new Configuration().configure(); SchemaExport se = new SchemaExport(cfg); //第一个参数 是否打印sql脚本 //第二个参数 是否将脚本导出到数据库中执行 se.create(true, true); } /** * 初始化表数据 */ @Test public void testInit(){ Session session = null; Transaction tx = null; try { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); session = HibernateUtil.getSession(); tx = session.beginTransaction(); Student stu1 = new Student("张三疯",150); Student stu2 = new Student("张无忌",15); Subject sub1 = new Subject("太极拳"); Subject sub2 = new Subject("乾坤大罗移"); Result r1 = new Result(stu1, sub1,100,df.parse("1990-08-12")); Result r2 = new Result(stu1, sub2,0,df.parse("1990-08-13")); Result r3 = new Result(stu2, sub1,98,df.parse("1990-08-14")); Result r4 = new Result(stu2, sub2,90,df.parse("1990-08-14")); session.save(stu1); session.save(stu2); session.save(sub1); session.save(sub2); session.save(r1); session.save(r2); session.save(r3); session.save(r4); tx.commit(); } catch (Exception e) { if(tx!=null) tx.rollback(); }finally { HibernateUtil.close(); } } /** */ @Test public void testGetData(){ Session session = HibernateUtil.getSession(); /*Student stu = (Student)session.get(Student.class, 1); Subject sub = (Subject)session.get(Subject.class, 1); Result result = new Result(stu, sub); result = (Result)session.get(Result.class, result);*/ List<Result> list = session.createCriteria(Result.class).list(); for(Result result:list) System.out.println(result.getStudent().getName()+"----"+result.getSubject().getName()+"----"+result.getScore()); HibernateUtil.close(); } }
这里:注释掉的部分是取单个值,而下面的是取列表