Hibernate干貨筆記——第一天

目錄

1. Hibernate框架的概述
  • 1.1 Hibernate簡介
  • 1.2 為什么要學習Hibernate
  • 1.3 Hibernate版本
2. Hibernate的日志記錄
3. Hibernate入門
  • 3.1 Hibernate框架目錄結構
  • 3.2 Hibernate入門實例
4. Hibernate的CURD操作
  • 4.1 保存記錄
  • 4.2 根據主鍵進行查詢
  • 4.3 修改記錄
  • 4.4 刪除記錄
  • 4.5 查詢所有
5. Hibernate配置
  • 5.1 核心配置文件hibernate.cfg.xml
  • 5.2 映射文件的配置Customer.hbm.xml
6. Hibernate的核心API
  • 6.1 Configuration
  • 6.2 SessionFactory
  • 6.3 Session
  • 6.4 Transaction
  • 6.5 Query
  • 6.6 Criteria
Hibernate中的持久化類

Hibernate框架的概述

Hibernate簡介

Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。

Hibernate是輕量級JavaEE應用的持久層解決方案,是一個關系數據庫ORM框架.ORM:Object Relational Mapping,將Java中的實體類與數據庫的關系表建立一個映射.就可以操作Java中對象,從而操作數據庫.

為什么要學習Hibernate
  • Hibernate對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重復性代碼
  • Hibernate是一個基于jdbc的主流持久化框架,是一個優秀的orm實現,它很大程度的簡化了dao層編碼工作
  • Hibernate使用java的反射機制,而不是字節碼增強程序類實現透明性
  • Hibernate的性能非常好,因為它是一個輕量級框架。映射的靈活性很出色。它支持很多關系型數據庫,從一對一到多對多的各種復雜關系.
Hibernate版本

Hibernate3.x版本 和 Hibernate4.x
** 企業中常用的還是Hibernate3.x.**

Hibernate的日志記錄

在hibernate使用的日志標準都為slf,slf可以看作為它的接口,因此需要找到它的實例,為我們做日志,我們選擇使用log4j為實例。
需要導入log4j-1.2.16.jar和slf4j-log4j12-1.7.2.jar
編寫property文件(log4J的配置信息)參考模板在如下位置 Hibernate_HOME/project/etc 示例中可以將log4j.properties文件拷貝出來進行修改放在項目中的classPath即src下

Hibernate入門

Hibernate框架目錄結構
目錄結構.png
Hibernate入門實例
  1. 創建一個Java工程,導入相應的jar包和配置文件
  • hibernate3.jar (核心jar包)
  • antlr-2.7.6.jar (必選jar包)
  • commons-collections-3.1.jar
  • dom4j-1.6.1.jar
  • javassist-3.12.0.GA.jar
  • jta-1.1.jar
  • slf4j-api-1.6.1.jar
  • hibernate-jpa-2.0-api-1.0.1.Final.jar(實現jpa規范jar包)
  • slf4j-log4j12-1.7.2.jar (日志記錄jar包)
  • log4j-1.2.16.jar
  • mysql-connector-java-5.0.4-bin.jar(數據庫驅動jar包)
  • log4j.properties(日志配置文件放到src下)
  1. 創建一個表
create database hibernate3_day01;
use hibernate3_day01;
create table customer(
      id int primary key auto_increment,
      name varchar(20),
      age int
);
  1. 創建一個實體類
public class Customer {
     private int id;
     private String name;
     private int age;
     public int getId() {
        return id;
    }
     public void setId(int id) {
        this.id = id;
    }
     public String getName() {
        return name;
    }
     public void setName(String name) {
        this.name = name;
    }
     public int getAge() {
        return age;
    }
     public void setAge(int age) {
        this.age = age;
    }
}
  1. 創建一個ORM映射文件
    映射文件只要是一個XML格式文件就可以.名字任意,跟需要映射的類放在一個包下
    通常情況下名稱規范:實體類名稱.hbm.xml
    引入約束:hibernate3.jar/org.hibernate.hibernate-mapping-3.0.dtd
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- 建立類與表的映射 -->
    <!-- class標簽:用于映射類與表的關系 name :類的全路徑  table:表名稱 -->
    <class name="com.java.hibernate3.demo1.Customer" table="customer">
        <!-- 建立類中屬性與表中的字段映射 -->
        <!-- 唯一標識 -->
        <!-- 使用id的標簽 配置唯一屬性 -->
        <!-- 在<id>標簽中配置一個主鍵的生成策略. -->
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <!-- 普通屬性 -->
        <!-- property標簽:映射類中的普通屬性 name:類中的屬性名稱, column:表中字段名稱 -->
        <!-- 
            type:三種寫法
                * Java類型        :java.lang.String
                * Hibernate類型   :string
                * SQL類型     :不能直接使用type屬性,需要子標簽<column>
                    * <column name="name" sql-type="varchar(20)"/>
         -->
        <property name="name" column="name" type="string"/>
        <property name="age" column="age"/>
    </class>
