Hibernate关系映射之many-to-many
2016-07-03 18:08
489 查看
1、建表
2、创建实体类及映射文件
Student.java类
使用多对多注解应该是:
Teacher.java类
被控方注解是:
Student.hbm.xml
Teacher.hbm.xml
hibernate.cfg.xml
3、建立测试用例
测试用例一:
对应的SQL语句是:
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
测试用例二:
对应的SQL语句是:
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
测试用例三:
对应的SQL语句是:
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
通过测试用例发现,两个实体类都进行了级联操作,但是只有将Teacher实体对象添加到Student的teachers属性集合中时才能更新维护中间表。因为Student中的teachers集合的inverse属性是false,使得Student类成为主控方,负责维护关联关系;而Teacher中的students集合的inverse属性为true,使得Teacher类成为被控方,不会维护关联关系。
2、创建实体类及映射文件
Student.java类
public class Student implements java.io.Serializable { // Fields private Integer sid; private String sname; private Set<Teacher> teachers=new HashSet<Teacher>(); // Constructors /** default constructor */ public Student() { } /** full constructor */ public Student(String sname) { this.sname = sname; } // Property accessors public Integer getSid() { return this.sid; } public void setSid(Integer sid) { this.sid = sid; } public String getSname() { return this.sname; } public void setSname(String sname) { this.sname = sname; } public Set<Teacher> getTeachers() { return teachers; } public void setTeachers(Set<Teacher> teachers) { this.teachers = teachers; } }
使用多对多注解应该是:
@ManyToMany @JoinTable(name="teacher_student",joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="tid")}) public Set<Teacher> getTeachers() { return teachers; }
Teacher.java类
public class Teacher implements java.io.Serializable { // Fields private Integer tid; private String tname; private Set<Student> students=new HashSet<Student>(); // Constructors /** default constructor */ public Teacher() { } /** full constructor */ public Teacher(String tname) { this.tname = tname; } // Property accessors public Integer getTid() { return this.tid; } public void setTid(Integer tid) { this.tid = tid; } public String getTname() { return this.tname; } public void setTname(String tname) { this.tname = tname; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } }
被控方注解是:
@ManyToMany(mappedBy="teachers") public Set<Student> getStudents() { return students; }
Student.hbm.xml
<hibernate-mapping> <class name="com.db.Student" table="student" catalog="mydb"> <id name="sid" type="java.lang.Integer"> <column name="sid" /> <generator class="native" /> </id> <property name="sname" type="java.lang.String"> <column name="sname" length="32" /> </property> <!-- 通过table属性告诉hibernate中间表,cascade指明级联操作的类型,inverse属性说明Student实体类是主控方,负责维护关系表 --> <set name="teachers" table="teacher_student" cascade="save-update,delete" inverse="false"> <!-- 通过key属性告诉hibernate在中间表里面查询sid值相应的student记录 --> <key> <column name="sid" not-null="true" /> </key> <!-- 通过column项告诉hibernate对teacher表中查找tid值相应的teacher记录 --> <many-to-many class="com.db.Teacher" column="tid"/> </set> </class> </hibernate-mapping>
Teacher.hbm.xml
<hibernate-mapping> <class name="com.db.Teacher" table="teacher" catalog="mydb"> <id name="tid" type="java.lang.Integer"> <column name="tid" /> <generator class="native" /> </id> <property name="tname" type="java.lang.String"> <column name="tname" length="32" /> </property> <!-- 通过table属性告诉hibernate中间表,cascade指明级联操作的类型,inverse属性说明Teacher实体类是被控方,不负责维护关系表 ,不能触发对象和数据库的同步更新的。--> <set name="students" table="teacher_student" inverse="true" cascade="save-update,delete"> <key> <column name="tid" not-null="true" /> </key> <many-to-many class="com.db.Student" column="sid" /> </set> </class> </hibernate-mapping>
hibernate.cfg.xml
<hibernate-configuration> <session-factory> <property name="dialect"> org.hibernate.dialect.MySQLInnoDBDialect </property> <property name="connection.url"> jdbc:mysql://localhost:3306/mydb </property> <property name="connection.username">root</property> <property name="connection.password">123456</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="myeclipse.connection.profile"> MyDBAccount </property> <property name="show_sql">true</property> <mapping resource="com/db/Student.hbm.xml" /> <mapping resource="com/db/Teacher.hbm.xml" /> </session-factory> </hibernate-configuration>
3、建立测试用例
测试用例一:
public static void main(String[] args) { // TODO Auto-generated method stub Session session=HibernateSessionFactory.getSession(); Student stu1=new Student(); stu1.setSname("StudentAmy"); Teacher t1=new Teacher(); t1.setTname("TeacherSusan"); Teacher t2=new Teacher(); t2.setTname("TeacherLily"); Teacher t3=new Teacher(); t3.setTname("TeacherMaike"); Set<Teacher> teachers=new HashSet<Teacher>(); teachers.add(t1); teachers.add(t2); teachers.add(t3); stu1.setTeachers(teachers); session.save(stu1); session.getTransaction().commit(); }
对应的SQL语句是:
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
测试用例二:
public static void main(String[] args) { // TODO Auto-generated method stub Session session=HibernateSessionFactory.getSession(); Student stu1=new Student(); stu1.setSname("StudentJhon1"); Student stu2=new Student(); stu2.setSname("StudentLihua1"); Teacher t1=new Teacher(); t1.setTname("TeacherJay1"); t1.getStudents().add(stu1); t1.getStudents().add(stu2); session.beginTransaction(); session.save(t1); session.getTransaction().commit(); } }
对应的SQL语句是:
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
测试用例三:
public static void main(String[] args) { // TODO Auto-generated method stub Session session=HibernateSessionFactory.getSession(); Student stu1=new Student(); stu1.setSname("StudentJhon1"); Student stu2=new Student(); stu2.setSname("StudentLihua1"); Teacher t1=new Teacher(); t1.setTname("TeacherJay1"); t1.getStudents().add(stu1); t1.getStudents().add(stu2); stu2.getTeachers().add(t1); session.beginTransaction(); session.save(t1); session.getTransaction().commit(); } }
对应的SQL语句是:
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
通过测试用例发现,两个实体类都进行了级联操作,但是只有将Teacher实体对象添加到Student的teachers属性集合中时才能更新维护中间表。因为Student中的teachers集合的inverse属性是false,使得Student类成为主控方,负责维护关联关系;而Teacher中的students集合的inverse属性为true,使得Teacher类成为被控方,不会维护关联关系。
相关文章推荐
- 我的音乐播放器(3)逻辑代码
- TCP/IP详解学习笔记(9)-TCP协议概述
- TCP/IP详解学习笔记(8)-DNS域名系统
- LeetCode 334 Increasing Triplet Subsequence
- TCP/IP详解学习笔记(7)-广播和多播,IGMP协议
- springmvc文件的上传
- vue-cli需要的包
- TCP/IP详解学习笔记(6)-UDP协议
- EasyUI学习总结(二)——EasyUI布局
- java-并发-Callable、Future和FutureTask
- TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节
- SQL SERVER Study
- NHibernate系列文章十一:NHibernate并发控制
- TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
- js设计模式至观察者模式--不同模块间解耦
- @Test报错,Junit使用注意事项
- mongoVUE 出现“Unable to connect to server 127.0.0.1:27017: 由于目标计算机积极拒绝,无法连接。 127.0.0.1:27017.”
- TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
- 《120医生教您学急救》:内容还是偏专业,心肺复苏显然不应该是仅仅通过看书来学习的。三星推荐
- 计蒜客 菜鸟物流的运输网络