一对多关联关系映射(one to many+双向)

一对多关联关系映射(one to many+双向)(见教程23)
hihernate一对多关联映射(双向Classes<----->Student)

一对多双向关联映射:
* 在一一端的集合上使用<key>,在对方表中加入一个外键指向一一端
* 在多一端采用<many-to-one>
注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段的错误
如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,对classid为空这个问题也是个问题,所以我们一般在多
的一端来维护关联关系,这样就不会发出多于的update语句

关于inverse属性:
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,
默认inverse为false,所以我们可以从”一“一端和”多“一端维护关联关系,
如果设置成inverse为true,则我们只能从多一端来维护关联关系
注意:inverse属性,只影响数据的存储,也就是持久化
inverse和cascade
* inverse是关联关系的控制方向
* cascade操作上的连锁反应 


我们还是以班级和学生为例来说明这个问题:
第一步建立班级和学生的实体类:
班级实体类为:
public class Classes {
private int id;
private String name;
private Set students; //持有学生类的集合
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 Set getStudents() {
return students;
}

public void setStudents(Set students) {
this.students = students;
}
}

学生的实体类:
public class Student {
private int id;
private String name;
private Classes classes;//持有班级的引用

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 Classes getClasses() {
return classes;
}

public void setClasses(Classes classes) {
this.classes = classes;
}
}




第二步:写实体类的映射文件:
class的映射文件是:
<hibernate-mapping package="com.bjsxt.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" inverse="true" cascade="all">//设置inverse属性,inverse默认的值为false,是还允许在一的一端来维护这个关系
若设为true,作用是使一的一端失效,让多的一端来维护,目的是为了避免多于发出update和classid为空时存不进去的错误。这样不论采用什么方式存,都会使用多的一端来维护
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>

student段的映射文件是:
<hibernate-mapping> <class name="com.bjsxt.hibernate.Student" table="t_student"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <many-to-one name="classes" column="classesid"/>//这个字段的名字必须和那边的key中的字段名字一样,原因见教程23.这说不清楚 </class> </hibernate-mapping>


第三步写hibernate的配置文件:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_one2many_1</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">bjsxt</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="com/bjsxt/hibernate/Classes.hbm.xml"/>
<mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>



第四步写测试代码:
public class One2ManyTest extends TestCase { public void testSave2() {//在多的一端存 Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Classes classes = new Classes(); classes.setName("尚学堂"); session.save(classes); Student student1 = new Student(); student1.setName("10"); student1.setClasses(classes); session.save(student1); Student student2 = new Student(); student2.setName("祖儿"); student2.setClasses(classes); session.save(student2); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } public void testSave3() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Classes classes = new Classes(); classes.setName("尚学堂"); Student student1 = new Student(); student1.setName("10"); student1.setClasses(classes); Student student2 = new Student(); student2.setName("祖儿"); student2.setClasses(classes); Set students = new HashSet(); students.add(student1); students.add(student2); classes.setStudents(students); //可以正确保存 session.save(classes); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } public void testLoad2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Student student = (Student)session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); System.out.println("student.classes.name=" + student.getClasses().getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } }





















































你可能感兴趣的:(一对多)