博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate(二)
阅读量:6607 次
发布时间:2019-06-24

本文共 15886 字,大约阅读时间需要 52 分钟。

  hot3.png

1. 对象的状态

代码

public class StateTest extends HiberanteUtils{	/**	 * session.save方法把一个临时状态的对象转化成持久化状态的对象	 */	@Test	public void testSavePerson(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = new Person();		person.setPname("afds");		person.setPsex("af");			session.save(person);				transaction.commit();		session.close();	}		/**	 * session.update方法可以把一个对象的状态变成持久化状态	 */	@Test	public void testUpdate(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person2 = new Person();//临时状态		person2.setPid(1L);//临时状态		session.update(person2);//持久化状态				transaction.commit();		session.close();	}		/**	 * 当session.get方法得到一个对象的时候,是不需要再执行 update语句,因为已经是持久化状态	 * 当一个对象是一个持久化对象的时候,当进行提交的时候,hibernate内部会让该对象和快照进行对比,如果一样,则不发出update语句	 * 如果不一样,则发出update语句	 */	@Test	public void testGet(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = (Person)session.get(Person.class, 1L);//持久化		person.setPname("ttkjkjhg");				//session.update(person);		transaction.commit();		session.close();	}		/**	 * session.clear方法把所有的对象从session中清空	 */	@Test	public void testClear(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = (Person)session.get(Person.class, 1L);		person.setPname("asd");		session.clear();//把session中所有的对象清空		session.update(person);//把对象从脱管状态转化成持久化状态				transaction.commit();		session.close();	}		/**	 * session.evict把一个对象从session中清空	 */	@Test	public void testEvict(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = (Person)session.get(Person.class, 1L);		person.setPname("asdsss");		session.evict(person);//脱管状态		session.update(person);//把对象的状态转化成持久化状态				transaction.commit();		session.close();	}			/**	 * 一个对象是否是持久化对象是针对某一个session而言的	 */	@Test	public void testSession(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = (Person)session.get(Person.class, 1L);		person.setPname("asfd");		transaction.commit();		session.close();				session =  sessionFactory.openSession();//94		transaction =  session.beginTransaction();		//person.setPname("aaa");//person对象对于94的session来说是一个临时状态的对象		session.update(person);				transaction.commit();		session.close();	}		/**	 * 当执行transaction.commit的时候,hibernate内部会检查session	 *    1、如果一个对象为临时状态的对象,则session不会管	 *    2、如果一个对象是持久化状态的对象,如果有ID值,并且和数据库对应,	 *    	 那么先把该对象与快照进行对比,如果一致,则什么都不做,如果不一致,则发出update语句	 *    3、如果一个对象是持久化状态的对象,如果没有ID值,则会发出save语句	 */	@Test	public void testMuplyOption(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = new Person();		person.setPname("rrr1");		person.setPsex("asdfasdf");				Person person3 = new Person();		person3.setPname("rrr2");		person3.setPsex("asdfasdf");				session.save(person);				Person person2 = (Person)session.get(Person.class, 18L);		person2.setPname("asdfasdf");				transaction.commit();//会检查session中对象的状态。如果是临时对象,session根本不管		//如果持久话对象的id有值,update.没值,save()		session.close();	}			@Test	public void testMutiplyOption2(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Person person = new Person();		person.setPname("haha1");		person.setPsex("haha2");		session.save(person); 		transaction.commit();				session.evict(person);		session.close();				session = sessionFactory.openSession();		transaction = session.beginTransaction();		session.update(person);		session.clear();		transaction.commit();		session.close();	}}

2. 一对多的单项关联

2.1. 数据库表和实体类关系

2.2. Classes映射文件中cascade、inverse、外键的配置

2.3. 代码体现

package cn.itcast.hibernate.sh.test;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.annotations.Type;import org.junit.Test;import cn.itcast.hiberate.sh.domain.Classes;import cn.itcast.hiberate.sh.domain.Student;import cn.itcast.hibernate.sh.utils.HiberanteUtils;/** * 1、新建一个班级 * 2、新建一个学生 * 3、新建一个班级的时候同时新建一个学生 * 4、已经存在一个班级,新建一个学生,建立学生与班级之间的关系 * 5、已经存在一个学生,新建一个班级,把学生加入到该班级 * 6、把一个学生从一个班级转移到另一个班级 * 7、解析一个班级和一个学生之间的关系 * 8、解除一个班级和一些学生之间的关系 * 9、解除该班级和所有的学生之间的关系 * 10、已经存在一个班级,已经存在一个学生,建立该班级与该学生之间的关系 * 11、已经存在一个班级,已经存在多个学生,建立多个学生与班级之间的关系 * 12、删除学生 * 13、删除班级 *     删除班级的时候同时删除学生 *     在删除班级之前,解除班级和学生之间的关系 * @author Think * */public class OneToManySingleTest extends HiberanteUtils{	@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();	}				@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();	}		@Test	public void testSaveClasses_Student(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Classes classes = new Classes();		classes.setCname("传智上海云二期:");		classes.setDescription("很牛X");				Student student = new Student();		student.setSname("班长");		student.setDescription("老牛:很牛X");				session.save(student);		session.save(classes);		transaction.commit();		session.close();	}		/**	 * 在保存班级的时候,级联保存学生	 */	@Test	public void testSaveClasses_Cascade_Student_Save(){		Session session = sessionFactory.openSession();		Transaction transaction = session.beginTransaction();				Classes classes = new Classes();		classes.setCname("传智上海云三期:");		classes.setDescription("很牛XX");				Student student = new Student();		student.setSname("班长");		student.setDescription("老牛:很牛XX");				Set
students = new HashSet
(); students.add(student); //建立classes与student之间的关联 classes.setStudents(students); session.save(classes); transaction.commit(); session.close(); } /** * 在保存班级的时候,级联更新学生 */ @Test public void testSaveClasses_Cascade_Student_Update(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = new Classes(); classes.setCname("传智上海云四期:"); classes.setDescription("很牛XXX"); Student student = (Student)session.get(Student.class, 1L); student.setSname("班秘"); Set
students = new HashSet
(); students.add(student); classes.setStudents(students); session.save(classes); transaction.commit(); session.close(); } /** * 更新班级的同时保存学生 */ @Test public void testUpdateClasses_Cascade_Student_Save(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 5L); Student student = new Student(); student.setSname("班花"); student.setDescription("稀有人物"); classes.getStudents().add(student);//因为已经有班级了,所以先获取班级的学生,再添加学生 //因为classes是持久化对象,所以不用update() transaction.commit(); session.close(); } /** * 更新班级的同时更新学生 */ @Test public void testUpdateClasses_Cascade_Student_Update(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 5L); Set
students = classes.getStudents();//为cid为5的班级的所有的学生// for(Student student:students){// student.setDescription("压力山大");// } 快照 transaction.commit(); session.close(); } /** * 一个错误的演示---在classes映射文件中删除了cascade="save-update" * 保存班级的同时保存学生 * ------------------------------------ * 在客户端试图通过保存班级保存学生,但是由于在配置文件中针对students没有cascade属性,没有级联, * 所以导致classes中的student成为临时状态的对象了,hibernate不允许这种情况出现。 * 把session.save/update一个对象的操作为显示操作,级联对象的操作为隐式操作 */ @Test public void testSaveClasses_Cascade_Student_Save_Error(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = new Classes(); classes.setCname("传智上海云六期:"); classes.setDescription("很牛XXXXXX"); Student student = new Student(); student.setSname("班长XXXXXX"); student.setDescription("老牛:很牛XXXXXX"); Set
students = new HashSet
(); students.add(student); //建立classes与student之间的关联 classes.setStudents(students); session.save(classes); transaction.commit(); session.close(); } /** * 【方式一】 * 已经存在一个班级,新建一个学生,建立学生与班级之间的关系 * ============================================================== * 新建立一个学生,在学生表的cid自断处处,添加这个学生班级的id,即建立了关系。 * 通过更新班级级联保存学生 cascade起作用,负责:已经存在一个班级,新建一个学生 * 建立班级和学生之间的关系 inverse起作用,负责:建立学生与班级之间的关系 * ============================================================== * 用inverse属性代替了外键,面向对象的思考方式。因为在student类中不能出现cid * inverse用来维护两个表之间的关系 */ @Test public void testSaveStudent_R_1(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Student student = new Student(); student.setSname("技术班长"); student.setDescription("大神"); Classes classes = (Classes)session.get(Classes.class, 1L); classes.getStudents().add(student); transaction.commit(); session.close(); } /**【方式二】 * Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=? Hibernate: select max(sid) from Student Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=? Hibernate: insert into Student (sname, description, sid) values (?, ?, ?) 更新关系的操作 Hibernate: update Student set cid=? where sid=? */ @Test public void testSaveStudent_R_2(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Student student = new Student(); student.setSname("技术班长"); student.setDescription("大神"); Classes classes = (Classes)session.get(Classes.class, 1L); session.save(student); classes.getStudents().add(student);//只有建立了关系inverse才能起作用。若没这行cid为null transaction.commit(); session.close(); } /** * 已经存在一个学生,新建一个班级,把学生加入到该班级 */ @Test public void testSaveClasses_R(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = new Classes(); classes.setCname("老毕基础加强班"); classes.setDescription("必看,杀手锏"); Student student = (Student)session.get(Student.class, 2L); Set
students = new HashSet
(); students.add(student); classes.setStudents(students); session.save(classes); transaction.commit(); session.close(); } /** * 把一个学生从一个班级转移到另一个班级 * 即:先解除班级和学生之间的关系,再建立学生和另外一个班级之间的关系 * Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=? Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=? Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=? Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=? Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=? Hibernate: update Student set cid=null where cid=? and sid=? //解除 Hibernate: update Student set cid=? where sid=? //建立 简单操作:直接把外键5变为6就可以完成 */ @Test public void testTransformClass(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); //Classes classes5 = (Classes)session.get(Classes.class, 5L); Classes classes6 = (Classes)session.get(Classes.class, 6L); Student student = (Student)session.get(Student.class, 1L); //classes5.getStudents().remove(student); //只是移除了关系,并不是删除学生 classes6.getStudents().add(student);//建立新关系 transaction.commit(); session.close(); } /** * 解除一个班级和一些学生之间的关系 */ @Test public void testR_Some(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 1L); Set
students = classes.getStudents();// for(Student student:students){// if(student.getSid().longValue()==6||student.getSid().longValue()==7){// students.remove(student);// }// } //set-->list List
sList = new ArrayList
(students); for(int i=0;i
(sList); classes.setStudents(students); /** * 增强for循环只能修改一次 * 1、用普通的for循环 * 2、新建一个set集合,把原来的set集合要保留的数据存放到新的set集合中 */ transaction.commit(); session.close(); } /**解除班级一和所有学生之间的关系 * classes.setStudents(null);直接把班级针对student的集合设置为null */ @Test public void testRealseAll(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 1L); //方式一 Set
students = classes.getStudents();// students.clear(); //为何不用removeAll(Conllection c) //方式2 classes.setStudents(null); transaction.commit(); session.close(); } /** * 删除学生 */ @Test public void testDeleteStudent(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Student student = (Student)session.get(Student.class, 8L); session.delete(student); transaction.commit(); session.close(); } /** * 在删除班级之前,解除班级和学生之间的关系 */ @Test public void testDeleteClasses(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 5L); //classes.setStudents(null);//如果不维护关系。inverse=true session.delete(classes);//班级维护了关系,所以在删除班级的时候,自然也解除了学生和班级的关系 transaction.commit(); session.close(); } /** * 级联删除班级5的同时删除学生 */ @Test public void testDeleteClasses_Cascade(){ Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 5L); session.delete(classes); transaction.commit(); session.close(); }}

