学生 和 课程就是一种多对多的关系映射,那么再hibernate中,对于多对多关系在怎么配置?

和一些注意的事项?简单测试下。


建表

实体

配置文件和映射

测试



1。使用oracle ,建表sql

createtablestudents(idnumber(7)primarykey,namenvarchar2(20),agenumber(2))createtablecourse(idnumber(7)primarykey,namenvarchar2(20),timenvarchar2(20))createtablest_cou(st_idreferencesstudents(id),cou_idreferencescourse(id),primarykey(st_id,cou_id))

2. students 实体

packagecom.hibernate.entity;importjava.util.HashSet;importjava.util.Set;publicclassStudents{privateIntegerid;privateStringname;privateIntegerage;privateSet<Course>course=newHashSet<Course>();publicIntegergetId(){returnid;}publicvoidsetId(Integerid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.age=age;}publicSet<Course>getCourse(){returncourse;}publicvoidsetCourse(Set<Course>course){this.course=course;}publicStudents(Integerid,Stringname,Integerage){super();this.id=id;this.name=name;this.age=age;}publicStudents(){super();}@OverridepublicStringtoString(){return"Students[id="+id+",name="+name+",age="+age+",course="+course+"]";}}

3. course实体

packagecom.hibernate.entity;importjava.util.HashSet;importjava.util.Set;publicclassCourse{privateIntegerid;privateStringname;privateStringtime;privateSet<Students>students=newHashSet<Students>();publicIntegergetId(){returnid;}publicvoidsetId(Integerid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicStringgetTime(){returntime;}publicvoidsetTime(Stringtime){this.time=time;}publicSet<Students>getStudents(){returnstudents;}publicvoidsetStudents(Set<Students>students){this.students=students;}publicCourse(Integerid,Stringname,Stringtime){super();this.id=id;this.name=name;this.time=time;}publicCourse(){super();}@OverridepublicStringtoString(){return"Course[id="+id+",name="+name+",time="+time+"]";}}

4.hibernate.cfg.xml 配置

<!DOCTYPEhibernate-configurationPUBLIC"-//Hibernate/HibernateConfigurationDTD3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><!--添加配置信息:数据库连接参数--><propertyname="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property><propertyname="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property><propertyname="hibernate.connection.username">zt</property><propertyname="hibernate.connection.password">zt</property><!--添加配置信息:hibernate自身属性dialect:方言,指定数据类型,hibernate可以针对不同的数据库做出相应的优化--><propertyname="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property><propertyname="hibernate.show_sql">true</property><propertyname="hibernate.format_sql">true</property><!--为getCurrentSession增加配置--><propertyname="current_session_context_class">thread</property><mappingresource="course.cfg.xml"/></session-factory></hibernate-configuration>

course.hbm.xmc 映射配置

<?xmlversion="1.0"?><!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mappingpackage="com.hibernate.entity"><classname="Students"table="students"><idname="id"><generatorclass="increment"></generator></id><propertyname="age"/><propertyname="name"/><!--name:是实体中关联的另一方属性cascade:是级联级别table:是学生和课程中间关联的那张表下面course配置和students配置是一样的。--><setname="course"cascade="all"table="st_cou"><!--columun:是关系表中的自己的维护字段--><keycolumn="st_id"></key><!--class:是关系对方的实体column:是关系对方的维护字段--><many-to-manyclass="Course"column="cou_id"/></set></class><classname="Course"table="course"><idname="id"><generatorclass="increment"></generator></id><propertyname="name"/><propertyname="time"/><setname="students"cascade="all"table="st_cou"><keycolumn="cou_id"></key><many-to-manyclass="Students"column="st_id"></many-to-many></set></class></hibernate-mapping>

5. 测试

查询和更新测试略

查询直接查就可以了,更新查询后,修改值后,更新就可以了。


插入测试,级联插入

@Testpublicvoidinset(){Sessionsession=HibUtil.getSession();Transactiontx=session.beginTransaction();Coursecourse=newCourse(null,"地理","面貌");Studentsstudents=newStudents(null,"蛋蛋",18);students.getCourse().add(course);//course.getStudents().add(students);这句不用写session.save(students);tx.commit();}

多对多中,插入,只要乙方进行维护就可以,如果二方都写

students.getCourse().add(course);course.getStudents().add(students);

那么插入中,再关联表中,由于乙方已经维护,此时已经存在关联关系,这时候,另一方已进行维护

那么由于已经存在关联关系,这时候会报 违反唯一约束条件


删除测试

@Testpublicvoiddelete(){Sessionsession=HibUtil.getSession();Transactiontx=session.beginTransaction();Studentsstudents=(Students)session.get(Students.class,1);session.delete(students);tx.commit();}

执行之后,进入数据库查询,发现,只要是在关联表中存在的,相关学生和课程都会被删除。

配置中,我们配置了级联级别是 all 这中权限过大,慎用。级联级别修改为 save-update


6.注意

1.实体中 我们写关系一方有

private Set<Course> course = new HashSet<Course>();

为什么 newHashSet<Course>();

当我们进行单个插入表时,如果没有newHashSet<Course>();

Studentsstudents=(Students)session.get(Students.class,1);Coursecourse=newCourse(null,"地理","面貌");这里的course.getStudents()是个null而用null对象.add会是空指针course.getStudents().add(students);

2. 级联关系

在关联关系中,要慎用关系,以免对另一方数据操作损失。