(一)Hibernate之基礎

有關Spring的知識大部分都已經溫習完畢,今天開始轉向Hibernate的溫習工作了

必須包hibernate-distribution-3.5.3-Final\hibernate3.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

         hibernate-distribution-3.5.3-Final\lib\required\slf4j-api-1.5.8.jar

首先在hibernate資源包中找到:hibernate-distribution-3.5.3-Final\project\tutorials\web\src\main\resources\hibernate.cfg.xml將這個配置文件複製到你的項目SRC目錄下,然後根據實際情況進行適當修改,我的示例中修改後爲


Xml代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;"><?xml version="1.0" encoding="utf-8" ?>  
  2. <!DOCTYPE hibernate-configuration PUBLIC  
  3.     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  5. <hibernate-configuration>  
  6.     <session-factory>  
  7.       <!--數據庫連接設置-->  
  8.         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
  9.         <property name="connection.url">jdbc:mysql:///test</property>  
  10.         <property name="connection.username">root</property>  
  11.         <property name="connection.password">root</property>  
  12.   
  13.         <!--JDBC連接池大小-->  
  14.         <property name="connection.pool_size">2</property>  
  15.         <!-- 數據庫語言 -->  
  16.         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  17.         <!-- Hibernate當前的會話上下文 -->  
  18.         <property name="current_session_context_class">org.hibernate.context.ManagedSessionContext</property>  
  19.         <!-- 禁用二級緩存 -->  
  20.         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>  
  21.         <!-- 控制檯顯示SQL語句 -->  
  22.         <property name="show_sql">true</property>  
  23.        <!-- 格式化SQL語句 -->  
  24.         <property name="hibernate.format_sql">true</property>  
  25.   
  26.     <!--  
  27.         啓動時刪數據庫中的表,然後創建,退出時不刪除數據表   
  28.         <property name="hbm2ddl.auto">create</property>  
  29.     -->  
  30.     <!--  
  31.         啓動時刪數據庫中的表,然後創建,退出時自動刪除所有表   
  32.         <property name="hbm2ddl.auto">create-drop</property>  
  33.     -->  
  34.     <!--  
  35.         自動修改,如果表結構與實體類不一致,那麼就更新表結構,數據會保留  
  36.         (如果原表不存在,就創建新表;如果缺少相應的字段,就加入;對於原來存在的多餘字段,不作處理)  
  37.         <property name="hbm2ddl.auto">update</property>  
  38.     -->  
  39.     <!--  
  40.         自動校驗,如果表結構與實體類不一致,那麼不做任何操作,報錯  
  41.          <property name="hbm2ddl.auto">validate</property>  
  42.     -->  
  43.          <!-- Drop and re-create the database schema on startup -->  
  44.         <property name="hbm2ddl.auto">create</property>  
  45.   
  46.         <!-- 實體關係映射文件 -->  
  47.         <mapping resource="com/javacrazyer/domain/Student.hbm.xml"/>  
  48.     </session-factory>  
  49. </hibernate-configuration></span></span>  


 數據庫方言一定要設定對,跟數據庫驅動匹配org.hibernate.dialect.MySQLDialect

 否則的話就會出現下面這個錯誤


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">Unknown table 'system_sequences' in information_schema</span></span>  


 其次,看看實體類Student.java


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.domain;  
  2.   
  3. import java.util.Date;  
  4.   
  5. /** 
  6.  * 學生實體類 --> 按JavaBean的形式定義 
  7.  *  
  8.  */  
  9. public class Student {  
  10.     private int id;  //OID 對象標識符  
  11.     private String name;  
  12.     private int age;  
  13.     private boolean gender;  
  14.     private Date birthday;  
  15.     private double score;  
  16.       
  17.     public int getId() {  
  18.         return id;  
  19.     }  
  20.     public void setId(int id) {  
  21.         this.id = id;  
  22.     }  
  23.     public String getName() {  
  24.         return name;  
  25.     }  
  26.     public void setName(String name) {  
  27.         this.name = name;  
  28.     }  
  29.     public int getAge() {  
  30.         return age;  
  31.     }  
  32.     public void setAge(int age) {  
  33.         this.age = age;  
  34.     }  
  35.     public boolean isGender() {  
  36.         return gender;  
  37.     }  
  38.     public void setGender(boolean gender) {  
  39.         this.gender = gender;  
  40.     }  
  41.     public Date getBirthday() {  
  42.         return birthday;  
  43.     }  
  44.     public void setBirthday(Date birthday) {  
  45.         this.birthday = birthday;  
  46.     }  
  47.     public double getScore() {  
  48.         return score;  
  49.     }  
  50.     public void setScore(double score) {  
  51.         this.score = score;  
  52.     }  
  53.       
  54.     @Override  
  55.     public String toString(){  
  56.         return "id=" + id + ",name=" + name + ",gender=" + gender + ",age=" + age  
  57.         + ",birthday=" + this.birthday + ",score=" + score;  
  58.     }  
  59.       
  60. }</span></span>  


 實體關係映射文件Student.hbm.xml,具體內容也可以參照hibernate資源包下:

