代码 java
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 * 一、若是一个对象为临时状态的对象,则session不会管 * 二、若是一个对象是持久化状态的对象,若是有ID值,而且和数据库对应, * 那么先把该对象与快照进行对比,若是一致,则什么都不作,若是不一致,则发出update语句 * 三、若是一个对象是持久化状态的对象,若是没有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(); } }
<?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.itcast.hiberate.sh.domain.Classes"> <id name="cid" length="5" type="java.lang.Long"> <generator class="increment"></generator> </id> <property name="cname" length="20" type="java.lang.String"></property> <property name="description" length="100" type="java.lang.String"></property> <!-- set元素对应类中的set集合 经过set元素使classes表与student表创建关联 key是经过外键的形式让两张表创建关联 one-to-many是经过类的形式让两个类创建关联 【cascade】 级联 * save-update 一、当保存班级的时候,对学生进行怎么样的操做 若是学生对象在数据库中没有对应的值,这个时候会执行save操做 若是学生对象在数据库中有对应的值,这个时候会执行update操做 * delete:删除班级的时候删除学生 * all:save-update,delete 【inverse】 维护关系 * true 不维护关系 * false 维护关系 * default false inverse所在的映射文件类。Classes是否维护Classes与student之间的关系,若是不维护cid为null --> <!-- cascade表示,在对classes进行操做的时候对班级进行cascade中值的什么操做 --> <set name="students" cascade="all" inverse="true"> <!-- key是用来描述外键--> <key> <column name="cid"></column> </key> <one-to-many class="cn.itcast.hiberate.sh.domain.Student"/> </set> </class> </hibernate-mapping>
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三、删除班级 * 删除班级的时候同时删除学生 * 在删除班级以前,解除班级和学生之间的关系 * @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<Student> students = new HashSet<Student>(); 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<Student> students = new HashSet<Student>(); 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<Student> 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<Student> students = new HashSet<Student>(); 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<Student> students = new HashSet<Student>(); 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<Student> students = classes.getStudents(); // for(Student student:students){ // if(student.getSid().longValue()==6||student.getSid().longValue()==7){ // students.remove(student); // } // } //set-->list List<Student> sList = new ArrayList<Student>(students); for(int i=0;i<sList.size();i++){ if(sList.get(i).getSid().longValue()==6||sList.get(i).getSid().longValue()==7){ sList.remove(sList.get(i)); i--; } } students = new HashSet<Student>(sList); classes.setStudents(students); /** * 加强for循环只能修改一次 * 一、用普通的for循环 * 二、新建一个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<Student> 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(); } }
一、hibernate的组成部分 持久化类 实现对应的序列化接口 必须有默认的构造函数 持久化类的属性不能使用关键字 标示符 映射文件 类型 java类型和hibernate类型 主键的产生器 increment identity assigned uuid id prototype set集合 cascade 对象与对象之间的关系,和外键没有关系 inverse 对象与外键之间的关系 配置文件 数据库的连接信息 存放了映射文件的信息 其余信息:hibernate内部功能的信息 显示sql语句:<property name="show_sql">true</property> 生成表的:<property name="hbm2ddl.auto">update</property> 二、hibernate的流程 Configuraction 加载了配置文件 Configuration configuration = new Configuration(); configuration.configure(); SessionFactory(接口) 配置文件的信息、映射文件的信息、持久化类的信息所有在SessionFactory 特色:线程安全、单例 SessionFactory sessionFactory = configuration.buildSessionFactory(); Session(接口) Session session = sessionFactory.openSession(); 一、crud的操做都是由session完成的 二、事务是由session开启的 三、两个不一样的session只能用各自的事务 四、session决定了对象的状态 一个对象在session中,确定是持久化的 五、建立完一个session,至关于打开了一个数据库的连接 Transaction Transaction transaction = session.beginTransaction(); transaction.commit(); 一、事务默认不是自动提交的 * jdbc的事务默认是自动提交的 二、必须由session开启 三、必须和当前的session绑定(两个session不可能共用一个事务) 三、对象的状态的转化 四、hibernate的原理: 根据客户端的代码,参照映射文件,生成sql语句,利用jdbc技术进行数据库的操做