1. 程式人生 > >【框架】[Hibernate]構架知識點詳解入門與測試例項

【框架】[Hibernate]構架知識點詳解入門與測試例項

Hibernate介紹:

Hibernate是一個開放原始碼的、非常優秀、成熟的O/R Mapping框架。它提供了強大、高效能的Java物件和關係資料的持久化和查詢功能。

O/R Mapping
物件關係對映(Object Relational Mapping,簡稱ORM)技術,是通過使用描述物件和資料庫之間對映的元資料,將Java程式中的物件自動持久化到關係資料庫中。
物件和關係資料是業務實體的兩種表現形式,業務實體在記憶體中表現為物件,在資料庫中表現為關係資料。記憶體中的物件之間存在關聯和繼承關係,而在資料庫中,關係資料無法直接表達多對多關聯和繼承關係。因此,物件-關係對映(ORM)系統一般以中介軟體的形式存在,主要實現程式物件到關係資料庫資料的對映。

Hibernate 只是一個將持久化類與資料庫表相對映的工具,每個持久化類例項均對應於資料庫表中的一條資料行。可以使用面向物件的方法操作此持久化類例項,完成對資料庫表的插入、刪除、修改等操作。

利用Hibernate操作資料庫,我們通過應用程式經過Hibernate持久層來訪問資料庫,其實Hibernate完成了以前JDBC的功能,不過Hibernate使用面向物件的方法操作資料庫。

Hibernate體系結構圖:

Hibernate構架入門步驟

第1步: 先建一個Java工程匯入使用Hibernate最小必要包。
一般在解壓後的lib目錄下的

required目錄下。
可以到官方網站

http://hibernate.org/orm/downloads/ 下載Hibernate最新的zip壓縮包。
如果訪問資料庫,則還需要匯入資料庫的驅動包。
mysql-connector-java-5.1.39 .zip下載地址:

第2步:在src建立配置檔案hibernate.cfg.xml,放置在src目錄下。

第3步:編寫一個會話工廠類。通過會話工廠類產生一個會話Session物件。Session物件是Hibernate的核心。任何對資料庫操作都在會話中進行的。

對於熟悉C3P0的朋友,可以按下面的理解:
(配置檔案hibernate.cfg.xml可以類比c3p0.properties的配置檔案,HibernateSessionFactory可以類比C3p0Pool,SessionFactory可以類比C3p0中的DataSource,Session可以類比Connection去理解)

第4步:編寫POJO類以及對映檔案。
POJO(POJO(Plain Ordinary Java Object)簡單的Java物件,實際就是普通JavaBeans)

第5步:編寫測試檔案

hibernate.cfg.xml配置檔案詳解

hibernate.cfg.xml其實這個名字自己可以隨便取的,但是大家都這麼取名,於是形成了一個習慣了!!!

<?xml version='1.0' encoding='UTF-8'?>
<!--標準的XML檔案的起始行,version='1.0'表明XML的版本,encoding='UTF-8'表明XML檔案的編碼方式 -->

