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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...