Hibernate(二)

来源:http://www.cnblogs.com/xiangkejin/archive/2016/10/20/5979873.html
-Advertisement-
Play Games

首先我們進一步理解什麼是對象關係映射模型? 它將對資料庫中數據的處理轉化為對對象的處理。如下圖所示: 入門簡單實例: hiberante 可以用在 j2se 項目,也可以用在 j2ee (web項目中),而struts是web框架,所以用在 web項目。 hibernate開發方式的主要兩種方式: ...


首先我們進一步理解什麼是對象關係映射模型

它將對資料庫中數據的處理轉化為對對象的處理。如下圖所示:

入門簡單實例:

hiberante 可以用在 j2se 項目,也可以用在 j2ee (web項目中),而strutsweb框架,所以用在 web項目。

hibernate開發方式的主要兩種方式:

1.Domain object -> mapping->db。(更加符合面向對象的編程方式,從對象入手來通過映射生成表)

2.DB開始,用工具生成mappingDomain object(往往更加習慣從表的構建入手,使用更多)

我們首先用從對象映射出表,到後面再使用第二種。

步驟:

1.創建一個工程

2.引入Hibernate相關包,引入資料庫驅動包(對於sql server資料庫需要三個包msbase.jar mssqlserver.jar msutil.jar)。

除了hibernate.jar核心包還需要其他相關的庫。

3.配置hibernate.cfg.xml文件

4.開發domain對象和對象關係映射文件

5.測試

domain對象

//要序列化,唯一標識對象
public class Employee implements java.io.Serializable{

    private static final long serialVersionUID = 1L;
    private Integer id;
    private String name;
    private String email;
    private java.util.Date hiredate;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public java.util.Date getHiredate() {
        return hiredate;
    }
    public void setHiredate(java.util.Date hiredate) {
        this.hiredate = hiredate;
    }
    
}

註意對象實現了序列化,序列化就是講對象的位元組序列持久化,也能唯一標識一個對象。對於序列化的知識可參考博主孤傲倉狼的文章:

Java基礎學習總結——Java對象的序列化和反序列化

對象關係映射文件

作用是用於指定 domain對象和表的映射關係.,該文件的取名有規範:domain對象.hbm.xml,一般我們放在 domain對象同一個文件夾下(包下)

對主鍵增長策略比較講究,對於不同的資料庫,有相應的方式。

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xidian.domain">
    <class name="Employee" table="employee">
    <id name="id" column="id" type="java.lang.Integer">
    <!-- id設置自增長 -->
     <generator class="identity"></generator>     
    </id>
    <!-- 對其它屬性還有配置 -->
    <property name="name" type="java.lang.String">
    <column name="name" length="500" not-null="false" />   //length的預設長度是255
    </property>
    <property name="email" type="java.lang.String" >
    <column name="email" not-null="false"/>
    </property>
    <property name="hiredate" type="java.util.Date">
    <column name="hiredate" not-null="false" />
    </property>
    </class>
    
</hibernate-mapping>

hibernate.cfg.xml文件(預設是放在src文件夾下麵,也可放在子文件夾下麵,不過就要使用重載函數載入讀取) 

該文件用於配置 連接的資料庫的類型driver用戶名密碼 ,url ....同時管理對象關係映射文件 ,該文件的名稱我們一般不修改.

<?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>
    <!-- hibernate 設計者,給我們提供了一寫常用的配置 -->
    <!-- 配置使用的driver -->
    <property name="connection.driver_class">com.microsoft.jdbc.sqlserver.SQLServerDriver
        </property>
    <property name="connection.username">sa</property>
    <property name="connection.password">dba</property>
    <property name="connection.url">jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test</property>
    <!-- 配置dialect方言,明確告訴hibernate連接是哪種資料庫 -->
    <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
    <!-- 顯示出sql -->
    <property name="show_sql">true</property>
    <property name="format_sql">true</property>
    <property name="current_session_context_class">thread</property>
    <!-- 讓hibernate給我們自動創建表 create :如果沒有該表則創建.如果有表則刪除後再創建
     update:如果沒有表則創建新表,如果有表則看表結構有沒有變化 ,有變化則會創建新表    -->
    <property name="hbm2ddl.auto">update</property>
    <!-- 指定管理的對象映射文件 -->
    <mapping resource="com/xidian/domain/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