<!--表明解析本XML檔案的DTD文件位置,DTD是Document Type Definition 的縮寫,即文件型別的定義,
XML解析器使用DTD文件來檢查XML檔案的合法性。
hibernate.sourceforge.net/hibernate-configuration-3.0dtd可以在Hibernate3.1.3軟體包中的
src\org\hibernate目錄中找到此檔案-->   
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!--宣告Hibernate配置檔案的開始 -->
<hibernate-configuration>

    <!--表明以下的配置是針對session-factory配置的,SessionFactory是Hibernate中的一個類,
    這個類主要負責儲存HIbernate的配置資訊,以及對Session的操作-->   
    <session-factory>
        <!--配置資料庫的驅動程式,Hibernate在連線資料庫時,需要用到資料庫的驅動程式-必須 -->
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <!--設定資料庫的連線url:jdbc:mysql://127.0.0.1:3306/hib,其中127.0.0.1表示mysql伺服器名稱,
        3306是連線埠,此處為本機,hib是資料庫名-必須 -->
        <property name="connection.url">
            jdbc:mysql://127.0.0.1:3306/hib
        </property>
        <!-- 設定資料庫的使用者名稱 -必須 -->
        <property name="connection.username">root</property>
        <!-- 設定資料庫的密碼 -必須 -->
        <property name="connection.password">1234</property>
        <!--資料庫連線池的大小 -->
        <!-- <property name="connection.pool.size">20 </property> 與下句是一樣的 -->
        <property name="hibernate.connection.pool.size">20 </property>

        <!--是否在後臺顯示Hibernate用到的SQL語句,開發時設定為true,便於查錯,
        程式執行時可以在Eclipse的控制檯顯示Hibernate的執行Sql語句。
        專案部署後可以設定為false,提高執行效率-->   
        <property name="hibernate.show_sql">true </property>   

        <!--jdbc.fetch_size是指Hibernate每次從資料庫中取出並放到JDBC的Statement中的記錄條數。
        Fetch Size設的越大,讀資料庫的次數越少,速度越快,Fetch Size越小,讀資料庫的次數越多,速度越慢-->   
        <property name="jdbc.fetch_size">50 </property> 

        <!--jdbc.batch_size是指Hibernate批量插入,刪除和更新時每次操作的記錄數。
        Batch Size越大,批量操作的向資料庫傳送Sql的次數越少,速度就越快,同樣耗用記憶體就越大-->   
        <property name="jdbc.batch_size">23 </property>  

        <!--jdbc.use_scrollable_resultset是否允許Hibernate用JDBC的可滾動的結果集。
        對分頁的結果集。對分頁時的設定非常有幫助-->   
        <property name="jdbc.use_scrollable_resultset">false </property> 

        <!--connection.useUnicode連線資料庫時是否使用Unicode編碼-->   
        <property name="connection.useUnicode">true</property>   
        <!--connection.characterEncoding連線資料庫時資料的傳輸字符集編碼方式-->   
        <property name="connection.characterEncoding">utf-8</property> 


<!--hibernate.dialect 只是Hibernate使用的資料庫方言,就是要用Hibernate連線那種型別的資料庫伺服器。-->   
        <!--這句不用管,照寫就是 -必須 -->
        <property name="dialect">
            org.hibernate.dialect.MySQLDialect
        </property>

        <!-- 指定對映檔案為“cn/hncu/domain/Student.hbm.xml”,可以有多個 -用到了就必須 -->
        <mapping resource="cn/hncu/domain/Student.hbm.xml" />
    </session-factory>

</hibernate-configuration>

簡單配置版:

<?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>
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="connection.url">
        jdbc:mysql://127.0.0.1:3306/hib
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">1234</property>

    <property name="dialect">
        org.hibernate.dialect.MySQLDialect
    </property>

    <mapping resource="cn/hncu/domain/Student.hbm.xml"/>
</session-factory>

</hibernate-configuration>

Hibernate核心介面

(1) Configuration介面

Configuration 介面負責管理Hibernate 的配置資訊。為了能夠連上資料庫必須配置一些屬性,這些屬性包括:
資料庫URL
資料庫使用者
資料庫使用者密碼
資料庫JDBC驅動類
資料庫dialect,用於對特定資料庫提供支援,其中包含了針對特定資料庫特性的實現。

 /*建立一個配置物件,讀取配置檔案*/
 Configuration config = new Configuration();
 config.configure("/hibernate.cfg.xml");

(2) SessionFactory介面

應用程式從SessionFactory(會話工廠)裡獲得Session(會話)例項。
這裡用到了一個設計模式即工廠模式,使用者程式從工廠類SessionFactory中取得Session的例項。
SessionFactory不是輕量級的。它佔的資源比較多,所以它應該能在整個應用中共享。
一個專案通常只需要一個SessionFactory就夠了,但是當專案要操作多個數據庫時,必須為每個資料庫指定一個SessionFactory。
會話工廠快取了生成的SQL語句和Hibernate在執行時使用的對映元資料。它也儲存了在一個工作單元中讀入的資料並且可能在以後的工作單元中被重用(只有類和集合對映指定了使用這種二級快取時才會如此)Session類。

/*通過配置物件產生一個會話工廠*/
    SessionFactory factory=config.buildSessionFactory();

(3) Session介面

該介面是Hibernate使用最多的介面。Session不是執行緒安全的,它代表與資料庫之間的一次操作。
Session是持久層操作的基礎,相當於JDBC中的Connection。然而在Hibernate中,例項化的Session是一個輕量級的類,建立和銷燬它都不會佔用很多資源。
Session通過SessionFactory開啟,在所有的工作完成後,需要關閉。但如果在程式中,不斷地建立以及銷燬Session物件,則會給系統帶來不良影響。所以有時需要考慮session的管理合理的建立合理的銷燬。