</hibernate-mapping>
  1. 創建hibernate核心配置文件
    通知Hibernate連接是哪個數據庫,在src下創建一個hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
    <!-- 必須去配置的屬性 -->
    <!-- 配置數據庫連接的基本信息: -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="hibernate.connection.url">
        jdbc:mysql:///hibernate3_day01
    </property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">123</property>
    <!-- Hibernate的方言 -->
    <!-- 生成底層SQL不同的 -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <!-- 可選的屬性 -->
    <!-- 顯示SQL -->
    <property name="hibernate.show_sql">true</property>
    <!-- 格式化SQL -->
    <property name="hibernate.format_sql">true</property>
    <!-- hbm:映射 to DDL: create drop alter -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- 通知Hibernate加載那些映射文件 -->
    <mapping resource="com/java/hibernate3/demo1/Customer.hbm.xml" />
 </session-factory>
</hibernate-configuration>
  1. 測試
@Test
    // 向數據庫中插入一條記錄
    public void demo1(){
        // 1.Hiberante框架加載核心配置文件(有數據庫連接信息)
        Configuration configuration = new Configuration().configure();
        // 2.創建一個SessionFactory.(獲得Session--相當連接對象)
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        // 3.獲得Session對象.
        Session session = sessionFactory.openSession();
        // 4.默認的情況下,事務是不自動提交.
        Transaction tx = session.beginTransaction();
        // 5.業務邏輯操作
        // 向數據庫中插入一條記錄:
        Customer customer = new Customer();
        customer.setName("小明");
        customer.setAge(18);
        session.save(customer);
        // 6.事務提交
        tx.commit();
        // 7.釋放資源
        session.close();
        sessionFactory.close();
    }

Hibernate的CURD操作

  1. 保存記錄
session.save(customer);
  1. 根據主鍵查詢
Customer customer = (Customer)session.get(Customer.class ,1);
Customer customer = (Customer)session.load(Customer.class,1);

get 和load的區別
① 發送SQL的時機:
load這個方法采用了一個技術.lazy延遲加載(懶加載).真正使用這個對象的數據的時候.(對象的數據不包括主鍵).
get這個方法是立即檢索.當執行session.get()方法的時候,馬上發送SQL語句查詢.
② 返回的對象:
load方法返回的是代理對象.
get方法返回的是真實的對象.
③ 查詢一個不存在的數據:
load方法拋異常:ObjectNotFoundException.
get方法拋異常:NullPointException.

  1. 修改記錄
    session.update(customer);
    修改有兩種方式 :
    手動創建對象的方式
Customer customer = new Customer();
customer.setId(2);
customer.setName("蒼老師");    
session.update(customer);
這種方式如果沒有設置的屬性,會將這個屬性的默認值存入了

先查詢在修改的方式(推薦方式)

Customer customer = (Customer) session.get(Customer.class, 1);
customer.setName("鳳姐");     
session.update(customer);
  1. 刪除記錄
    session.delete(customer);
    刪除記錄有兩種方式:
    手動創建對象的方式
Customer customer = new Customer();
customer.setId(2);
session.delete(customer);

先查詢在刪除的方式

Customer customer = (Customer)session.get(Customer.class, 1);
session.delete(customer);
  1. 查詢所有
    HQL:
    HQL:Hibernate Query Language.
    面向對象的寫法:
Query query = session.createQuery("from Customer where name = ?");
query.setParameter(0, "蒼老師");
Query.list();

QBC:
Query By Criteria.(條件查詢)

Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "小明"));
List<Customer> list = criteria.list();

SQL:

SQLQuery query = session.createSQLQuery("select * from customer");
List<Object[]> list = query.list();
SQLQuery query = session.createSQLQuery("select * from customer");
query.addEntity(Customer.class);
List<Customer> list = query.list();

Hibernate配置和核心API

核心配置文件hibernate.cfg.xml