hibernate-distribution-3.5.3Final\project\tutorials\web\src\main\resources\org\hibernate\tutorial\

domain\Person.hbm.xml

那麼進行修改後的內容爲


Xml代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  3. <hibernate-mapping>  
  4.     <class name="com.javacrazyer.domain.Student" table="student">  
  5.         <id name="id" column="id">  
  6.             <generator class="native"/>  
  7.         </id>  
  8.         <property name="name" column="name"/>  
  9.         <property name="age"/>  
  10.         <property name="gender"/>  
  11.         <property name="birthday"/>  
  12.         <property name="score"/>  
  13.     </class>  
  14. </hibernate-mapping></span></span>  


 現在介紹下hbm.xml映射文件中各種屬性的介紹吧

1.class 節點
name: 類名

table: 類對應表名,默認爲類名稱

dynamic-update: 生成更新字段時,只包含發生變動的字段,默認爲false。

dynamic-insert: 生成insert語句時僅包含非null字段

Proxy: 代理類,默認爲空

discriminator-value: 子類辨別標識用於多態支持

where: 通過限定條件查詢結果集。如:查詢有籍在校學生的信息可以使用"where studentstatus='0'"

2.id節點
1.column                字段名稱
2.type                  字段類型
3.length                字段長度
4.unsaved-value         用於判斷對象值是否已經保存
5.generator-class       主鍵產生方式
                        assigned
                        hilo
                        seqhilo
                        increment
                        identity
                        sequence
                        native
                        uuid.hex
                        uuid.string
                        foreign

---------------------------------------------------------------------------------------------------------------
主鍵產生方式說明

increment(遞增) 
用於爲long, short或者int類型生成唯一標識。只有在沒有其他進程往同一張表中插入數據時才能使用。 在集羣下不要使用。

identity 
對DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的內置標識字段提供支持。返回的標識符是long, short 或者int類型的。

sequence (序列) 
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的標識符是long, short或者 int類型的。

hilo (高低位) 
使用一個高/低位算法來高效的生成long, short或者 int類型的標識符。給定一個表和字段(默認分別是是hibernate_unique_key 和next_hi)作爲高位值得來源。高/低位算法生成的標識符只在一個特定的數據庫中是唯一的。在使用JTA獲得的連接或者用戶自行提供的連接中,不要 使用這種生成器。

seqhilo(使用序列的高低位) 
使用一個高/低位算法來高效的生成long, short或者 int類型的標識符,給定一個數據庫序列(sequence)的名字。

uuid.hex 
用一個128-bit的UUID算法生成字符串類型的標識符。在一個網絡中唯一(使用了IP地址)。UUID被編碼爲一個32位16進制數字的字符串。

uuid.string 
使用同樣的UUID算法。UUID被編碼爲一個16個字符長的任意ASCII字符組成的字符串。不能使用在PostgreSQL數據庫中

