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

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

java之hibernate之组合主键映射的更多相关文章

  1. hibernate笔记--组合主键映射方法

    一个数据库表中其主键有可能不止一个属性,同样映射到实体类中,可能有两个或多个属性共同配置成为一个主键,假设一个实体类Score,其主键有两个属性stuId(学生编号)和subjectId(科目编号), ...

  2. Hibernate 组合主键映射

    在开发过程中创建数据库表时,有时候会发现单纯的创建一个主键是不可行的,有时候就需要多个字段联合保持唯一,本文讲述如何创建组合主键的映射. 例如:记录一个班的考试成绩.学生跟科目是多对多的关系,只有一个 ...

  3. hibernate中基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同

    基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同,主要区别是在配置映射文件上会有区别 两个持久化类为Manager和Department 1:基于主键映射1-1关联关系 1)使用其他持久化 ...

  4. Hibernate 中 联合主键映射 组合关系映射 大对象映射(或者说文本大对象,二进制数据大对象)

    Clob:文本大对象,最长4G Blob:二进制数据大对象,最长4G util: public class HibUtil { private static SessionFactory sessio ...

  5. java之hibernate之基于主键的双向一对一关联映射

    这篇 基于主键的双向一对一关联映射 1.依然考察人和身份证的一对一关系,如果采用主键关联,那么其表结构为: 2.类结构 Person.java public class Person implemen ...

  6. java之hibernate之基于主键的单向一对一关联映射

    这篇讲 基于主键的单向一对一关联映射 1.依然考察人和身份证的一对一关系,如果采用主键关联,那么其表结构应该为: 2.类结构 Person.java public class Person imple ...

  7. Hibernate之基于主键映射的一对一关联关系

    1. 基于主键的映射策略:指一端的主键生成器使用foreign策略,表明根据"对方"的主键来生成自己的主键,自己并不能独立生成主键.并用<param> 子元素指定使用当 ...

  8. hibernate 注解 联合主键映射

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将 该类注解 ...

  9. hibernate 联合主键生成机制(组合主键XML配置方式)

    hibernate 联合主键生成机制(组合主键XML配置方式)   如果数据库中用多个字段而不仅仅是一个字段作为主键,也就是联合主键,这个时候就可以使用hibernate提供的联合主键生成策略. 具体 ...

随机推荐

  1. java 从 PKCS12(比如pfx格式)证书中提取私钥证书(PrivateKey)和受信任的公钥证书(X509Certificate)的序列号(SerialNumber)

    import lombok.Cleanup; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; impor ...

  2. Proj.4 升级新版本5.x和6.x

    目录 Proj.4 升级新版本5.x和6.x 0.缘起 1.5.x和6.x更新情况简述 PROJ 5.x 更新 PROJ 6.x 更新 2.从PROJ.4向新版本迁移 迁移到5.x版本 迁移到6.x版 ...

  3. java合并多个word 2007 文档 基于docx4j

    参考文章:http://dh.swzhinan.com/post/185.html 引入的jar包 <dependency> <groupId>org.docx4j</g ...

  4. Python3基础 from...import 局部导入

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  5. 通过case when实现SQL 多个字段合并为一列值

    with tt as (select A.GID, CASE WHEN A.IsApp='是' THEN 'APP' else '' end 'APP', CASE WHEN A.IsSmallApp ...

  6. Linux部署springboot项目,两种方式

    部署jar包(官方推荐) 在linux服务器上运行Jar文件时通常的方法是: $ java -jar test.jar 这种方式特点是ssh窗口关闭时,程序中止运行.或者是运行时没法切出去执行其他任务 ...

  7. 【GMT43智能液晶模块】例程二十二:USB_CDC实验——高速数据传输

    源代码下载链接: 链接:https://pan.baidu.com/s/10KOWONWbNYlonyuX0W0Mcg 提取码:ggpo 复制这段内容后打开百度网盘手机App,操作更方便哦 GMT43 ...

  8. EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案之使用RTSP流判断摄像机设备是否在线以及快照抓取

    背景分析 熟知EasyNVR产品的小伙伴都知道,通过纯Web化的交互方式,只要配置出摄像机的IP.端口.用户名.密码等信息,就可以将地址进行通道配置完成,即可将设备接入.如果设备支持Onvif协议,E ...

  9. 大数据 -- zookeeper和kafka集群环境搭建

    一 运行环境 从阿里云申请三台云服务器,这里我使用了两个不同的阿里云账号去申请云服务器.我们配置三台主机名分别为zy1,zy2,zy3. 我们通过阿里云可以获取主机的公网ip地址,如下: 通过secu ...

  10. Ubuntu tricks

    linux 复制文件夹内所有文件到另一个文件夹 cp -Rf /home/user1/* /root/temp/ 将 /home/user1目录下的所有东西拷到/root/temp/下而不拷贝user ...