专栏首页Vincent-yuanjava之hibernate之组合主键映射

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java之hibernate之crud

    Vincent-yuan
  • java之spring之整合ssh

    github地址:https://github.com/Vincent-yuan/spring_ssh

    Vincent-yuan
  • java之struts2之ajax

    1.Ajax 技术在现有开发中使用非常多,大多是做管理类型系统。在servlet中可以使用ajax。在struts2中共还可以使用servlet的方式来实现aj...

    Vincent-yuan
  • Hibernate笔记(二)

    1.一对多的关系映射 对于一的一方: package domain; import java.util.HashSet; import java.util.S...

    lwen
  • 快速排序

    用户2436820
  • 你想过吗,为什么说面向对象最符合人的思维?

    在学习Java的过程中,我觉得面向对象是我遇到的第二个难题(第一个就是配置环境变量,哈哈)。我相信也有很多同胞也在这里被绊脚了吧,今天的话也就是其实也只是作为笔...

    ZackSock
  • struts2+Hibernate实现用户登陆功能

    实现的功能,在登陆页面输入Username和PassWord后,将username和password通过Hibernate匹对数据库是否含有一样的usernam...

    用户1624346
  • Prototype模式简介

    用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式是实现了一个原型接口,该接口用于创建当前对象的克...

    用户2929716
  • java设计模式(15)-观察者模式

    观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知...

    爱敲代码的猫
  • 09(02)总结final,多态,抽象类,接口

    (4)抽象类的练习 A:猫狗案例练习 B:老师案例练习 C:学生案例练习 D:员工案例练习 /* A: 猫狗案例 具体事物:猫,狗 共性:姓名,...

    奋斗蒙

扫码关注云+社区

领取腾讯云代金券