2.4. 常见错误分析

3. hibernate基础知识总结

1、hibernate的组成部分    	持久化类    	    实现对应的序列化接口    	    必须有默认的构造函数    	    持久化类的属性不能使用关键字    	    标示符 			映射文件 	    类型		java类型和hibernate类型 	    主键的产生器		increment identity  assigned uuid 	    id  prototype 	    set集合 		cascade  对象与对象之间的关系,和外键没有关系 		inverse  对象与外键之间的关系  			配置文件  	    数据库的链接信息  	    存放了映射文件的信息  	    其他信息:hibernate内部功能的信息  		显示sql语句:
true
生成表的:
update
2、hibernate的流程 Configuraction 加载了配置文件 Configuration configuration = new Configuration(); configuration.configure(); SessionFactory(接口) 配置文件的信息、映射文件的信息、持久化类的信息全部在SessionFactory 特点:线程安全、单例 SessionFactory sessionFactory = configuration.buildSessionFactory(); Session(接口) Session session = sessionFactory.openSession(); 1、crud的操作都是由session完成的 2、事务是由session开启的 3、两个不同的session只能用各自的事务 4、session决定了对象的状态 一个对象在session中,肯定是持久化的 5、创建完一个session,相当于打开了一个数据库的链接 Transaction Transaction transaction = session.beginTransaction(); transaction.commit(); 1、事务默认不是自动提交的 * jdbc的事务默认是自动提交的 2、必须由session开启 3、必须和当前的session绑定(两个session不可能共用一个事务)3、对象的状态的转化4、hibernate的原理: 根据客户端的代码,参照映射文件,生成sql语句,利用jdbc技术进行数据库的操作

转载于:https://my.oschina.net/ilaoda/blog/502555

你可能感兴趣的文章
【转】关于大型网站技术演进的思考(十二)--网站静态化处理—缓存(4)
查看>>
积跬步,聚小流------Bootstrap学习记录(1)
查看>>
HDUPhysical Examination(贪心)
查看>>
HTML5 FileAPI
查看>>
使用tdcss.js轻松制作自己的style guide
查看>>
SecureCRTPortable.exe 如何上传文件
查看>>
C++中public、protected及private用法
查看>>
苹果公司的产品已用完后门与微软垄断,要检查起来,打架!
查看>>
顶级的JavaScript框架、库、工具及其使用
查看>>
AYUI -AYUI风格的 超美 百度网盘8.0
查看>>
简明 Python 教程
查看>>
用MPMoviePlayerController做在线音乐播放
查看>>
Java查找算法——二分查找
查看>>
如何构建微服务架构
查看>>
【前端笔记】彻底理解变量与函数的声明提升
查看>>
Android 反编译利器,jadx 的高级技巧
查看>>
二叉搜索树(递归实现)
查看>>
Spring Retry重试机制
查看>>
Android官方架构组件LiveData: 观察者模式领域二三事
查看>>
[Android组件化]组件化数据分享
查看>>