java之hibernate之组合主键映射

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();
    }
}

这里:注释掉的部分是取单个值,而下面的是取列表

 

原文地址:https://www.cnblogs.com/Vincent-yuan/p/11210001.html