在一的一方的类中,添加一个集合,用来保存多的一方的对象!数据库在操作一的一方的时候,会联动操作多的一方!
1.数据库表结构:
班级:
classes cid cname description | 学生: student sid sname description cid //作为外键 |
2.类结构:
public class Classes{ private Long cid; private String cname; private String description; //保存学生 private Set<Student> students; //set和get方法 } | public class Student{ private Long sid; private String sname; private String description; //没有cid这一项! } |
3.映射文件:
Classes.hbm.xml:
<?
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
>
<
class
name="cn.itheima03.hibernate.domain.Classes" table="classes" >
<id name= "cid" type ="java.lang.Long" length= "5" >
<column name= "cid"></column >
<generator class= "increment"></generator >
</id>
<property name= "cname" length ="20"></ property>
<property name= "description" length="50" ></property>
<!--
描述set集合
1、通过外键的描述告诉 hibernate,classes与student的关联
用于生成两张表关联的 sql语句的
2、建立对象与对象之间的关联
cascade 级联
save-update
all
delete
1、前提条件:
必须是两个对象以上
2、在保存classes的时候,怎么样对student集合进行操作
3、在更新classes的时候,怎么样对student集合进行操作
inverse:自动维护关系
false:维护,为默认值;
true:不维护
-->
< set name ="students" cascade ="save-update" inverse ="false">
<!--
key是用来描述外键的
-->
<key>
<column name= "cid"></column >
</key>
<one-to-many class="cn.itheima03.hibernate.domain.Student" />
</set>
</
class
>
</
hibernate-mapping
>
|
Student.hbm.xml:property中没有cid这一项!
<?
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
>
<
class
name="cn.itheima03.hibernate.domain.Student">
<id name= "sid" length ="5">
<generator class= "increment"></generator >
</id>
<property name= "sname" length ="20"></ property>
<property name= "description" length="50" ></property>
</
class
>
</
hibernate-mapping
>
|
4.配置文件:
hibernate.cfg.xml
<?
xml
version= '1.0' encoding ='utf-8'?>
<!
DOCTYPE
hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
<
hibernate-configuration
>
<
session-factory
>
<
property
name="connection.username"> root</ property>
<
property
name="connection.password"> root</ property>
<
property
name= "connection.url">
jdbc:mysql:// localhost:3306/hibernate512
</
property
>
<
property
name="dialect">
org.hibernate.dialect.MySQLDialect
</
property
>
<
property
name="connection.driver_class">
com.mysql.jdbc.Driver
</
property
>
<
property
name="hbm2ddl.auto"> update</ property>
<
property
name="show_sql"> true</ property>
<
property
name="format_sql"> true</ property>
<
mapping
resource="cn/itheima03/hibernate/domain/Classes.hbm.xml" />
<
mapping
resource="cn/itheima03/hibernate/domain/Student.hbm.xml" />
</
session-factory
>
</
hibernate-configuration
>
|
5.DAO操作:
/**
* 一对多的单项关联
*
@author Think
* 相关的操作:
* 1、保存班级
* 2、保存学生
* 3、保存班级同时保存学生
* 4、有一个新的学生,加入到一个班级
* 5、已经存在一个学生,新建一个班级,把该学生加入到新的班级
* 6、已经存在一个学生,已经存在一个班级,解除该学生和班级之间的关系
* 7、解析一些学生和一个班级之间的关系
* 8、解除该班级和所有的学生之间的关系
* 9、一个学生从一个班级转移到另外一个班级
* 10、删除一个学生
* 11、删除班级
* 1、先解除关系,再删除班级
* 2、在删除班级的同时删除学生
*/
public
class OneToManySingleTest extends HibernateUtils{
/**
* 1.保存班级
*/
@Test
public
void testSaveClasses(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes =
new Classes();
classes.setCname(
"云三");
classes.setDescription(
"云里的三、挺好" );
session.save(classes);
transaction.commit();
session.close();
}
/**
* 2.保存学生
*/
@Test
public
void testSaveStudent(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student =
new Student();
student.setSname(
"云三班秘" );
student.setDescription(
"美女");
session.save(student);
transaction.commit();
session.close();
}
/**
* <set name="students" cascade="save-update">
* 3
-1.保存班级的同时保存学生的数据,学生的数据是update还是save,取决于在数据库中是否有该数据;
*/
@Test
public
void testSaveClassesAndStudent(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes =
new Classes();
classes.setCname(
"云四");
classes.setDescription(
"晕死");
Student student =
new Student();
student.setSname(
"云四");
student.setDescription(
"衰哥");
Set<Student> students =
new HashSet<Student>();
students.add(student);
/**
* 建立classes与student之间的关联
*/
classes.setStudents(students);
session.save(classes);
transaction.commit();
session.close();
}
/**
* 3
-2.测试保存classes时,学生数据update,是否update取决跟快照的对比结果
*/
@Test
public
void testSaveClassesUpdateStudent(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes =
new Classes();
classes.setCname(
"云四");
classes.setDescription(
"晕死");
//得到的是持久化对象
Student student = (Student)session.get(Student.
class
, 1L);
student.setDescription(
"555");
Set<Student> students =
new HashSet<Student>();
students.add(student);
/**
* 建立classes与student之间的关联,保存class时,会联动的更新student数据,
* 因为在classes的映射文件中:<set name="students" cascade="save-update">
*/
classes.setStudents(students);
session.save(classes);
transaction.commit();
session.close();
}
/**
* 4.新的学生,加入到一个班级
* <set name="students" cascade="save-update">
*
*/
@Test
public
void saveStudentToClassse(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student=
new Student();
student.setSname(
"小明");
student.setDescription(
"小伙子很帅噢" );
// session.save(student);//在有cascade="save-update"这句话时,不需要这句话就可以操作成功!
Classes classes=(Classes)session.get(Classes.
class
, 2L);//得到的是持久化对象
Set<Student> students = classes.getStudents();
students.add(student);
transaction.commit();
session.close();
}
/**
*
* 5、已经存在一个学生,新建一个班级,把该学生加入到新的班级
*
* <set name="students" cascade="save-update" inverse="false">
*
*/
@Test
public
void saveClassesUpdateStudent(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//得到学生
Student student=(Student) session.get(Student.
class
, 2L);
//新建班级
Classes classes=
new Classes();
classes.setCname(
"勤务班");
classes.setDescription(
"跑腿的。。。" );
Set<Student> students =
new HashSet<Student>();
//将学生加入到班级中;
students.add(student);
classes.setStudents(students);
//保存班级为持久化状态;
session.save(classes);
transaction.commit();
session.close();
}
/**
* 6、已经存在一个学生,已经存在一个班级,解除该学生和班级之间的关系
* 分析:从集合中移除
* 解除3号学生与2号班级之间的关系!
*/
@Test
public
void releaseRelation(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes=(Classes) session.get(Classes.
class
, 2L);
Set<Student> students = classes.getStudents();
//可以,无需实现 hashcode和equals方法
Student student=(Student) session.get(Student.
class
, 3L);
/* 方法二:
* //根据Id new 出学生,用 sid重写hashcode 的equals方法,可以实现
Student student=new Student();
student.setSid(3L);*/
students.remove(student);
transaction.commit();
session.close();
}
/**
*7、解出一些学生和一个班级之间的关系
* 分析:从集合中移除一些数据;
* 1、2、3号学生都属于5号班级,解除1、2与5号班级的关系;
*/
@Test
public
void test7(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes=(Classes) session.get(Classes.
class
, 5L);
Set<Student> students = classes.getStudents();
Student student1=
new Student();
student1.setSid(1L);
Student student2=
new Student();
student2.setSid(2L);
students.remove(student1);
students.remove(student2);
transaction.commit();
session.close();
}
/**
*8、解出所有学生和一个班级之间的关系
* 分析:清空集合
* 1、3号学生都属于5号班级,解除其关系;
*/
@Test
public
void test8(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes=(Classes) session.get(Classes.
class
, 5L);
classes.setStudents(
null);//这分钟方法效率最高!
/*Set<Student> students = classes.getStudents();
students.clear();*/
transaction.commit();
session.close();
}
/**
* 9、一个学生从一个班级转移到另外一个班级
* 把1号学生移动到1号班级
*/
@Test
public
void test9(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//得到学生
Student student = (Student) session.get(Student.
class
, 1L);
//得到班级
Classes classes=(Classes) session.get(Classes.
class
, 1L);
Set<Student> students = classes.getStudents();
//加入班级
students.add(student);
transaction.commit();
session.close();
}
/**
* 10、删除一个学生
*/
@Test
public
void test10(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//得到学生
Student student = (Student) session.get(Student.
class
, 3L);
session.delete(student);
transaction.commit();
session.close();
}
/**
* 11、删除班级
* 1、先解除关系,再删除班级
* 1号班级有1、3号学生
* <set name="students" cascade="save-update" inverse="false">
* 直接删除班级即可!因为inverse为false,会自动的维护关系;
*
*
*/
@Test
public
void test11_1(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes=(Classes) session.get(Classes.
class
, 1L);
//删除班级,
session.delete(classes);
transaction.commit();
session.close();
}
/**
*在删除班级的同时删除学生
* 1.<set name="students" cascade="all" inverse="false">
* 当为all时,删除班级时会自动的删除学生;
* 2.<set name="students" cascade="save-update" inverse="false">
* 得到班级的学生,遍历删除学生;
*/
@Test
public
void test11_2(){
Session session =
sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes=(Classes) session.get(Classes.
class
, 3L);
Set<Student> students = classes.getStudents();
for (Student student : students) {
session.delete(student);
}
//删除班级
session.delete(classes);
transaction.commit();
session.close();
}
}
|