/*通過工廠產生一個會話*/
     Session session=factory.openSession();

(4) Query類

Query類可以很方便地對資料庫及持久物件進行查詢,它可以有兩種表達方式:查詢語句使用HQL(面向”值物件”,HQL語言) (HQL是Hibernate Query Lanaguage簡稱是Hibernate配備了一種非常強大的查詢語言,類似於SQL)或者本地資料庫的SQL語句(面向”資料表”,SQL語言)編寫。

/*通過會話產生一個查詢物件*/
        Query query = session.createQuery("from Student");//Student是POJO類,需要在配置檔案中設定好對映
        /*通過查詢物件查詢資料庫,返回集合*/
        List list = query.list();
        for (int i = 0; i < list.size(); i++) {
            Student student= (Student) list.get(i);
            System.out.println(Student.getDname());
        }

(5) Transaction介面

如果你向資料庫中增加資料或修改資料時,需要使用事務處理,這時你需要Transaction介面。
Transaction介面是對實際事務實現的一個抽象,該介面可以實現JDBC的事務、JTA中的UserTransaction、甚至可以是CORBA事務等跨容器的事務。
之所以這樣設計是能讓開發者能夠使用一個統一事務的操作介面,使得自己的專案可以在不同的環境和容器之間方便地移值。

一個完整示例,顯示了Hibernate程式設計基本思路

首先,準備好例項資料庫:

create database hib charset=utf8;
use hib;
create table students(
    sId varchar(8) primary key,
    sName varchar(40),
    sAge int
);
insert into students(sId,sName,sAge) values('S001','Jack',23);
insert into students(sId,sName,sAge) values('S002','Tom',25);
insert into students(sId,sName,sAge) values('S003','張三',43);
insert into students(sId,sName,sAge) values('S004','李四',55);

準備好必要的jar包。

接下來配置好hibernate.cfg.xml檔案:

前面有的,就不重複了,配個圖好了。

POJO類:

package cn.hncu.domain;

public class Student {
    private String sId;
    private String sName;
    private Integer sAge;

    public Student() {
        super();
    }
    public String getsId() {
        return sId;
    }
    public void setsId(String sId) {
        this.sId = sId;
    }
    public String getsName() {
        return sName;
    }
    public void setsName(String sName) {
        this.sName = sName;
    }
    public Integer getsAge() {
        return sAge;
    }
    public void setsAge(Integer sAge) {
        this.sAge = sAge;
    }
    @Override
    public String toString() {
        return "Student [sId=" + sId + ", sName=" + sName + ", sAge=" + sAge
                + "]";
    }
}

cn/hncu/domain/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 package="cn.hncu.domain">

    <!--name指的是POJO類的類名,table是資料庫的表名,catalog是資料庫的名稱  -->
    <class name="Student" table="students" catalog="hib">
        <!--id表示此欄位為資料庫的主鍵,這裡也可以用property來寫,name為Student類的成員變數名,type為型別的包全名  -->
        <id name="sId" type="java.lang.String">
            <!--column表示對映的資料庫的欄位,name表示資料庫中欄位名,length表示varchar/char型的長度  -->
            <column name="sId" length="8"></column>
        </id>
        <property name="sName" type="java.lang.String">
            <column name="sName" length="40" />
        </property>
        <property name="sAge" type="java.lang.Integer">
            <column name="sAge" />
        </property>
    </class>

</hibernate-mapping>

HibernateSessionFactory

package cn.hncu.hib;

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

public class HibernateSessionFactory {
   private static String configFile = "/hibernate.cfg.xml";
   private static Configuration config = new Configuration();
   private static SessionFactory sessionFactory =null;

   private static final ThreadLocal<Session> t = new ThreadLocal<Session>();

