一对多和多对一映射原理一致:都是在多的一端加入一个外键指向一的一端
区别在于维护的关系不同:
1、多对一维护的关系是多指向一的关系,若维护了多指向一的关系,加载多的时候就会把一加载上来
2、一对多维护的关系是一指向多的关系,若维护了一指向多的关系,加载一的时候就会把多加载上来
在一端维护关系存在缺陷(可用一对多双向关联映射,解决一端维护关系存在的缺陷):
1、因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系);所以在保存Sudent的时候关系字段classes_id是为null的,若将该关系字段设为非空,则将无法保存数据
2、另外因为Student不维护关系,Classes维护关系,Classes就会发出多余的update语句,保证Classes和Student有关系,这样加载Classes的时候才可以把该Classes对应的学生加载上来
一、单向关联映射
One(维护端:Classes)
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.app.model"> <class name="Classes" table="t_classes"> <id name="id"> <generator class="increment"/> </id> <property name="name"/> <!-- 维护关系: --> <set name="students"> <!-- 往多的一端加个外键 --> <key column="classes_id"></key> <one-to-many class="org.app.model.Student"/> </set> </class> </hibernate-mapping>
To
Many(非维护端:Student)
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.app.model"> <class name="Student" table="t_student"> <id name="id"> <generator class="increment"/> </id> <property name="name"/> </class> </hibernate-mapping>
public void testOneToMany() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); // 关联有方向性,一对多(一依赖多),故先有Student、再有Classes Student student1 = new Student(); student1.setName("name"); session.save(student1); Student student2 = new Student(); student2.setName("name"); session.save(student2); Set<Student> set = new HashSet<Student>(); set.add(student1); set.add(student2); Classese classes = new Classese(); classes.setName("className"); classes.setStudents(set); // 最后保存维护端 session.save(classes); // 先插入两条student // 然后插入一条classes // 再修改两条student(用于维护关系) session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } }
二、双向关联映射
One(维护端:Classes)
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.app.model"> <class name="Classes" table="t_classes"> <id name="id"> <generator class="increment"/> </id> <property name="name"/> <set name="students"inverse=”true”> <!—加上inverse后该端不再维护关系,而是另外一端维护关系 --> <!-- 往多的一端加个外键 --> <key column="classes_id"></key> <one-to-many class="org.app.model.Student"/> </set> </class> </hibernate-mapping>
To
Many(维护端:Student)
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.app.model"> <class name="Student" table="t_student"> <id name="id"> <generator class="increment"/> </id> <property name="name"/> <!-- 维护关系:在多的一端加外键 --> <many-to-one name="classes"column="classes_id"></many-to-one> </class> </hibernate-mapping>
先保存一的一端再保存多的多的一端可避免多发update语句
inverse属性(默认false:本端可维护关系;true:本端不维护关系,交由另一端维护)可用在一对多和多对多双向关联上
一对多关联映射通常在多的一端维护关系,让一的一端失效(设置inverse=true)
inverse pk cascade
inverse是控制方向上的反转,只影响存储
cascade是操作上的连锁反应(同步关联的对象)
时间: 2024-11-06 09:25:20