Hibernate入门六(单项的保存操作)
来源:互联网 发布:单片机方案开发 编辑:程序博客网 时间:2024/05/29 08:28
package com.itheima12.hibernate.onetomanysingle;import java.util.HashSet;import java.util.Set;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;import com.itheima12.hibernate.domain.Classes;import com.itheima12.hibernate.domain.Student;import com.itheima12.hibernate.utils.HibernateUtils;/** * 一对多的单项 * @author zd * 一般操作 1、保存班级 2、保存学生 3、保存班级,保存学生 级联操作 4、保存班级级联保存学生 5、保存班级级联更新学生 6、更新班级级联保存学生 7、更新班级级联更新学生 8、删除班级级联删除学生 9、在班级有级联save-update的情况下,从关联得到学生,并且删除学生? 关系操作 8、已经存在一个班级,新建一个学生,把该学生加入到该班级(建立关系操作) 9、已经存在一个学生,新建一个班级,把该学生加入到该班级(建立关系操作) 10、已经存在一个学生,已经存在一个班级,把该学生加入到该班级 11、已经存在一个学生,把一个学生从一个班级转移到另外一个班级 在一的一方维护关系的时候,总会发出维护关系的update语句,该update语句就是更新外键 级联和关系的混合: 12、在删除班级的时候,解除班级和学生之间的关系 */public class OneToManySingleTest extends HibernateUtils{ @Test //保存一个班级对象 public void testSaveClasses(){ //我继承自HibernateUtils 我就能直接调用getCurrentSession Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = new Classes(); classes.setName("黑马JavaEE+hadoop的12期"); classes.setDescription("牛"); session.save(classes); transaction.commit(); } @Test //保存一个学生对象 public void testSaveStudent(){ //我继承自HibernateUtils 我就能直接调用getCurrentSession Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Student student = new Student(); student.setName("班长"); student.setDescription("带头大哥"); session.save(student); transaction.commit(); } @Test //想保存一个班级和学生 public void testSaveClassesAndSaveStudent(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = new Classes(); classes.setName("黑马视频班"); classes.setDescription("野牛"); Student student = new Student(); student.setName("班秘"); student.setDescription("凤姐"); //保存两次 session.save(classes); session.save(student); transaction.commit(); }
这个运行起来 还是没有关联起来,而且一般不这么做,因为假设有100个学生对象的话,save100次。。。。
如果想要是进行级联操作的话,需要配置classess的配置文件
<?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="com.itheima12.hibernate.domain.Classes"> <id name="cid" length="5"> <generator class="increment"></generator> </id> <property name="description" length="50"></property> <property name="name" length="20"></property> <!-- set元素针对的就是Classes类中的Set属性 cascade 级联操作 null 默认值 save-update 在保存classes对象的时候,针对student进行保存或者更新的操作 在更新classes对象的时候,针对student进行保存或者更新的操作 all delete inverse 关系操作 default:classes维护classes与student之间的关系 true: classes不维护classes与student之间的关系 false: classes维护classes与student之间的关系 --> <set name="students" cascade="save-update" inverse="true"> <!-- 外键 告诉hibernate,通过cid就可以建立classes与student之间的关联 --> <key> <column name="cid"></column> </key> <!-- 告诉hibernate,Classes类中的set集合中存放的是哪个元素 --> <one-to-many class="com.itheima12.hibernate.domain.Student"/> </set> </class></hibernate-mapping>
配置好xml文件以后,继续编写测试类
/** * 在保存班级的时候,级联保存学生 */ @Test public void testSaveClasses_Cascade_Save_Student(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = new Classes(); classes.setName("黑马视频班"); classes.setDescription("野牛"); Student student = new Student(); student.setName("班秘"); student.setDescription("凤姐"); //建立classes与student之间的关联 但是如果在xml文件中没有配置 级联的话就会出现错误 //我先准备一个set集合 Set<Student> students = new HashSet<Student>(); students.add(student); classes.setStudents(students); session.save(classes); //显示保存的是classes,把保存student称为隐式保存 //这里有个很难排 transient 临时的 transaction.commit(); } /** * 在更新班级的时候,级联更新学生 * sessin.flush的时候 * 1、检查一级缓存中所有的持久化状态的对象 * 判断发出insert语句或者update语句 * 2、检查所有的持久化对象的关联对象 * 如果关联对象是由临时状态转化过来的,则对关联对象发出insert语句 * 如果关联对象是从数据库中提取出来的,则对照副本,决定是否发出update语句 */ @Test public void testUpdateClasses_Cascade_Update_Student(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 2L);//持久化类 Set<Student> students = classes.getStudents();//持久化类 for (Student student : students) {//把每一个student对象(关联对象)也放入到了一级缓存中 student.setDescription("bb"); } students = classes.getStudents();//再次执行的话 发现并没有发出sql语句 说明 for (Student student : students) {//把每一个student对象(关联对象)也放入到了一级缓存中 student.setDescription("bb"); } transaction.commit(); }
/** * 在更新班级的时候,添加学生 */ @Test public void testUpdateClasses_Cascade_Save_Student(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); /* * 给cid为2的班级添加一个学生 */ //首先我得得到cid为2的班级 Classes classes = (Classes)session.get(Classes.class, 2L); //接下来我得整一个学生 Student student = new Student(); student.setName("美女1"); student.setDescription("小林志玲"); /** * 建立班级与学生的关联 * Set<Student> students = new HashSet<Student>(); * students.add(student); * 这个不行 会全覆盖 涉及到了关系操作 */ classes.getStudents().add(student); transaction.commit(); }总结一下:在保存或者更新班级的时候,我操作学生 /** * 在更新班级的时候,级联保存学生,并且维护关系 * Hibernate: select classes0_.cid as cid0_0_, classes0_.description as descript2_0_0_, classes0_.name as name0_0_ from Classes classes0_ where classes0_.cid=? Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.description as descript2_1_0_, students0_.name as name1_0_ from Student students0_ where students0_.cid=? Hibernate: select max(sid) from Student Hibernate: 因为在Classes.hbm.xml文件中设置了级联 <set name="students" cascade="save-update"> insert into Student (description, name, sid) values (?, ?, ?) Hibernate: 因为在Classes.hbm.xml文件中,inverse没有写,默认classes维护classes与student之间的关系 所以发出了更新关系的update语句 怎么体现维护关系 通过更新外键关系 这个语句发出的关键是 inverse update Student set cid=? where sid=? */ @Test public void testUpdateClasses_Cascade_Save_Student_Inverse(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); /* * 给cid为2的班级添加一个学生 */ Classes classes = (Classes)session.get(Classes.class, 2L); Student student = new Student(); student.setName("美女1"); student.setDescription("小林志玲"); /** * 建立班级与学生的关联 */ classes.getStudents().add(student); transaction.commit(); } /** * 已经存在一个班级cid为1,已经存在一个学生,已经存在另外一个班级cid为2,该学生从cid为1的班级转到cid为2的班级 */ @Test public void testTransform(){ /** * 1、把cid为1,2和sid为1的对象提取出来 */ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); //Classes classes1 = (Classes)session.get(Classes.class, 1L); Classes classes2 = (Classes)session.get(Classes.class, 2L);//发出查询的sql语句 Student student = (Student)session.get(Student.class, 1L);//发出查询的sql语句 //解除 classes1与student之间的关系 //classes1.getStudents().remove(student); //建立classes2与student之间的关系 classes2.getStudents().add(student); transaction.commit(); } /** * 解除该班级和该班级中的所有的学生之间的关系 */ @Test public void testRealseR(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); /** * 解除cid为2的班级和所有的学生之间的关系 */ Classes classes = (Classes)session.get(Classes.class,2L); classes.setStudents(null); transaction.commit(); } /** * 解除该班级和所有的学生之间的关系,再建立该班级和一些学生之间的关系 */ @Test public void testRealseAllR_BuildSomeR(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); //解除cid为2的班级和所有的学生之间的关系 Classes classes = (Classes)session.get(Classes.class, 2L); classes.setStudents(null); Student student1 = new Student(); student1.setName("王二麻子"); Student student2 = new Student(); student2.setName("隔壁老李"); Set<Student> students = new HashSet<Student>(); students.add(student2); students.add(student1); classes.setStudents(students); transaction.commit(); } /** * 删除一个班级 * 在删除班级之前,解除班级和学生之间的关系 * Hibernate: select classes0_.cid as cid0_0_, classes0_.description as descript2_0_0_, classes0_.name as name0_0_ from Classes classes0_ where classes0_.cid=? Hibernate: 因为classes负责维护关系,所以该语句就是解除关系的sql语句 update Student set cid=null where cid=? Hibernate: delete from Classes where cid=? */ @Test public void testDeleteClasses_1(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 1L); session.delete(classes); transaction.commit(); } /** * 在 Classes.hbm.xml文件中 * <set name="students" cascade="all"> * 在删除班级的时候,级联删除学生 */ @Test public void testDeleteClasses_2(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 1L); session.delete(classes); transaction.commit(); } /** * 删除一个学生,但是该学生必须从班级中提取出来 * 因为在Classes.hbm.xml文件中 * <set name="students" cascade="save-update"> * classes针对student是关联的 * 而程序中的student对象是从classes中提取出来的关联对象,所以不能删除 */ @Test public void testError(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 1L); Set<Student> students = classes.getStudents(); //classes.setStudents(null);//解除关系 for (Student student : students) { session.delete(student); } transaction.commit(); }}
这里来解释一下:为什么每次执行都跟着一个update语句
我要建立联系班级和学生的联系,在hibernate面向对象操作,cascade是级联操作,hibernate当中有个属性叫做inverse
inverse 关系操作
- default:classes维护classes与student之间的关系
- true: classes不维护classes与student之间的关系
- false: classes维护classes与student之间的关系
阅读全文
0 0
- Hibernate入门六(单项的保存操作)
- Hibernate 单项级联操作
- hibernate多表操作之一对多的单项操作
- Hibernate单项映射的问题(原因在最后面)
- hibernate的基本保存操作
- hibernate的级联保存操作(一对多)
- hibernate 数据保存操作的原理
- hibernate 数据保存操作的原理
- Hibernate的配置及保存操作
- Hibernate 关联映射 之 一对多单项关联 (二)聪明的懒加载
- hibernate映射(二) 之Hibernate单项一对多映射
- 创建单项链接的六点不可错过新技巧
- Hibernate入门BLOG [六、Hibernate的关键字总结]
- hibernate单项一对一
- Hibernate 一对多 单项
- Hibernate 关联映射 之 一对多单项关联 (一)
- wcf 单项操作
- 后台订单管理异步加载订单项的操作
- MySQL半同步复制--handle_slave_io--4
- AUTOCAD学习笔记4:常用电器元件的绘制
- 观察者模式
- Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。
- AJAX工作原理及其优缺点
- Hibernate入门六(单项的保存操作)
- 敌兵布阵
- 学习编程,技术那么多,如何选择呢?
- js -- java controller param
- hdu 3518 Boring counting 后缀数组
- Echarts基础(二)柱、饼、折线图
- 用顺序表完成简单的学生成绩管理系统
- spring4.3.x与apach-cxf.2.7x jar冲突
- 检测openstack云平台是否存在脑裂的虚拟机,加入zabbix告警