[Hibernate]基于xml和annotation的many-to-many双向关联【学习笔记】

基于xml的many-to-many双向关联的关键配置:

many2many(xml):双向关联
  |--->model
  	|--->Student
  		|--->private Set<Course> courses = new HashSet<Student>();
  	|--->Course
  		|--->private Set<Student> students = new HashSet<Course>();
  |--->*.hbm.xml
  	|--->Student.hbm.xml
  		|---><set name="courses" table="STUDENT_COURSE_1" cascade="save-update,remove">
  		     	<key column="STUDENT_ID" />
  		     	<many-to-many column="COURSE_ID" class="Course" />
  		     </set>
  	|--->Course.hbm.xml
  		|---><set name="students" table="STUDENT_COURSE_1" cascade="save-update,remove" inverse="true">
  				<key column="COURSE_ID" />
  				<many-to-many column="STUDENT_ID" class="Student" />
  		     </set>
  |--->hibernate.cfg.xml
  	|---><mapping resource="model/Student.hbm.xml" />
    |---><mapping resource="model/Course.hbm.xml" />

    注意到Student.hbm.xml和Course.hbm.xml的<set>元素其子元素<key> <many-to-many> 刚好相反,而其中一个有inverse=true的属性。
inverse映射属性究竟是什么:
    双向关联只是在两端正确的设置引用,而hibernate并没有足够的信息去正确地执行insert和update语句以避免违反数据库约束。
inverse属性告诉hibernate忽略这一端,而把这一端看作另一端的镜像mirror,也可以理解为该端被人为地指定为负的导航方向了。
只需记住一个rule:双向关联必须有一端被设置为inverse。 
    在一对多的双向关联中,它必须是多(many)的那一端而多对多的双向关联中,则因为两端并没有差别,所以在哪一端设置为inverse完全取决于自己。


基于annotation的many-to-many双向关联:

先看Student实体类:

package model;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name="STUDENTS_11")
public class Student implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue(strategy=GenerationType.TABLE)
	@Column(name="STUDENT_ID")
	private Long student_id;
	@Column(name="SNAME")
	private String sname;
	@Column(name="GENDER")
	private String gender;
	@Column(name="AGE")
	private int age;
	@ManyToMany(targetEntity=Course.class)
	@JoinTable(name="STUDENT_COURSE_11",schema="hibernate",
			joinColumns={@JoinColumn(name="STUDENT_ID")},
			inverseJoinColumns={@JoinColumn(name="COURSE_ID")}
		)
	@Cascade(value={CascadeType.SAVE_UPDATE,CascadeType.REMOVE})
	private Set<Course> courses = new HashSet<Course>();
	
	public Long getStudent_id() {
		return student_id;
	}
	public void setStudent_id(Long student_id) {
		this.student_id = student_id;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Set<Course> getCourses() {
		return courses;
	}
	public void setCourses(Set<Course> courses) {
		this.courses = courses;
	}
	public static long getSerialversionuid() {
		return serialVersionUID;
	}
	
}

Course实体类:

package model;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="COURSES_11")
public class Course implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue(strategy=GenerationType.TABLE)
	@Column(name="COURSE_ID")
	private Long course_id;
	@Column(name="CNAME")
	private String cname;
	@ManyToMany(mappedBy="courses")
	private Set<Student> students = new HashSet<Student>();
	
	public Long getCourse_id() {
		return course_id;
	}
	public void setCourse_id(Long course_id) {
		this.course_id = course_id;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
	
}
对比两个Entity classes可知基于annotation的many-to-many双向关联的关键配置如下:

many2many(xml):双向关联
  |--->model
  	|--->Student
  		|--->private Set<Course> courses = new HashSet<Student>();
  			@ManyToMany(TargetEntity=Course.class)
  			@JoinTable(name="STUDENT_COURSE_11",schema="hibernate",
			       joinColumns={@JoinColumn(name="STUDENT_ID")},
			       inverseJoinColumns={@JoinColumn(name="COURSE_ID")}
		        )
			@Cascade(value={CascadeType.SAVE_UPDATE,CascadeType.REMOVE})
  	|--->Course
  		|--->private Set<Student> students = new HashSet<Course>();
  			@ManyToMany(mappedBy="courses")
  |--->hibernate.cfg.xml
  	|---><mapping class="model.Student" />
    |---><mapping class="model.Course" />
    注意这里在负的导航方向一端(inverseJoinColumns={@JoinColumn(name="COURSE_ID")}指明了哪一端为负),其集合字段被注解为@ManyToMany(mappedBy="courses").





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值