核心配置有兩種方式進行配置:

  1. 屬性文件的配置:
    hibernate.properties 格式:key=value
    hibernate.connection.driver_class=com.mysql.jdbc.Driver
    注意:沒有辦法在核心配置文件中加載映射文件.(必須手動編碼的方式進行加載.)
  2. XML格式文件配置:
    hibernate.cfg.xml 格式:<property name="hibernate.connection.username">root</property>

在核心配置中:

  1. 必須的配置:
    連接數據庫4個基本參數:
    hibernate.connection.driver_class 連接數據庫驅動程序
    hibernate.connection.url 連接數據庫URL
    hibernate.connection.username 數據庫用戶名
    hibernate.connection.password 數據庫密碼
    Hibernate的方言:
    hibernate.dialect 操作數據庫方言
  2. 可選的配置:
    hibernate.show_sql true 在控制臺上輸出SQL語句
    hibernate.format_sql true 格式化控制臺輸出的SQL語句
    hibernate.connection.autocommit true 事務是否自動提交
    hibernate.hbm2ddl.auto create/create-drop/update/validate 4個選項
  • create:每次執行的時候,創建一個新的表.(如果以前有該表,將該表刪除重新創建.) 一般測試的時候的使用.
  • create-drop:每次執行的時候,創建一個新的表,程序執行結束后將這個表,刪除掉了. 一般測試的時候使用.
  • update:如果數據庫中沒有表,創建一個新的表,如果有了,直接使用這個表.可以更新表的結構.
  • validate:會使用原有的表.完成校驗.校驗映射文件與表中配置的字段是否一致.不一致報錯.

3.映射的配置:
在核心配置文件中加載映射文件:
<mapping resource="com/java/hibernate3/demo1/Customer.hbm.xml" />

映射文件的配置Customer.hbm.xml

ORM:對象和關系映射,配置Java對象與數據庫表的映射。

  1. 配置類與表的映射:
    name:類的全路徑,table:表的名稱:(可以省略的.使用類的名稱作為表名.)
    <class name="cn.itcast.hibernate3.demo1.Order" table=”orders”>

  2. 配置普通屬性與字段映射:
    <property name="name" column="name" type="string" length=”20”/>
    type:三種寫法

  • Java類型:java.lang.String
  • Hibernate類型:string
  • SQL類型:不能直接使用type屬性,需要子標簽
    <column><column name="name" sql-type="varchar(20)"/>
  1. 配置唯一標識與主鍵映射:
    一個表中只有一個主鍵的形式:
    <id name=”id” column=”id”></id>
    一個表對應多個主鍵形式:(復合主鍵:)---了解.
    <composite-id></composite-id>

Hibernate的核心API

Configuration:負責管理 Hibernate 的配置信息
  1. 加載核心配置文件:
    核心配置有兩種:
  • hibernate.properties:
    加載:Configuration configuration = new Configuration();
  • hibernate.cfg.xml:
    加載:Configuration configuration = new Configuration().configure();
  1. properties手動加載映射文件:
  • 第一種寫法:
    configuration.addResource("cn/itcast/hibernate3/demo1/Customer.hbm.xml");
  • 第二種寫法:(要求:映射文件名稱要規范,類與映射在同一個包下)
    configuration.addClass(Customer.class);
SessionFactory:Session工廠

Configuration對象根據當前的配置信息生成 SessionFactory對象
SessionFactory對象中保存了當前的數據庫配置信息和所有映射關系以及預定義的SQL語句
SessionFactory對象是線程安全的
SessionFactory還負責維護Hibernate的二級緩存
SessionFactory對象根據數據庫信息,維護連接池,創建Session(相當于Connection)對象.
抽取工具類

public class HibernateUtils {
    private static Configuration configuration;
    private static SessionFactory sessionFactory;
    static{
        configuration = new Configuration().configure();
        sessionFactory = configuration.buildSessionFactory();
    }
    public static Session openSession(){
        return sessionFactory.openSession();
    }
    public static void main(String[] args) {
        openSession();
    }
}

在Hibernate中使用c3p0連接池:

  • 引入c3p0的jar包
  • 在核心配置hibernate.cfg.xml中添加一段配置:
<!-- C3P0連接池設定-->
<!-- 使用c3po連接池  配置連接池提供的供應商-->
<propertyname="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在連接池中可用的數據庫連接的最少數目 -->
<property name="c3p0.min_size">5</property>
<!--在連接池中所有數據庫連接的最大數目  -->
<property name="c3p0.max_size">20</property>
<!--設定數據庫連接的過期時間,以秒為單位,
如果連接池中的某個數據庫連接處于空閑狀態的時間超過了timeout時間,就會從連接池中清除 -->
<property name="c3p0.timeout">120</property>
 <!--每3000秒檢查所有連接池中的空閑連接 以秒為單位-->
