1. 程式人生 > >Hibernate學習(一)

Hibernate學習(一)

!= 功能 exceptio class 獨立 gpo 應用 () 調試

一、什麽是Hibernate?

  Hibernate是一個輕量級的ORMapping框架   ORMapping原理(Object Relational Mapping 技術分享圖片 ORMapping基本對應規則: 1:類跟表相對應 2:類的屬性跟表的字段相對應 3:類的實例與表中具體的一條記錄相對應 4:一個類可以對應多個表,一個表也可以對應對個類 5:DB中的表可以沒有主鍵,但是Object中必須設置主鍵字段 6:DB中表與表之間的關系(如:外鍵)映射成為Object之間的關系 7:Object中屬性的個數和名稱可以和表中定義的字段個數和名稱不一樣

二、Hibernate能幹什麽:

Hibernate主要用來實現Java對象和表之間的映射,除此之外還提供還提供數據查詢和獲取數據的方法,可以大幅度減少開發時人工使用SQL和JDBC處理數據的時間。 Hibernate的目標是對於開發者通常的數據持久化相關的編程任務,解放其中的95%。對於以數據為中心的程序來說,它們往往只在數據庫中使用存儲過程來實現商業邏輯,Hibernate可能不是最好的解決方案;對於那些在基於Java的中間層應用中,它們實現面向對象的業務模型和商業邏輯的應用,Hibernate是最有用的。 Hibernate可以幫助你消除或者包裝那些針對特定廠商的SQL代碼,並且幫你把結果集從表格式的表示形式轉換到一系列的對象去。

(三)Hibernate中的對象

SessionFactory (org.hibernate.SessionFactory) 針對單個數據庫映射關系經過編譯後的內存鏡像,是線程安全的(不可變)。 它是生成的工廠,本身要用到。 Session (org.hibernate.Session) 表示應用程序與持久儲存層之間交互操作的一個單線程對象,此對象生存期很短,隱藏了連接,也是的工廠。 Transaction (org.hibernate.Transaction) 應用程序用來指定原子操作單元範圍的對象,它是單線程的,生命周期很短。它通過抽象將應用從底層具體的、以及事務隔離開。 ConnectionProvider (org.hibernate.connection.ConnectionProvider)
生成連接的工廠(有連接池的作用)。它通過抽象將應用從底層的或隔離開。僅供開發者擴展/實現用,並不暴露給應用程序使用。 TransactionFactory (org.hibernate.TransactionFactory) 生成對象實例的工廠。僅供開發者擴展/實現用,並不暴露給應用程序使用。 示例如下: 數據庫表:Student.sql
create table student (
 studo  varchar2(20),
 stuname varchar2(20),
 STUPASS varchar2(20),
 STUSEX  VARCHAR2(2),
 MOBILE  VARCHAR2(
2), EMAIL VARCHAR2(20), ADDRESS VARCHAR2(50), STUAGE NUMBER );

配置文件:hibernate.cfg.xml 註意配置文件要寫在src下 否則會加載不到

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
     <session-factory>
            <!-- 數據庫URL -->
            <property name = "connection.url">jdbc:oracle:thin:@10.103.1.204:1521:orcl</property>
            <!-- jdbc驅動 -->
            <property name ="conneciton.driver_class">oracle.jdbc.driver.OracleDriver</property>
            <!-- 賬號 -->
            <property name = "connection.username">ybt</property>
            <!-- 密碼 -->
            <property name = "connection.password">ybt!123</property>
            <!-- 每個數據庫都有對應的Dialect以匹配其平臺特性 -->
            <property name  = "dialect">org.hibernate.dialect.Oracle10gDialect</property>
            <!-- 指定當前session範圍和上下文 -->
            <property name = "current_session_context_class">thread</property>
            <!-- 指定運行期生成的SQL輸出到日誌以供調試 -->
            <property name = "show_sql">true</property>
            <!-- 是否格式化SQL -->
            <property name = "format_sql">true</property>
            <!-- 映射文件 -->
            <mapping resource="student.hbm.xml" />
     </session-factory>
</hibernate-configuration>

映射文件:Student.hbm.xml

?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 ="entity.student"  table ="STUDENT">
         <id name = "studo" type = "java.lang.String" column = "studo">
          <!--generator的class類型
                assigned:主鍵的狀態 assigned表示程序生成
                sequence:Oracle中的序列
                identity:Sql中的自動編號
                increment:先查詢最大的編號再增1
                uuid:生成32位長的字符串
                native:根據數據庫自動生成
             -->
           <generator class="assigned"/>
         </id>
           <!-- 直接使用property屬性設置 -->
         <property name = "stuname"  type = "java.lang.String" column="stuname" length="50" not-null="true"/>
         <property name="stupass" type ="java.lang.String" column ="STUPASS">
         <!-- 使用column設置 -->
         <!--測試發現colum在上層元素使用之後再使用會報錯
         <column name="STUPASS" length="50" not-null="true"/> -->
         </property>
         <property name="stusex" type ="java.lang.String" column ="STUSEX"/>
         <property name="stuage" type ="java.lang.Integer" column ="STUAGE"/>
         <property name="mobile" type ="java.lang.String" column ="MOBILE"/>
         <property name="email"  type ="java.lang.String" column ="EMAIL"/>
         <property name="address" type ="java.lang.String" column ="ADDRESS"/>  
        </class>    
</hibernate-mapping>

java代碼:StudentService.java

/**
 * @author Administrator
 *
 */
package entity.dao;

import java.util.List;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import entity.student;

public class  studentService{
    
    private static Configuration conf; 
    private static SessionFactory sf; 
    private static Transaction tx;  
    
 static{
     try{
         /**
          * Configuration()的configure()方法會默認在classpath下尋找hibernate.cnf.xml
          * 如果沒有找到該文件,系統會打印如下信息並拋出HibernateException異常
          * 其實不使用configure()方法也可以Configuration cfg =new Configuration();
          * 這時hibernate會在classpath下面尋找hibernate.properties文件
          * 如果沒有找到該文件,系統會打印如下信息並拋出HibernateException異常。
          * 使用hibernate.properties配置連接數據庫時,
          * 還需要使用cfg.addClass()方法,把pojo類加載進來。
          */
         conf = new Configuration().configure();         //實例化hibernate.cnf.xml的配置
         sf = conf.buildSessionFactory();             ////實例化一個session工程對象
         
     } catch(HibernateException e){
       e.printStackTrace();
 }
}
 public static Session getSession(){
     return sf.openSession(); //過去老的方法,不需要使用事務
   //return sf.getCurrentSession();// 新的方法,需要和事務一起使用,可以保證每個用戶創建的session獨立,需要在配置文件中配置 
     //<property name="current_session_context_class">thread</property>
 }
 
 /**
  * 獲取所有學生列表
  * @return
  */
 public List GetAllStudent(){
     List list = null;
     Session session = getSession();
     if(session != null){
         try{
            String hql = "from student";
            Query query = session.createQuery(hql);
            list = query.list();
         }catch(HibernateException e){
             e.printStackTrace();
         }finally{
             session.close();
         }
     }
    return list; 
 }
 
 /**
  * 獲取單個學生信息
  * @param studo
  * @return
  */
   public student GetStudentBystudo(String studo){
    student stu = null;
    Session session = getSession();
    if(session != null){
        try{
        // get如果沒有查詢到數據,則返回null
        // stu = (Student) session.get(Student.class, stuNo);
        stu = (student) session.load(student.class, studo);// load如果沒有查詢到數據,則拋出異常
        
        }catch(HibernateException e){
            e.printStackTrace();
        }finally{
            session.close();
        }
    }
    return stu;   
   }
 
 /**
  * 添加一個學生
  * @param stu
 * @throws SystemException 
 * @throws HeuristicRollbackException 
 * @throws HeuristicMixedException 
 * @throws RollbackException 
 * @throws IllegalStateException 
 * @throws SecurityException 
  */
 
   public boolean AddStudent(student stu) throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException{
       boolean result  = false;
       Session session = getSession();
       if(session != null){
           try{
               tx = (Transaction) session.beginTransaction(); //開啟一個事務
               session.save(stu);   //保存
               tx.commit();  //提交事務
               result = true;
           }catch(HibernateException e){
               e.printStackTrace();
               tx.rollback();  //如果報錯 則回滾
           }finally{
               session.close();
           }
       }
    return result;       
   }
 /**
  * 更新一個學生   這裏只舉一個更新手機號的例子
  * @param stu
 * @throws SystemException 
 * @throws HeuristicRollbackException 
 * @throws HeuristicMixedException 
 * @throws RollbackException 
 * @throws IllegalStateException 
 * @throws SecurityException 
  */
 public boolean UpdateStudent(String studo,String newMobile) throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException{
     boolean result = false;
     Session session = getSession();
     if(session != null){
         try{
            // 開啟一個事務
             tx = (Transaction) session.beginTransaction();
             // 獲取一個學生對象
             student stu = (student) session.load(student.class, studo);
          // 更新某個屬性
           stu.setMobile(newMobile);
           // 提交事務
           tx.commit();
           result = true;
         }catch(HibernateException e){
             e.printStackTrace();
             tx.rollback();   //更新失敗需要回滾
         }finally{
             session.close();
         }
     }
    return result;     
 }
}

test.java

/**
 * @author Administrator
 *
 */
package text;
import java.util.List;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

import entity.student;
import entity.dao.studentService;

public class textHibernateSQL{
    public static void main(String []args) throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException{
        //添加兩個學生   
        //AddStudent();  成功
        //查出全部的學生
        //getAllStudent();  成功
        //查詢一個學生
        getStudentById();  
        //更新一個學生
        //UpdateStudent();  成功
    }

    private static void UpdateStudent() throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException {
        studentService ss = new studentService();
        String studo = "201205457";
        String newMobile = "00";
        ss.UpdateStudent(studo, newMobile);
    }

    private static void getStudentById() {
        studentService ss = new studentService();
        String no = "201205457";
        student st = ss.GetStudentBystudo(no);
        System.out.println(st.getAddress());
    }

    private static void getAllStudent() {
        studentService ss = new studentService();
        List<student> list =  ss.GetAllStudent();    
        for(student st: list){
            System.out.println(st.getStuname()+"  "+st.getStuage());
        }
    }

    private static void AddStudent() throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException {
        studentService ss = new studentService();
        student st = new student();
        st.setStuname("大偉哥");
        st.setAddress("天津南開");
        st.setEmail("[email protected]");
        st.setMobile("12");
        st.setStuage(24);
        st.setStudo("201205457");
        st.setStupass("WHAT");
        st.setStusex("1");
        ss.AddStudent(st);
        
    }
}
說明: 1:SessionFactory sf = new Configuration().configure().buildSessionFactory();這句話的意思是讀取hibernate.cfg.xml,創建Session工廠,是線程安全的。 默認是”hibernate.cfg.xml”,不用寫出來,如果文件名不是”hibernate.cfg.xml”,那麽需要顯示指定,如下: SessionFactory sf = new Configuration(). configure( “javass.cfg.xml” ).buildSessionFactory(); 2:Session是應用程序主要使用的Hibernate接口,約相當於JDBC的Connection+Statement/PreparedStatement的功能,是線程不安全的 3:這裏使用的事務Transaction是Hibernate的Transaction,需要有,不能去掉。

Hibernate學習(一)