測試:

package com.hsp.view;
import com.hsp.util.*;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.*;

import com.hsp.domain.Employee;
public class TestMain {

    public static void main(String[] args) {
        //查詢[load]->hql語句(hibernate query language)
    }


public static void addEmployee() {
        //我們使用hibernate完成crud操作[這裡我們只見對象,不見表]
        //現在我們不是用service ,直接測試.
        //1.創建Configuration,該對象用於讀取hibernate.cfg.xml,並完成初始化
        Configuration configuration=new Configuration().configure();
        //2.創建SessoinFactory[這是一個會話工廠,是一個重量級的對象(非常費記憶體,要只創建一個)]
        SessionFactory sessionFactory=configuration.buildSessionFactory();
        //3.創建Sessoin 相當於jdbc Connection[ servelt HttpSession ,不是 jsp session]
        Session session=sessionFactory.openSession();
        //4.對hiberate而言,要求程式員,在進行 增加,刪除,修改的時候使用事務提交,查詢可以不用事務
        Transaction transaction = session.beginTransaction();
        //添加一個雇員
        Employee employee=new Employee();
        employee.setName("xkj");
        employee.setEmail("[email protected]");
        employee.setHiredate(new Date());
        //insert .............
        //保存
        session.save(employee);//save employee就是持久化該對象 (把對象保存到了資料庫中稱為一條記錄)
        //==>insert into ....[被hiberante封裝]
        //提交
        transaction.commit();
        session.close();
    }


    public static void delEmp() {
        //刪除
        //獲取一個session
        Session session=MySessionFactory.getSessionFactory().openSession();
        Transaction ts=session.beginTransaction();
        //刪除1.先獲取該雇員,然後刪除
        Employee emp=(Employee) session.load(Employee.class, 3);
        session.delete(emp);
        ts.commit();
        session.close();
    }


Hibernate執行update語句會先查詢,如果查詢到資料庫中的數據和對象數據不一致則會指定update語句,如果查詢到沒有更改則只做查詢,沒有update語句
    public static void updateEmp() {
        // TODO Auto-generated method stub
        //修改用戶
        //獲取一個會話
        Session session=MySessionFactory.getSessionFactory().openSession();
        
        /*Transaction ts=session.beginTransaction();
        //修改用戶1. 獲取要修改的用戶,2.修改
        //load是通過主鍵屬性,獲取該對象實例.<--->表的記錄對應
        Employee emp=(Employee) session.load(Employee.class, 3);
        emp.setName("xkj8");//update...
        emp.setEmail("[email protected]");
        ts.commit();
        session.close();*/
        
        //如何在hibernate中回滾事務
        Transaction ts=null;
        try {
            ts=session.beginTransaction();
            Employee emp=(Employee) session.load(Employee.class, 1);
            emp.setName("xkj");
            emp.setEmail("[email protected]");
            int i=9/0;
            ts.commit();
            
        } catch (Exception e) {
            if(ts!=null){
                ts.rollback();
            }
            throw new RuntimeException(e.getMessage());
        }finally{
            if(session!=null&session.isOpen()){
            session.close();
            }
        }
        
    }

需要強調的是在用hibernate進行添加、修改、刪除的操作的時候一定要進行事務提交,否則不提交操作請求。使用查詢的時候是不必用事務的。

由圖可以看出,我在前四項紀錄,都用了事務提交,在第五項的時候沒有使用事務,沒有成功添加紀錄,下一次事務添加則直接從第六項開始。後面第九項也一樣。

這表明雖然沒有使用事務提交不能成功對紀錄進行操作,但是主鍵序列還是一直在變化

 

在使用hibernate開發項目的時候一定要保證只有一個sessionFactory,一個資料庫對應一個SessionFactory對象,我們用單例模式創建sessionFactory

final public class MySessionFactory {
    
    private static SessionFactory sessionFactory=null;
    
    private MySessionFactory(){
        
    }
    static {
        sessionFactory=new Configuration().configure().buildSessionFactory();
        
    }
    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }
    
}

運行測試代碼後在資料庫中可看見生成了employee表。

    

 

