代碼 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技術進行數據庫的操做