hibernate 單元測試架構

來源:互聯網
上載者:User

標籤:des   c   style   class   blog   code   

hibernate在寫資料庫設定檔時非常的不確定,必須進行必要的測試保證資料庫結構的正確性。所以可以應用junit進行測試。

使用junit非常簡單,eclipse只需要右鍵項目建立一個junit test case即可(填寫類名和包名)。然後在對應位置寫對應的代碼運行測試即可。

下面給出一個常用的hibernate測試架構:

package com.atguigu.hibernate.entities;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.sql.Blob;import java.sql.Connection;import java.sql.SQLException;import java.util.Date;import org.hibernate.Hibernate;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.jdbc.Work;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())                            .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testComponent(){Worker worker = new Worker();Pay pay = new Pay();pay.setMonthlyPay(1000);pay.setYearPay(80000); pay.setVocationWithPay(5);worker.setName("ABCD");worker.setPay(pay);session.save(worker);}@Testpublic void testBlob() throws Exception{//News news = new News();//news.setAuthor("cc");//news.setContent("CONTENT");//news.setDate(new Date());//news.setDesc("DESC");//news.setTitle("CC");////InputStream stream = new FileInputStream("Hydrangeas.jpg");//Blob image = Hibernate.getLobCreator(session)//              .createBlob(stream, stream.available());//news.setImage(image);////session.save(news);News news = (News) session.get(News.class, 1);Blob image = news.getImage();InputStream in = image.getBinaryStream();System.out.println(in.available()); }@Testpublic void testPropertyUpdate(){News news = (News) session.get(News.class, 1);news.setTitle("aaaa"); System.out.println(news.getDesc());System.out.println(news.getDate().getClass()); }@Testpublic void testIdGenerator() throws InterruptedException{News news = new News("AA", "aa", new java.sql.Date(new Date().getTime()));session.save(news); //Thread.sleep(5000); }@Testpublic void testDynamicUpdate(){News news = (News) session.get(News.class, 1);news.setAuthor("AABCD");}@Testpublic void testDoWork(){session.doWork(new Work() {@Overridepublic void execute(Connection connection) throws SQLException {System.out.println(connection); //調用預存程序. }});}/** * evict: 從 session 緩衝中把指定的持久化對象移除 */@Testpublic void testEvict(){News news1 = (News) session.get(News.class, 1);News news2 = (News) session.get(News.class, 2);news1.setTitle("AA");news2.setTitle("BB");session.evict(news1); }/** * delete: 執行刪除操作. 只要 OID 和資料表中一條記錄對應, 就會準備執行 delete 操作 * 若 OID 在資料表中沒有對應的記錄, 則拋出異常 *  * 可以通過設定 hibernate 設定檔 hibernate.use_identifier_rollback 為 true, * 使刪除對象後, 把其 OID 置為  null */@Testpublic void testDelete(){//News news = new News();//news.setId(11);News news = (News) session.get(News.class, 163840);session.delete(news); System.out.println(news);}/** * 注意: * 1. 若 OID 不為 null, 但資料表中還沒有和其對應的記錄. 會拋出一個異常.  * 2. 瞭解: OID 值等於 id 的 unsaved-value 屬性值的對象, 也被認為是一個游離對象 */@Testpublic void testSaveOrUpdate(){News news = new News("FFF", "fff", new Date());news.setId(11);session.saveOrUpdate(news); }/** * update: * 1. 若更新一個持久化對象, 不需要顯示的調用 update 方法. 因為在調用 Transaction * 的 commit() 方法時, 會先執行 session 的 flush 方法. * 2. 更新一個游離對象, 需要顯式的調用 session 的 update 方法. 可以把一個游離對象 * 變為持久化對象 *  * 需要注意的: * 1. 無論要更新的游離對象和資料表的記錄是否一致, 都會發送 UPDATE 語句.  *    如何能讓 updat 方法不再盲目的出發 update 語句呢 ? 在 .hbm.xml 檔案的 class 節點設定 *    select-before-update=true (預設為 false). 但通常不需要設定該屬性.  *  * 2. 若資料表中沒有對應的記錄, 但還調用了 update 方法, 會拋出異常 *  * 3. 當 update() 方法關聯一個游離對象時,  * 如果在 Session 的緩衝中已經存在相同 OID 的持久化對象, 會拋出異常. 因為在 Session 緩衝中 * 不能有兩個 OID 相同的對象! *     */@Testpublic void testUpdate(){News news = (News) session.get(News.class, 1);transaction.commit();session.close();//news.setId(100);session = sessionFactory.openSession();transaction = session.beginTransaction();//news.setAuthor("SUN"); News news2 = (News) session.get(News.class, 1);session.update(news);}/** * get VS load: *  * 1. 執行 get 方法: 會立即載入對象.  *    執行 load 方法, 若不適用該對象, 則不會立即執行查詢操作, 而返回一個代理對象 *     *    get 是 立即檢索, load 是延遲檢索.  *  * 2. load 方法可能會拋出 LazyInitializationException 異常: 在需要初始化 * 代理對象之前已經關閉了 Session *  * 3. 若資料表中沒有對應的記錄, Session 也沒有被關閉.   *    get 返回 null *    load 若不使用該對象的任何屬性, 沒問題; 若需要初始化了, 拋出異常.   */@Testpublic void testLoad(){News news = (News) session.load(News.class, 10);System.out.println(news.getClass().getName()); //session.close();//System.out.println(news); }@Testpublic void testGet(){News news = (News) session.get(News.class, 1);//session.close();System.out.println(news); }/** * persist(): 也會執行 INSERT 操作 *  * 和 save() 的區別 :  * 在調用 persist 方法之前, 若對象已經有 id 了, 則不會執行 INSERT, 而拋出異常 */@Testpublic void testPersist(){News news = new News();news.setTitle("EE");news.setAuthor("ee");news.setDate(new Date());news.setId(200); session.persist(news); }/** * 1. save() 方法 * 1). 使一個臨時對象變為持久化對象 * 2). 為對象分配 ID. * 3). 在 flush 緩衝時會發送一條 INSERT 語句. * 4). 在 save 方法之前的 id 是無效的 * 5). 持久化對象的 ID 是不能被修改的! */@Testpublic void testSave(){News news = new News();news.setTitle("CC");news.setAuthor("cc");news.setDate(new Date());news.setId(100); System.out.println(news);session.save(news);System.out.println(news);//news.setId(101); }/** * clear(): 清理緩衝 */@Testpublic void testClear(){News news1 = (News) session.get(News.class, 1);session.clear();News news2 = (News) session.get(News.class, 1);}/** * refresh(): 會強制發送 SELECT 語句, 以使 Session 緩衝中對象的狀態和資料表中對應的記錄保持一致! */@Testpublic void testRefresh(){News news = (News) session.get(News.class, 1);System.out.println(news);session.refresh(news); System.out.println(news); }/** * flush: 使資料表中的記錄和 Session 緩衝中的對象的狀態保持一致. 為了保持一致, 則可能會發送對應的 SQL 陳述式. * 1. 在 Transaction 的 commit() 方法中: 先調用 session 的 flush 方法, 再提交事務 * 2. flush() 方法會可能會發送 SQL 陳述式, 但不會提交事務.  * 3. 注意: 在未提交事務或顯式的調用 session.flush() 方法之前, 也有可能會進行 flush() 操作. * 1). 執行 HQL 或 QBC 查詢, 會先進行 flush() 操作, 以得到資料表的最新的記錄 * 2). 若記錄的 ID 是由底層資料庫使用自增的方式產生的, 則在調用 save() 方法時, 就會立即發送 INSERT 語句.  * 因為 save 方法後, 必須保證對象的 ID 是存在的! */@Testpublic void testSessionFlush2(){News news = new News("Java", "SUN", new Date());session.save(news);}@Testpublic void testSessionFlush(){News news = (News) session.get(News.class, 1);news.setAuthor("Oracle");//session.flush();//System.out.println("flush");News news2 = (News) session.createCriteria(News.class).uniqueResult();System.out.println(news2);}@Testpublic void testSessionCache(){News news = (News) session.get(News.class, 1);System.out.println(news); News news2 = (News) session.get(News.class, 1);System.out.println(news2);}}

package com.atguigu.hibernate.entities.n21;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.sql.Blob;import java.sql.Connection;import java.sql.SQLException;import java.util.Date;import org.hibernate.Hibernate;import org.hibernate.LazyInitializationException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.jdbc.Work;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())                            .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testDelete(){//在不設定級聯關係的情況下, 且 1 這一端的對象有 n 的對象在引用, 不能直接刪除 1 這一端的對象Customer customer = (Customer) session.get(Customer.class, 1);session.delete(customer); }@Testpublic void testUpdate(){Order order = (Order) session.get(Order.class, 1);order.getCustomer().setCustomerName("AAA");}@Testpublic void testMany2OneGet(){//1. 若查詢多的一端的一個對象, 則預設情況下, 只查詢了多的一端的對象. 而沒有查詢關聯的//1 的那一端的對象!Order order = (Order) session.get(Order.class, 1);System.out.println(order.getOrderName()); System.out.println(order.getCustomer().getClass().getName());session.close();//2. 在需要使用到關聯的對象時, 才發送對應的 SQL 陳述式. Customer customer = order.getCustomer();System.out.println(customer.getCustomerName()); //3. 在查詢 Customer 對象時, 由多的一端導航到 1 的一端時, //若此時 session 已被關閉, 則預設情況下//會發生 LazyInitializationException 異常//4. 擷取 Order 對象時, 預設情況下, 其關聯的 Customer 對象是一個代理對象!}@Testpublic void testMany2OneSave(){Customer customer = new Customer();customer.setCustomerName("BB");Order order1 = new Order();order1.setOrderName("ORDER-3");Order order2 = new Order();order2.setOrderName("ORDER-4");//設定關聯關係order1.setCustomer(customer);order2.setCustomer(customer);//執行  save 操作: 先插入 Customer, 再插入 Order, 3 條 INSERT//先插入 1 的一端, 再插入 n 的一端, 只有 INSERT 語句.//session.save(customer);////session.save(order1);//session.save(order2);//先插入 Order, 再插入 Customer. 3 條 INSERT, 2 條 UPDATE//先插入 n 的一端, 再插入 1 的一端, 會多出 UPDATE 語句!//因為在插入多的一端時, 無法確定 1 的一端的外索引值. 所以只能等 1 的一端插入後, 再額外發送 UPDATE 語句.//推薦先插入 1 的一端, 後插入 n 的一端session.save(order1);session.save(order2);session.save(customer);}}

package com.atguigu.hibernate.entities.n21.both;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())                            .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testCascade(){Customer customer = (Customer) session.get(Customer.class, 3);customer.getOrders().clear();}@Testpublic void testDelete(){//在不設定級聯關係的情況下, 且 1 這一端的對象有 n 的對象在引用, 不能直接刪除 1 這一端的對象Customer customer = (Customer) session.get(Customer.class, 1);session.delete(customer); }@Testpublic void testUpdat2(){Customer customer = (Customer) session.get(Customer.class, 1);customer.getOrders().iterator().next().setOrderName("GGG"); }@Testpublic void testUpdate(){Order order = (Order) session.get(Order.class, 1);order.getCustomer().setCustomerName("AAA");}@Testpublic void testOne2ManyGet(){//1. 對 n 的一端的集合使用消極式載入Customer customer = (Customer) session.get(Customer.class, 7);System.out.println(customer.getCustomerName()); //2. 返回的多的一端的集合時 Hibernate 內建的集合類型. //該類型具有消極式載入和存放代理對象的功能. System.out.println(customer.getOrders().getClass()); //session.close();//3. 可能會拋出 LazyInitializationException 異常 System.out.println(customer.getOrders().size()); //4. 再需要使用集合中元素的時候進行初始化. }@Testpublic void testMany2OneGet(){//1. 若查詢多的一端的一個對象, 則預設情況下, 只查詢了多的一端的對象. 而沒有查詢關聯的//1 的那一端的對象!Order order = (Order) session.get(Order.class, 1);System.out.println(order.getOrderName()); System.out.println(order.getCustomer().getClass().getName());session.close();//2. 在需要使用到關聯的對象時, 才發送對應的 SQL 陳述式. Customer customer = order.getCustomer();System.out.println(customer.getCustomerName()); //3. 在查詢 Customer 對象時, 由多的一端導航到 1 的一端時, //若此時 session 已被關閉, 則預設情況下//會發生 LazyInitializationException 異常//4. 擷取 Order 對象時, 預設情況下, 其關聯的 Customer 對象是一個代理對象!}@Testpublic void testMany2OneSave(){Customer customer = new Customer();customer.setCustomerName("AA");Order order1 = new Order();order1.setOrderName("ORDER-1");Order order2 = new Order();order2.setOrderName("ORDER-2");//設定關聯關係order1.setCustomer(customer);order2.setCustomer(customer);customer.getOrders().add(order1);customer.getOrders().add(order2);//執行  save 操作: 先插入 Customer, 再插入 Order, 3 條 INSERT, 2 條 UPDATE//因為 1 的一端和 n 的一端都維護關聯關係. 所以會多出 UPDATE//可以在 1 的一端的 set 節點指定 inverse=true, 來使 1 的一端放棄維護關聯關係!//建議設定 set 的 inverse=true, 建議先插入 1 的一端, 後插入多的一端//好處是不會多出 UPDATE 語句session.save(customer);//session.save(order1);//session.save(order2);//先插入 Order, 再插入 Cusomer, 3 條 INSERT, 4 條 UPDATE//session.save(order1);//session.save(order2);////session.save(customer);}}

省略測試時用到的,entity類和對應的設定檔,因為這些檔案根據業務的不同要進行相應的變換。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.