現在我們體驗一下hibernate切換資料庫的優勢。切換資料庫之後,只需要更改配置,而不需要修改主程式的業務代碼。

切換mysql資料庫

  1. 首先我們把  hibernate.cfg.xml文件重新配置.
<?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>
    <!-- hibernate 設計者,給我們提供了一寫常用的配置 -->
    <!-- 配置使用的driver -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>
    <property name="connection.url">jdbc:mysql:/localhost:3306/test</property>
    <!-- 配置dialect方言,明確告訴hibernate連接是哪種資料庫 -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- 顯示出對於sql -->
    <property name="show_sql">true</property>
    <!-- 讓hibernate給我們自動創建表 create :如果沒有該表則創建. -->
    <property name="hbm2ddl.auto">create</property>
    <!-- 指定管理的對象映射文件 -->
    <mapping resource="com/hsp/domain/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

 2.對對象映射文件,做了相應的修改.

<!-- 對主鍵生成策略我們做了修改 -->

<id name="id" column="id" type="java.lang.Integer">

<generator class="increment"></generator>

</id>

 

切換oracle資料庫

<?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>
    <!-- hibernate 設計者,給我們提供了常用的配置在文檔project--etc--hibernate.property  中可以查找到配置信息-->
    <!-- 配置使用的driver -->
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="connection.username">scott</property>
    <property name="connection.password">tiger</property>
    <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orclhsp</property>
    <!-- 配置dialect方言,明確告訴hibernate連接是哪種資料庫 -->
    <property name="dialect">org.hibernate.dialect.OracleDialect</property>
    <!-- 顯示出對於sql -->
    <property name="show_sql">true</property>
    <!-- 指定管理的對象映射文件 -->
    <mapping resource="com/hsp/domain/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>

2.對對象映射文件,做了相應的修改.

<!-- id元素用於指定主鍵屬性 -->

<id name="id" column="id" type="java.lang.Integer">

<!-- 該元素用於指定主鍵值生成策略hilo native increment sequence uuid -->

<generator class="sequence">

<param name="sequence">emp_seq</param>

</generator>

</id>


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 英文文檔: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) ...
  • 測試環境:php5.3.29 unix時間戳(從Unix 紀元(January 1 1970 00:00:00 GMT)到給定時間的秒數。)。以下簡稱時間戳。 返回某一時間的時間戳。 time(); //獲取當前本機時間的時間戳。 mktime(時,分,秒,月,日,年); //從右向左可以省略,省略 ...
  • Go的 switch 非常靈活,表達式不必是常量或整數,執行的過程從上至下,直到找到匹配項,不要break; switch 後面的表達式甚至不是必需的 利子: RadioButton為單選按鈕,可以分組, radiobuttongroup和radiobuttongroupbox ...
  • 通用精準化推薦平臺 平臺結構 以下為推薦流程可視化系統設計圖 以下為推薦結果可追溯系統設計圖 通過推薦流程可視化系統以及推薦結果可追溯系統,我們可以解決原有推薦系統架構的問題 推薦流程可視化系統 --------------------------... ...
  • 這兩個星期開始系統地學習設計模式相關的知識,對每一個原則或者設計模式主要從下麵幾點分析學習: - 定義:簡單地描述其作用 - 解決問題:說明該原則或設計模式解決什麼限制條件下的問題。 - 結構圖:繪製相關例子的UML機構圖。 - 代碼示例:通過一個例子解釋該模式的實現方法。 - 優缺點:該模式的局限... ...
  • 自從在園子里,發表了兩篇如何基於Netty構建RPC伺服器的文章:談談如何使用Netty開發實現高性能的RPC伺服器、Netty實現高性能RPC伺服器優化篇之消息序列化 之後,收到了很多同行、園友們熱情的反饋和若幹個優化建議,於是利用閑暇時間,打算對原來NettyRPC中不合理的模塊進行重構,並且增 ...
  • 先貼代碼有空來寫內容。 備忘錄1 測試類 備忘錄2 測試類 memento3 ...
  • Django 最開源地方就是可以使用強大第三方插件1,Django預設沒有提供對象(Object)級別的許可權控制,我們可以通過該Django Guardian 擴展來幫助Django實現對象級別的許可權控制。 2,Python social auth 可以進行社交賬號認證/註冊機制支持如Google、 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...