native(本地) 
根據底層數據庫的能力選擇identity, sequence 或者hilo中的一個。

assigned(程序設置) 
讓應用程序在save()之前爲對象分配一個標示符。

foreign(外部引用)

-------------------------------------------------------------------------------------------------------------------------

3.property 節點
1.column                數據庫表字段名稱
2.type                  類型
3.length                長度
4.not-null              字段是否允許爲空
5.unique                字段是否允許唯一(是否允許重複值)
6.insert                insert操作時,是否允許包含本字段數值
7.update                update操作時,是否包含本字段數據



特別說明

現在有個問題,按平常思路就是,得在數據庫中創建一個student表吧,字段及類型得與Student類吻合,其實不用,爲什麼這麼說,因爲在hibernate.cfg.xml中 <property name="hibernate.hbm2ddl.auto">update</property>這句話配置的值爲update就表示沒有表的情況下會在執行數據庫操作前自動創建數據庫表,這下就省了好多事了



不過,如果你非要手工去創建,寫SQL語句在數據庫工具中也沒必要,hibernate有相應的API支持你生成對應的數據庫表

下面這個類就就可以

創建數據庫表的類DBScriptExport .Java



Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.common;  
  2.   
  3. import org.hibernate.cfg.Configuration;  
  4. import org.hibernate.tool.hbm2ddl.SchemaExport;  
  5.   
  6. /** 
  7.  * 根據對象關係映射文件直接生成數據庫表或生成建表的腳本 
  8.  *  
  9.  */  
  10. public class DBScriptExport {  
  11.   
  12.     public static void main(String[] args) {  
  13.         export2File("dbcript.sql");  
  14.     }  
  15.       
  16.     public static void export2DB(){  
  17.         //加載Hibernate的全局配置文件  
  18.         Configuration config = new Configuration().configure();  
  19.         SchemaExport export = new SchemaExport(config);  
  20.         export.create(truetrue);  
  21.     }  
  22.       
  23.     public static void export2File(String dest){  
  24.         Configuration config = new Configuration().configure();  
  25.         SchemaExport export = new SchemaExport(config);  
  26.           
  27.         export.setOutputFile(dest)  
  28.             .setDelimiter(";")  
  29.             .setFormat(true)  
  30.             .create(truefalse);  
  31.     }  
  32.   
  33. }  
  34. </span></span>  

 

獲取session的HibernateUtil.java


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.common;  
  2.   
  3. import org.hibernate.Session;  
  4. import org.hibernate.SessionFactory;  
  5. import org.hibernate.cfg.Configuration;  
  6.   
  7. /** 
  8.  * Hibernate工具類 
  9.  *  
  10.  */  
  11. public class HibernateUtil {  
  12.     private static final SessionFactory factory;  
  13.       
  14.     private HibernateUtil(){}  
  15.       
  16.     static{  
  17.         //加載Hibernate全局配置文件,根據配置信息創建SessionFactory工廠實例  
  18.         factory = new Configuration().configure().buildSessionFactory();  
  19.     }  
  20.       
  21.     public static SessionFactory getSessionFactory(){  
  22.         return factory;  
  23.     }  
  24.       
  25.     public static Session getSession(){  
  26.         return factory.openSession();  
  27.     }  
  28. }  
  29. </span></span>  

 最後的測試類HibernateTest.java