<property name="c3p0.idle_test_period">3000</property>
Session:相當于JDBC的Connection

Session 是應用程序與數據庫之間交互操作的一個單線程對象,是 Hibernate 運作的中心
Session是線程不安全的
所有持久化對象必須在 session 的管理下才可以進行持久化操作
Session 對象有一個一級緩存,顯式執行 flush 之前,所有的持久化操作的數據都緩存在 session 對象處
持久化類與 Session 關聯起來后就具有了持久化的能力
Session維護了Hiberante一級緩存.

save()/persist()    :添加.
update()            :修改
saveOrUpdate()  :增加和修改對象
delete()            :刪除對象
get()/load()        :根據主鍵查詢
createQuery()       :創建一個Query接口,編寫HQL語句
createSQLQuery()    :創建一個SQLQuery接口,編寫SQL語句數據庫操作對象
createCriteria()    :返回一個Criteria接口.條件查詢
Transaction

獲得:Transaction tx = session.beginTransaction();
常用方法:
commit() :提交相關聯的session實例
rollback() :撤銷事務操作
wasCommitted():檢查事務是否提交
如果沒有開啟事務,那么每個Session的操作,都相當于一個獨立的事務

Query

Query代表面向對象的一個Hibernate查詢操作
session.createQuery 接受一個HQL語句
HQL是Hibernate Query Language縮寫, 語法很像SQL語法,但是完全面向對象的

Criteria:條件查詢

Hibernate中的持久化類

持久化類=實體類 + 映射文件.

持久化類是有編寫規范

  • 提供一個無參數 public訪問控制符的構造器 :用到反射.
  • 提供一個標識屬性,映射數據表主鍵字段 :
  • java區分兩個對象是否是同一個:使用地址.
  • 數據庫區分兩條記錄是否一致:使用主鍵.
  • Hibernate中區分持久化對象是否是同一個,根據唯一標識:
  • 所有屬性提供public訪問控制符的 set get 方法 :框架中存值和取值的時候使用.
  • 標識屬性應盡量使用基本數據類型的包裝類型(默認值為null而不是0)
  • 持久化類盡量不要使用final進行修飾:用final修飾的類是不能被繼承.無法生成代理對象.(延遲加載的時候返回代理對象.延遲加載就失效.)

建表的時候:

  1. 自然主鍵:
    創建一個人員表.人員表中某條記錄唯一確定.人都有身份證號.我們可以使用身份證號作為主鍵.(身份證號本身就是人員的一個屬性.作為主鍵.)
  2. 代理主鍵:
    創建一個人員表.人員表中某條記錄唯一確定.但是沒有使用身份證號作為主鍵,新建字段(用新建的字段作為主鍵.只是一個標識作用.)

盡量要Hibernate自己去維護主鍵:
主鍵的生成策略:

  • increment:自動增長.適合 short int long...不是使用數據庫的自動增長機制.使用Hibernate框架提供的自動增長方式.
  • select max(id) from 表; 在最大值的基礎上+1.(多線程的問題.)在集群下不要使用
  • identity :自動增長.適合 short int long...采用數據庫的自動增長機制.不適合于Oracle數據庫.
  • sequence :序列.適用于 short int long ... 應用在Oracle上 .
  • uuid :適用于字符串類型的主鍵.采用隨機的字符串作為主鍵.
  • native :本地策略.底層數據庫不同.自動選擇適用identity 還是 sequence.
  • assigned :Hibernate框架不維護主鍵,主鍵由程序自動生成.
  • foreign :主鍵的外來的.(應用在多表一對一的關系.)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文包括: 1、CRM 項目的整體介紹 2、Hibernate 框架概述 3、Hibernate 快速入門 4、H...
    廖少少閱讀 3,485評論 9 66
  • Hibernate: 一個持久化框架 一個ORM框架 加載:根據特定的OID,把一個對象從數據庫加載到內存中OID...
    JHMichael閱讀 2,000評論 0 27
  • 本文包括:1、Hibernate的持久化類2、Hibernate 持久化對象的三個狀態(難點)3、Hibernat...
    廖少少閱讀 1,495評論 0 13
  • 本文中我們介紹并比較兩種最流行的開源持久框架:iBATIS和Hibernate,我們還會討論到Java Persi...
    大同若魚閱讀 4,346評論 4 27
  • Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與數據庫...
    蘭緣小妖閱讀 1,227評論 1 18