hibernate中一种可替代联合主键的设计模式

有如下设计:

存在这样的表结构  学生表、课程表和分数表。

我们可以这样设计,一个学生对应多门课程,一门课程对应多个学生,他们之间是多对多的关系。我们可以建立一个中间表来关联他们,而此时恰巧有一个分数表来帮我充当这2个表的中间表的关系。

我们来分析一下,分数和学生,课程之间是这样的对应关系。一个具体的分数是某个学生、某门课程下的分数,是通过唯一的学生id和唯一的课程id来标识的。

所以,我们可以在score表上设置联合主键(student_id 和course_id),但是联合主键有其不必要的复杂性,我们完全可以通过以下方式,来方便他的设计。

我们在score表中设计一个主键id,在设计一个外键student_id 和course_id.关系图如下

建表语句:

CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` varchar(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 PACK_KEYS=0;
CREATE TABLE `course` (
  `id` int(11) NOT NULL,
  `name` varchar(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 PACK_KEYS=0;
CREATE TABLE `score` (
  `id` int(11) NOT NULL,
  `student_id` int(11) default NULL,
  `course_id` int(11) default NULL,
  `score` int(3) default NULL,
  KEY `student_id` (`student_id`),
  KEY `course_id` (`course_id`),
  CONSTRAINT `score_fk2` FOREIGN KEY (`course_id`) REFERENCES `course` (`id`),
  CONSTRAINT `score_fk1` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 PACK_KEYS=0;

对应的类文件语句如下:

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Student entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "student", catalog = "hibernate")
public class Student implements java.io.Serializable {

	// Fields

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Set<Score> scores = new HashSet<Score>(0);

	// Constructors

	/** default constructor */
	public Student() {
	}

	/** minimal constructor */
	public Student(Integer id) {
		this.id = id;
	}

	/** full constructor */
	public Student(Integer id, String name, Set<Score> scores) {
		this.id = id;
		this.name = name;
		this.scores = scores;
	}

	// Property accessors
	@Id
	@Column(name = "id", unique = true, nullable = false)
	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name = "name", length = 20)
	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "student")
	public Set<Score> getScores() {
		return this.scores;
	}

	public void setScores(Set<Score> scores) {
		this.scores = scores;
	}

}
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Course entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "course", catalog = "hibernate")
public class Course implements java.io.Serializable {

	// Fields

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Set<Score> scores = new HashSet<Score>(0);

	// Constructors

	/** default constructor */
	public Course() {
	}

	/** minimal constructor */
	public Course(Integer id) {
		this.id = id;
	}

	/** full constructor */
	public Course(Integer id, String name, Set<Score> scores) {
		this.id = id;
		this.name = name;
		this.scores = scores;
	}

	// Property accessors
	@Id
	@Column(name = "id", unique = true, nullable = false)
	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name = "name", length = 20)
	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "course")
	public Set<Score> getScores() {
		return this.scores;
	}

	public void setScores(Set<Score> scores) {
		this.scores = scores;
	}

}
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * Score entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "score", catalog = "hibernate")
public class Score implements java.io.Serializable {

	// Fields

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private ScoreId id;
	private Course course;
	private Student student;

	// Constructors

	/** default constructor */
	public Score() {
	}

	/** minimal constructor */
	public Score(ScoreId id) {
		this.id = id;
	}

	/** full constructor */
	public Score(ScoreId id, Course course, Student student) {
		this.id = id;
		this.course = course;
		this.student = student;
	}

	// Property accessors
	@EmbeddedId
	@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "id", nullable = false)), @AttributeOverride(name = "studentId", column = @Column(name = "student_id")), @AttributeOverride(name = "courseId", column = @Column(name = "course_id")), @AttributeOverride(name = "score", column = @Column(name = "score")) })
	public ScoreId getId() {
		return this.id;
	}

	public void setId(ScoreId id) {
		this.id = id;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "course_id", insertable = false, updatable = false)
	public Course getCourse() {
		return this.course;
	}

	public void setCourse(Course course) {
		this.course = course;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "student_id", insertable = false, updatable = false)
	public Student getStudent() {
		return this.student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}

}
时间: 2024-10-17 05:39:48

hibernate中一种可替代联合主键的设计模式的相关文章

《Hibernate学习笔记之三》:联合主键的映射

<Hibernate学习笔记之三>:联合主键的映射 就如在前面所举的例子一样,是使用的id作为唯一的主键,一般情况下我们也只使用唯一的一个属性作为主键,但是在实际中,我们可能会遇到几个属性作为主键的情况,因此,在本篇博文中,就来介绍下,联合主键的映射关系应该如何来做?? 联合主键的映射有两种方式来进行实现. 1.使用映射文件 XXX.bhm.xml 2.使用Annotation Hibernate首先需要使用联合主键的实体类必须实现Serializable接口,即为了使序列能够被序列化进行传输

Hibernate学习笔记(5)联合主键

现在大家都不推荐使用联合主键,关键是因为其需要自己手工维护,比较麻烦.但是一个项目可能因为历史遗留原因,你不得不面对联合主键. Hibernate联合主键问题解决如下: 可以使用一个组件作为一个实体类的标识符.你的组件类必须满足以下要求: (1)它必须实现 java.io.Serializable 接口 (2)它必须重新实现 equals() 和 hashCode() 方法,始终和组合关键字在数据库中的概念保持一致 注意:在 Hibernate3 中,第二个要求并非是 Hibernate 强制必

Hibernate注解映射联合主键的三种主要方式(转载)

转自:http://blog.csdn.net/robinpipi/article/details/7655388 联合主键用hibernate注解映射方式主要有三种:第一.将联合主键的字段单独放在一个类中,该类需要实现Java.io.Serializable接口并重写equals和hascode,再将该类注解为@Embeddable,最后在主类中(该类不包含联合主键类中的字段)保存该联合主键类的一个引用,并生成set和get方法,并将该引用注解为@Id 第二.将联合主键的字段单独放在一个类中,

Hibernate注解映射联合主键的三种主要方式

今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateSessionFactory' defined in class path resource [spring-config/ac-cif-srv-config.xml]: Invocation of init met

hibernate 注解 联合主键映射

联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将 该类注解为@Embeddable,最后在主类中(该类不包含联合主键类中的字段)保存该联合主键类的一个引用,并生成set和get方法,并将该引用注 解为@Id 第二.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,最后 在主类中(该

JPA学习---第十二节:JPA中的联合主键

1.定义实体类,代码如下: (1).将联合主键放到一个类中,代码如下: package learn.jpa.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Embeddable; /** * * 1.必须要有无擦得构造函数 * 2.必须要实现序列接口 * 3.必须重写 equals() 和 hashCode() 方法 * @Embeddable 告诉 jp

Hibernate中联合主键生成策略

一.xml配置联合主键 单独设计一个类,作为主键类,如StudentPK A.实现序列化(Serializable接口) B.重写equals()和hashCode() 为什么要从写equals()和hashCode()方法? hashCode相同的会被存储在hash表的同一位置,当找到特定的hashcode之后,会根据equals()方法判断是否是相同的对象,来查找到对应的数据. 小实验1: (1)创建联合主键类StudentPK package com.zgy.hibernate.model

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

Clob:文本大对象,最长4G Blob:二进制数据大对象,最长4G util: public class HibUtil { private static SessionFactory sessionFactory; static{ //获取配置信息 hibernate.cfg.xml Configuration configuration = new Configuration().configure(); //创建一个 ServiceRegistry的实例 //首先获得其标准建造器,此处用

Hibernate笔记③--集合映射、组合映射、联合主键、查询案例

lazy 懒加载 默认为proxy ? 继承映射 discriminant column="type" type="string" ? 集合映射 生成表的语句: public class DbCreate { ????public static void main(String[] args) { ????????Configuration cfg=new Configuration().configure("/hibernate.cfg.xml"