Java代碼  收藏代碼
  1. <span style="font-size: large;"><span style="font-size: large;">package com.javacrazyer.test;  
  2.   
  3. import java.util.Date;  
  4. import java.util.List;  
  5.   
  6. import org.hibernate.Criteria;  
  7. import org.hibernate.HibernateException;  
  8. import org.hibernate.Query;  
  9. import org.hibernate.Session;  
  10. import org.hibernate.Transaction;  
  11. import org.hibernate.criterion.Order;  
  12. import org.junit.Assert;  
  13. import org.junit.Test;  
  14.   
  15. import com.javacrazyer.common.HibernateUtil;  
  16. import com.javacrazyer.domain.Student;  
  17.   
  18. /** 
  19.  * 使用Hibernate API完成CRUD 
  20.  * 更復雜的持久化操作需要使用到Query接口 
  21.  *  
  22.  */  
  23. public class HibernateTest {  
  24.       
  25.     @Test  
  26.     public void testAdd(){  
  27.         Student stu = new Student();  
  28.         stu.setName("test");  
  29.         stu.setBirthday(new Date());  
  30.         stu.setAge(1);  
  31.         stu.setGender(true);  
  32.         stu.setScore(66.8);  
  33.           
  34.         //利用工廠打開一個Session實例  
  35.         Session session = HibernateUtil.getSession();  
  36.           
  37.         //開啓一個操作事務  
  38.         Transaction tx = session.beginTransaction();  
  39.           
  40.         //利用session進行持久化操作  
  41.         session.save(stu);  
  42.           
  43.         //提交事務  
  44.         tx.commit();  
  45.           
  46.         //關閉Session  
  47.         session.close();  
  48.     }  
  49.       
  50.     @Test  
  51.     public void getStu(){  
  52.           
  53.         //持久化管理器  
  54.         Session session = null;  
  55.         Transaction tx = null;  
  56.         try{  
  57.             session = HibernateUtil.getSession();  
  58.           
  59.             tx = session.beginTransaction();  
  60.           
  61.             //根據ID查詢實體對象  
  62.             Student stu = (Student)session.get(Student.class1);  
  63.               
  64.             Assert.assertNotNull(stu);  
  65.             System.out.println(stu);  
  66.           
  67.             tx.commit();  
  68.         }catch(HibernateException he){  
  69.             he.printStackTrace();  
  70.             tx.rollback();  
  71.         }finally{  
  72.             if(null != session && session.isOpen()){  
  73.                 try{  
  74.                     session.close();  
  75.                 }catch(HibernateException e){  
  76.                     e.printStackTrace();  
  77.                 }  
  78.             }  
  79.         }  
  80.     }  
  81.       
  82.     @Test  
  83.     public void testUpdate(){  
  84.         Session session = null;  
  85.           
  86.         try{  
  87.             session = HibernateUtil.getSession();  
  88.               
  89.             session.beginTransaction();  
  90.               
  91.             Student stu = (Student)session.get(Student.class1);  
  92.             stu.setName("zs");  
  93.             stu.setScore(52.1);  
  94.           
  95.             session.update(stu);  
  96.               
  97.             session.getTransaction().commit();  
  98.         }catch(HibernateException e){  
  99.             Assert.fail();  
  100.             e.printStackTrace();  
  101.             session.getTransaction().rollback();  
  102.         }finally{  
  103.             if(session != null && session.isOpen()){  
  104.                 session.close();  
  105.             }  
  106.         }  
  107.     }  
  108.       
  109.     @Test  
  110.     public void testDelete(){  
  111.         Session session = null;  
  112.           
  113.         try{  
  114.             session = HibernateUtil.getSession();  
  115.             //session.beginTransaction();  
  116.               
  117.             Student stu = (Student)session.get(Student.class2);  
  118.             System.out.println(stu);  
  119.             session.delete(stu);  
  120.               
  121.             //session.getTransaction().commit();  
  122.         }catch(HibernateException e){  
  123.             Assert.fail();  
  124.             e.printStackTrace();  
  125.             //session.getTransaction().rollback();  
  126.         }finally{  
  127.             if(session != null && session.isOpen()){  
  128.                 session.close();  
  129.             }  
  130.         }  
  131.     }  
  132.       
  133.     @Test  
  134.     public void testGet(){  
  135.         Session session = null;  
  136.           
  137.         try{  
  138.             session = HibernateUtil.getSession();  
  139.             session.beginTransaction();  
  140.               
  141.             Student stu = (Student)session.get(Student.class2);  
  142.   
  143.             System.out.println(stu);  
  144.               
  145.             Student stu2 = (Student) session.get(Student.class2);  
  146.               
  147.             System.out.println(stu2);  
  148.               
  149.             session.getTransaction().commit();  
  150.         }catch(HibernateException e){  
  151.             Assert.fail();  
  152.             e.printStackTrace();  
  153.             session.getTransaction().rollback();  
  154.         }finally{  
  155.             if(session != null && session.isOpen()){  
  156.                 session.close();  
  157.             }  
  158.         }  
  159.     }  
  160.       
  161.     @Test  
  162.     public void testGet2(){  
  163.             Session session = null;  
  164.           
  165.             session = HibernateUtil.getSession();  
  166.             session.beginTransaction();  
  167.             Student stu = (Student)session.get(Student.class2);  
  168.             System.out.println(stu);  
  169.             session.getTransaction().commit();  
  170.             session.close();  
  171.               
  172.             session = HibernateUtil.getSession();  
  173.             session.beginTransaction();  
  174.             Student stu2 = (Student) session.get(Student.class2);  
  175.             System.out.println(stu2);  
  176.             session.getTransaction().commit();  
  177.             session.close();  
  178.     }  
  179.       
  180.     @SuppressWarnings("unchecked")  
  181.     @Test  
  182.     public void testQuery(){  
  183.         Session session = null;  
  184.         try{  
  185.             session = HibernateUtil.getSession();  
  186.             session.beginTransaction();  
  187.               
  188.             Query query = session.createQuery("from Student");  
  189.             List<Student> stus = query.list();  
  190.               
  191.             for(Student stu : stus){  
  192.                 System.out.println(stu);  
  193.             }  
  194.               
  195.             session.getTransaction().commit();  
  196.           
  197.         }catch(HibernateException e){  
  198.             e.printStackTrace();  
  199.             session.getTransaction().rollback();  
  200.         }finally{  
  201.             if(session != null && session.isOpen()){  
  202.                 session.close();  
  203.             }  
  204.         }  
  205.     }  
  206.       
  207.     @SuppressWarnings("unchecked")  
  208.     @Test  
  209.     public void testCriteria(){  
  210.         Session session = null;  
  211.         try{  
  212.             session = HibernateUtil.getSession();  
  213.             session.beginTransaction();  
  214.               
  215.             Criteria criteria = session.createCriteria(Student.class);  
  216.               
  217.             List<Student> stus = criteria.addOrder(Order.desc("id")).list();  
  218.               
  219.             for(Student stu : stus){  
  220.                 System.out.println(stu);  
  221.             }  
  222.               
  223.             session.getTransaction().commit();  
  224.           
  225.         }catch(HibernateException e){  
  226.             e.printStackTrace();  
  227.             session.getTransaction().rollback();  
  228.         }finally{  
  229.             if(session != null && session.isOpen()){  
  230.                 session.close();  
  231.             }  
  232.         }  
  233.     }  
  234.       
  235. }</span></span>  

 

補充說明:

如果在hibernate.cfg.xml中配置的是

 <property name="hibernate.hbm2ddl.auto">create</property>

這種配置前提是表已經存在

在這種情況下,只要你在項目的src下新建一個文件夾命名爲import.sql,並且裏面寫上數據庫插入語句,那麼就會執行插入操作,爲什麼只是插入,這得跟create值的這種創建啊方式有關,它是啓動hibernate時先刪除已存在的表,後新建表,新建的表本身就是空的,當然只能進行插入操作了

import.sql

Java代碼  收藏代碼
  1. <span style="font-size: large;">insert into student(name,age,gender,birthday,score) values('test2',10,false,now(),11.2);</span>  
 這時,如果你在執行上面那個測試類的添加方法,就會發現,結果插入了兩條數據,一條是import.sql中的,一條是測試方法中的,顯然import.sql中的先執行,因爲在hibernate啓動時就執行了
發佈了7 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章