   static{
       try {
           /*建立一個配置物件,讀取配置檔案*/
           config.configure(configFile);
           /*通過配置物件產生一個會話工廠類*/
           sessionFactory = config.buildSessionFactory();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
   }

   public static Session getSession() throws HibernateException{
       Session session = t.get();
       if(session == null || !session.isOpen()){
           if(sessionFactory==null){
               rebuildSessionFactory();
           }
           /*通過會話工廠類產生一個會話例項*/
           session = (sessionFactory!=null) ? sessionFactory.openSession() : null;
           t.set(session);
       }
       return session;
   }

   private static void rebuildSessionFactory() {
       try {
           config.configure(configFile);
           sessionFactory = config.buildSessionFactory();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
   }

   //關閉與資料庫的會話
   public static void closeSession() throws HibernateException{
       Session session = t.get();
       t.set(null);
       if(session!=null){
           session.close();
       }
   }
}

TestHib

package cn.hncu;

import java.util.List;

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

import cn.hncu.domain.Student;
import cn.hncu.hib.HibernateSessionFactory;

public class TestHib {

    public static void main(String[] args) {
        /*建立一個配置物件,讀取配置檔案*/
        String configfile="/hibernate.cfg.xml";
        Configuration config=new Configuration();
        config.configure(configfile);
        /*通過配置物件產生一個會話工廠類*/
        SessionFactory sessionfactory=config.buildSessionFactory();
        /*通過會話工廠類產生一個會話例項*/
        Session session=sessionfactory.openSession();
        /*通過會話產生一個查詢物件Query*/
        Query query=session.createQuery("from Student");
        /*進行查詢返回一個集合List*/
        List<Student> studs=query.list();
        for(Student s:studs){
           System.out.println(s);
        }

        session = HibernateSessionFactory.getSession();
        query = session.createQuery("from Student");
        List<Student> students = query.list();
        for(Student s: students){
            System.out.println(s);
        }
    }
}

測試結果:

完整例項程式碼:

相關推薦

框架[Hibernate]構架知識點入門測試例項

Hibernate介紹: Hibernate是一個開放原始碼的、非常優秀、成熟的O/R Mapping框架。它提供了強大、高效能的Java物件和關係資料的持久化和查詢功能。 O/R Mapping 物件關係對映(Object Relational

轉載瀏覽器緩存:expires cache-control last-modified

導致 lang -c csdn 判斷 屬性 lan -m load 最近在對CDN進行優化,對瀏覽器緩存深入研究了一下,記錄一下,方便後來者 畫了一個草圖: 每個狀態的詳細說明如下: 1、Last-Modified 在瀏覽器第一次請求某一個URL時,服務器端的返回

linux awk命令

column 環境變量 最後一行 工作流程 初始 文本文件 for循環 其中 cti 簡介 awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切

HTTP---HTTP狀態碼

無法 用戶輸入 格式 type 發送 pan http 節點 wiki https://en.wikipedia.org/wiki/List_of_HTTP_status_codes 1、百科名片 HTTP狀態碼(HTTP Status Code)是用以表示網頁服

HTMLHttp分段下載

多線程 ces 數值 alt locks www. 支持 read rand 一.為什麽需要Http分段下載 在實際的業務開發中,大文件使用Http普通下載非常容易OOM(內存溢出)或是鏈接超時的錯誤,這種情況下應該就應該考慮使用Http的分段下載了。下面筆者為你

Code First 屬性

map 時間 range get con 如果 per rem att 下面解釋每個配置的作用 Table :用於指定生成表的表名、架構信息。 Column :用於指定生成數據表的列信息,如列名、數據類型、順序等。 Key :用於指定任何名稱的屬性作為主鍵列並且默認將此列作

Lambda表達式

執行 pan mpi 新增 turn sum 下層 裏的 泛型類 前言 1、天真熱,程序員活著不易,星期天,也要頂著火辣辣的太陽,總結這些東西。 2、誇誇lambda吧:簡化了匿名委托的使用,讓你讓代碼更加簡潔,優雅。據說它是微軟自c#1

MySQLlower_case_table_names參數

安裝 系統 str pre 大寫 mysq db_name mysql 查看 簡介: lower_case_table_names 是mysql設置大小寫是否敏感的一個參數。 1.參數說明: lower_case_table_names=0 表名存儲為給定的大小和比較是

TestNGTestNG使用教程

一、TestNG介紹 TestNG是Java中的一個測試框架, 類似於JUnit 和NUnit, 功能都差不多, 只是功能更加強大,使用也更方便。 詳細使用說明請參考官方連結:https://testng.org/doc/index.html 二、TestNG安裝(基於eclipse

JAVA的內部類

轉載部落格: https://www.cnblogs.com/dolphin0520/p/3811445.html 作者:海 子   說起內部類這個詞,想必很多人都不陌生,但是又會覺得不熟悉。原因是平時編寫程式碼時可能用到的場景不多

linuxValgrind工具集(十五):Callgrind(效能分析圖)

一、概述 1、Callgrind Callgrind用於記錄程式中函式之間的呼叫歷史資訊,對程式效能分析。預設情況下,收集的資料包括執行的指令數,它們與原始碼行的關係,函式之間的呼叫者、被呼叫者關係以及此類呼叫的數量。可選項是,對快取記憶體模擬和分支預測(類似於Cachegrin

linuxValgrind工具集(十四):Cachegrind(快取和分支預測分析器)

一、概述 Cachegrind,它模擬CPU中的一級快取I1,Dl和二級快取,能夠精確地指出程式中cache的丟失和命中。如果需要,它還能夠為我們提供cache丟失次數,記憶體引用次數,以及每行程式碼,每個函式,每個模組,整個程式產生的指令數。這對優化程式有很大的幫助。 Cach

linuxValgrind工具集(十三):DRD(執行緒錯誤檢測器)

一、概述 多執行緒程式設計需要注意的問題: 資料競爭;鎖競爭;POSIX執行緒API使用不當;死鎖; 二、使用 1、例子main.c原始碼 #include <stdio.h> #include <pthread.h> #include <s

linuxValgrind工具集(十三):Helgrind(執行緒錯誤檢測器)

一、概述 Helgrind用於檢測C、C ++和Fortran程式中使用符合POSIX標準的執行緒函式造成的同步錯誤。 POSIX中關於執行緒的主要抽象描述有:共享公共地址空間的一組執行緒、執行緒建立、執行緒連線、執行緒退出、互斥(鎖)、條件變數(執行緒間事件通知)、讀寫器鎖、自

linuxValgrind工具集(十二):DHAT:動態堆分析器

一、概述 DHAT動態堆分析器。Massif(堆分析器)是在程式結束後輸出分析結果,而DHAT是實時輸出結果,所以叫做動態堆分析器。Massif只記錄堆記憶體的申請和釋放,DHAT還會分析堆空間的使用率、使用週期等資訊。 DHAT的功能:它首先記錄在堆上分配的塊,通過分析每次記憶體訪

linuxValgrind工具集(十一):Massif(堆分析器)

一、概述 Massif是一個堆分析器。它統計程式使用的堆記憶體大小(由malloc等函式分配的記憶體)。預設情況下不統計程式所使用的所有記憶體,如果想統計所有記憶體,需要使用選項–pages-as-heap=yes。 堆分析可以幫助減少程式使用的記憶體。如果分配的記憶體還沒有釋放

linuxValgrind工具集(十):SGCheck(檢查棧和全域性陣列溢位)

一、概述 SGCheck是一種用於檢查棧中和全域性陣列溢位的工具。它的工作原理是使用一種啟發式方法,該方法源於對可能的堆疊形式和全域性陣列訪問的觀察。 棧中的資料:例如函式內宣告陣列int a[10],而不是malloc分配的,malloc分配的記憶體是在堆中。 SGCheck和Me

linuxValgrind工具集(九):Memcheck檢查的內容和方法

一、值的有效性 1、什麼是值的有效性? 英文原文是Valid-value (V) bits,直譯過來就是有效值(V)位。 我將它理解為值的有效性,就是判斷在記憶體或CPU的實體地址中儲存的資料是否有效,比如在記憶體中變數(int i)代表的物理位置(不是地址),沒有初始化,就去使用它

linuxValgrind工具集(八):Memcheck命令列引數

【linux】Valgrind工具集詳解(五):命令列詳解中不夠全,在此專門針對Memcheck工具中的命令列引數做一次詳細的解釋。 Memcheck命令列選項 –leak-check=<no|summary|yes|full> [default: summary]

linuxValgrind工具集(七):Memcheck(記憶體錯誤檢測器)

一、概述 Memcheck是一個記憶體錯誤檢測器。它可以檢測C和C ++程式中常見的以下問題: 1、非法記憶體:如越界、釋放後繼續訪問; 2、使用未初始化的值; 3、釋放記憶體錯誤:如double-free(同一記憶體上執行了兩次free)、或者 malloc、new、new[] 與