當前位置:首頁 » 操作系統 » hibernate動態資料庫

hibernate動態資料庫

發布時間: 2023-07-10 13:16:59

㈠ Hibernate如何動態鏈接資料庫

一.導包 mysql
二.在默認src下創建hibernate.cfg.xml
1.創建xml文件,命名為hibernate.cfg.xml
2.添加約束
(在org.hibernate/hibernate-configuration-3.0.dtd中)
1 <!DOCTYPE hibernate-configuration PUBLIC2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"3 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.url">jdbc:mysql://localhost:3306/houserentsys</property> <!-- houserentsys是資料庫名稱 -->

<property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="connection.password">123456</property>
<property name="show_sql">true</property> <property name="format_sql">false</property> <!-- 設置為false就會不換行 --> <property name="hbm2ddl.auto">update</property> <!-- 進行操作時不會刪除重建-->

<!--hbm2ddl.auto屬性:

create:表示啟動的時候先drop,再create
c
reate-drop: 也表示創建,只不過再系統關閉前執行一下drop

update: 這個操作啟動的時候會去檢查schema是否一致,如果不一致會做scheme更新

validate: 啟動時驗證現有schema與你配置的hibernate是否一致,如果不一致就拋出異常,並不做更新
-->
<mapping resource="e/tsinghua/entity/mapping/district.xml"/> <mapping resource="e/tsinghua/entity/mapping/street.xml"/>
</session-factory></hibernate-configuration>

hbm2ddl.auto屬性:
create:表示啟動的時候先drop,再create
create-drop: 也表示創建,只不過再系統關閉前執行一下drop
update: 這個操作啟動的時候會去檢查schema是否一致,如果不一致會做scheme更新
validate: 啟動時驗證現有schema與你配置的hibernate是否一致,如果不一致就拋出異常,並不做更新
三.實體 實現序列化介面 封裝屬性和構造方法 實體.xml 位置隨意
(在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.cfg.xml 添加 映射文件的引用
<mapping resource="e.tsinghua.entity.mapping.district"/>
七個步驟(在新建的執行文件Test.java中)
//1.載入配置文件
Configuration cfg=new Configuration().configure();
//2.獲得sessionfactory
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
SessionFactory sf=cfg.buildSessionFactory(serviceRegistry);
//3.創建session
Session session=sf.openSession();
//4.創建事務
Transaction tx=session.beginTransaction();
//5.操作
District dis=new District(100,"海淀區");
session.save(dis);
//6.提交 回滾
tx.commit();//tx.rollback();
//7.釋放資源

㈡ hibernate可以跨資料庫嗎

首先來說,跨資料庫肯定是可以的!
通常有兩個方法,第一個是笨辦法,就是在配置項里定義兩個數據源,並且這兩個數據源分屬於兩個SessionFaction對象。並且在代碼中也有創建兩個對象分別對應兩個資料庫,這樣做比較麻煩,代碼會很繁瑣,並且執行效率不一定高。

第二個辦法是使用spring開源框架里提供的動態數據源,通過動態的載入,將兩個數據源信息載入到一個SessionnFacgtion對象中。方法一裡面提到的缺點在這里都能夠很好的解決。

大概步驟如下:
1.org.springframework.beans.factory.support.DefaultListableBeanF

actory獲得bean工廠,可以添加銷毀數據源;

2.org.springframework.beans.factory.support.BeanDefinitionBuilder動態創建bean,然後通過
DefaultListableBeanFactory.registerBeanDefinition(dsInfo.getId(), beanDefinitionBuilder.getBeanDefinition()); 注冊數據源事務

3.銷毀數據源
beanFactory.destroySingleton(tsId);
beanFactory.removeBeanDefinition(tsId);

㈢ hibernate連寫資料庫時,如何設置

Hibernate與各種資料庫連接的配置

1. Oracle連接配置
Oracler資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:dbname</property>
<!--資料庫用戶名-->
<property name="connection.username">test</property>
<!--資料庫密碼-->
<property name="connection.password">test</property>
上例使用的驅動類為:oracle.jdbc.driver.OracleDriver,開發人員需要將相關的jar包(ojdbc14.jar)加入到classpath中。

2. MySql連接配置
MySql資料庫的hibernate連接設置,在hibernate.cfg.xml文件中
<hibernate-configuration>
<session-factory>
<!--各屬性的配置-->
<!—為true表示將Hibernate發送給資料庫的sql顯示出來 -->
<property name="show_sql">true</property>
<!-- SQL方言,這邊設定的是MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!--一次讀的資料庫記錄數 -->
<property name="jdbc.fetch_size">50</property>
<!--設定對資料庫進行批量刪除 -->
<property name="jdbc.batch_size">30</property>
<!--驅動程序-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:mysql://localhost/dbname?
characterEncoding=gb2312</property>
<!--資料庫用戶名-->
<property name="connection.username">root</property>
<!--資料庫密碼-->
<property name="connection.password">root</property>
<!—映射文件 -->
<mapping resource="com/amigo/pojo/User.hbm.xml"/>
<mapping resource="com/amigo/pojo/Org.hbm.xml"/>
</session-factory>
</hibernate-configuration>
上面使用的驅動類是com.mysql.jdbc.Driver.需要將MySql的連接器jar包(eg. mysql-connector-java-Dbname為資料庫名字5.0.4-bin.jar)加入到classpath中。

3. Sql Server連接配置
Sql Server資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<!-- JDBC URL -->
<property
name="connection.url">jdbc:jtds:sqlserver://localhost:1433;DatabaseName=dbname</property>
<!--資料庫用戶名-->
<property name="connection.username">sa</property>
<!--資料庫密碼-->
<property name="connection.password"></property>
上例的驅動類使用的是jtds的驅動類,因此讀者需要將jtds的jar包(eg. jtds-1.2.jar)加入到classpath中

4. DB2連接配置
DB2資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class"> com.ibm.db2.jdbc.app.DB2Driver</property>
<!-- JDBC URL -->
<property
name="connection.url"> jdbc:db2://localhost:5000/sample </property> //sample為資料庫名
<!--資料庫用戶名-->
<property name="connection.username">admin</property>
<!--資料庫密碼-->
<property name="connection.password"></property>
上例使用的驅動類為:com.ibm.db2.jdbc.app.DB2Driver,開發人員需要將相關的jar包(db2jcc.jar)加入到classpath中。

5.sybase連接配置
sybase資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class">com.sybase.jdbc.SybDrive</property>
<!-- JDBC URL -->
<property
name="connection.url"> jdbc:sybase:Tds:localhost:5007/myDB</property> ;//myDB為資料庫名
<!--資料庫用戶名-->
<property name="connection.username">userid</property>
<!--資料庫密碼-->
<property name="connection.password">user_password</property>
上例使用的驅動類為:com.sybase.jdbc.SybDrive,開發人員需要將相關的jar包(jconn3.jar)加入到classpath中。

6. informix連接配置
informix資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class">com.informix.jdbc.IfxDrive</property>
<!-- JDBC URL -->
<property
name="connection.url">jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver </property> ;//myDB為資料庫名
<!--資料庫用戶名-->
<property name="connection.username">testuser</property>
<!--資料庫密碼-->
<property name="connection.password">testpassword</property>
上例使用的驅動類為:com.informix.jdbc.IfxDrive,開發人員需要將相關的jar包(ifxjdbc.jar)加入到classpath中。

7.PostgreSQL連接配置
PostpreSQL資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class">org.postgresql.Driver</property>
<!-- JDBC URL -->
<property
name="connection.url">jdbc:postgresql://localhost/myDB</property>;//myDB為資料庫名
<!--資料庫用戶名-->
<property name="connection.username">myuser</property>
<!--資料庫密碼-->
<property name="connection.password">mypassword</property>
上例使用的驅動類為:com.informix.jdbc.IfxDrive,開發人員需要將相關的jar包(postgresql-8.1-405.jdbc3)加入到classpath中。

8.access連接配置
access資料庫的hibernate在配置文件中配置。
連接部分
<!--驅動程序-->
<property name="connection.driver_class">sun.jdbc.odbc.JdbcOdbcDriver</property>
<!-- JDBC URL -->
<property
name="connection.url">jdbc:odbc:Driver={MicroSoft..Access..Driver(*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb")</property> ;//myDB為資料庫名
<!--資料庫用戶名-->
<property name="connection.username">myuser</property>
<!--資料庫密碼-->
<property name="connection.password">mypassword</property>

㈣ Hibernate緩存何時使用和如何使用

關於hibernate緩存的問題

基本的緩存原理

Hibernate緩存分為二級

第一級存放於session中稱為一級緩存 默認帶有且不能卸載

第二級是由sessionFactory控制的進程級緩存 是全局共享的緩存 凡是會調用二級緩存的查詢方法 都會從中受益 只有經正確的配置後二級緩存才會發揮作用 同時在進行條件查詢時必須使用相應的方法才能從緩存中獲取數據 比如erate()方法 load get方法等 必須注意的是session find方法永遠是從資料庫中獲取數據 不會從二級緩存中獲取數據 即便其中有其所需要的數據也是如此

查詢時使用緩存的實現過程為 首先查詢一級緩存中是否具有需要的數據 如果沒有 查詢二級緩存 如果二級緩存中也沒有 此時再執行查詢資料庫的工作 要注意的是 此 種方式的查詢速度是依次降低的

存在的問題

一級緩存的問題以及使用二級緩存的原因

因為Session的生命期往往很短 存在於Session內部的第一級最快緩存的生命期當然也很短 所以第一級緩存的命中率是很低的 其對系統性能的改善也是很有限的 當然 這個Session內部緩存的主要作用是保持Session內部數據狀態同步 並非是hibernate為了大幅提高系統性能所提供的

為了提高使用hibernate的性能 除了常規的一些需要注意的方法比如

使用延遲載入 迫切外連接 查詢過濾等以外 還需要配置hibernate的二級緩存 其對系統整體性能的改善往往具有立竿見影的效果!

(經過自己以前作項目的經驗 一般會有 ~ 倍的性能提高)

N+ 次查詢的問題

什麼時候會遇到 +N的問題?

前提 Hibernate默認表與表的關聯方法是fetch= select 不是fetch= join 這都是為了懶載入而准備的

)一對多(<set><list>) 在 的這方 通過 條sql查找得到了 個對象 由於關聯的存在 那麼又需要將這個對象關聯的集合取出 所以合集數量是n還要發出n條sql 於是本來的 條sql查詢變成了 +n條

)多對一<many to one> 在多的這方 通過 條sql查詢得到了n個對象 由於關聯的存在 也會將這n個對象對應的 方的對象取出 於是本來的 條sql查詢變成了 +n條

)iterator 查詢時 一定先去緩存中找( 條sql查集合 只查出ID) 在沒命中時 會再按ID到庫中逐一查找 產生 +n條SQL

怎麼解決 +N 問題?

)lazy=true hibernate 開始已經默認是lazy=true了 lazy=true時不會立刻查詢關聯對象 只有當需要關聯對象(訪問其屬性 非id欄位)時才會發生查詢動作

)使用二級緩存 二級緩存的應用將不怕 +N 問題 因為即使第一次查詢很慢(未命中) 以後查詢直接緩存命中也是很快的 剛好又利用了 +N

) 當然你也可以設定fetch= join 一次關聯表全查出來 但失去了懶載入的特性

執行條件查詢時 iterate()方法具有著名的 n+ 次查詢的問題 也就是說在第一次查詢時iterate方法會執行滿足條件的查詢結果數再加一次(n+ )的查詢 但是此問題只存在於第一次查詢時 在後面執行相同查詢時性能會得到極大的改善 此方法適合於查詢數據量較大的業務數據

但是注意 當數據量特別大時(比如流水線數據等)需要針對此持久化對象配置其具體的緩存策略 比如設置其存在於緩存中的最大記錄數 緩存存在的時間等參數 以避免系統將大量的數據同時裝載入內存中引起內存資源的迅速耗盡 反而降低系統的性能!!!

使用hibernate二級緩存的其他注意事項

關於數據的有效性

另外 hibernate會自行維護二級緩存中的數據 以保證緩存中的數據和資料庫中的真實數據的一致性!無論何時 當你調用save() update()或 saveOrUpdate()方法傳遞一個對象時 或使用load() get() list() iterate() 或scroll()方法獲得一個對象時 該對象都將被加入到Session的內部緩存中 當隨後flush()方法被調用時 對象的狀態會和資料庫取得同步

也就是說刪除 更新 增加數據的時候 同時更新緩存 當然這也包括二級緩存!

只要是調用hibernate API執行資料庫相關的工作 hibernate都會為你自動保證 緩存數據的有效性!!

但是 如果你使用了JDBC繞過hibernate直接執行對資料庫的操作 此時 Hibernate不會/也不可能自行感知到資料庫被進行的變化改動 也就不能再保證緩存中數據的有效性!!

這也是所有的ORM產品共同具有的問題 幸運的是 Hibernate為我們暴露了Cache的清除方法 這給我們提供了一個手動保證數據有效性的機會!!

一級緩存 二級緩存都有相應的清除方法

其中二級緩存提供的清除方法為

按對象class清空緩存

按對象class和對象的主鍵id清空緩存

清空對象的集合中的緩存數據等

適合使用的情況

並非所有的情況都適合於使用二級緩存 需要根據具體情況來決定 同時可以針對某一個持久化對象配置其具體的緩存策略

適合於使用二級緩存的情況

數據不會被第三方修改

一般情況下 會被hibernate以外修改的數據最好不要配置二級緩存 以免引起不一致的數據 但是如果此數據因為性能的原因需要被緩存 同時又有可能被第 方比如SQL修改 也可以為其配置二級緩存 只是此時需要在sql執行修改後手動調用cache的清除方法 以保證數據的一致性

數據大小在可接收范圍之內

如果數據表數據量特別巨大 此時不適合於二級緩存 原因是緩存的數據量過大可能會引起內存資源緊張 反而降低性能 如果數據表數據量特別巨大 但是經常使用的往往只是較新的那部分數據 此時 也可為其配置二級緩存 但是必須單獨配置其持久化類的緩存策略 比如最大緩存數 緩存過期時間等 將這些參數降低至一個合理的范圍(太高會引起內存資源緊張 太低了緩存的意義不大)

數據更新頻率低

對於數據更新頻率過高的數據 頻繁同步緩存中數據的代價可能和 查詢緩存中的數據從中獲得的好處相當 壞處益處相抵消 此時緩存的意義也不大

非關鍵數據(不是財務數據等)

財務數據等是非常重要的數據 絕對不允許出現或使用無效的數據 所以此時為了安全起見最好不要使用二級緩存

因為此時 正確性 的重要性遠遠大於 高性能 的重要性

目前系統中使用hibernate緩存的建議

目前情況

一般系統中有三種情況會繞開hibernate執行資料庫操作

多個應用系統同時訪問一個資料庫

此種情況使用hibernate二級緩存會不可避免的造成數據不一致的問題 此時要進行詳細的設計 比如在設計上避免對同一數據表的同時的寫入操作 使用資料庫各種級別的鎖定機制等

動態表相關

所謂 動態表 是指在系統運行時根據用戶的操作系統自動建立的數據表

比如 自定義表單 等屬於用戶自定義擴展開發性質的功能模塊 因為此時數據表是運行時建立的 所以不能進行hibernate的映射 因此對它的操作只能是繞開hibernate的直接資料庫JDBC操作

如果此時動態表中的數據沒有設計緩存 就不存在數據不一致的問題

如果此時自行設計了緩存機制 則調用自己的緩存同步方法即可

使用sql對hibernate持久化對象表進行批量刪除時

此時執行批量刪除後 緩存中會存在已被刪除的數據

分析

當執行了第 條(sql批量刪除)後 後續的查詢只可能是以下三種方式

a session find()方法

根據前面的總結 find方法不會查詢二級緩存的數據 而是直接查詢資料庫

所以不存在數據有效性的問題

b 調用iterate方法執行條件查詢時

根據iterate查詢方法的執行方式 其每次都會到資料庫中查詢滿足條件的id值 然後再根據此id 到緩存中獲取數據 當緩存中沒有此id的數據才會執行資料庫查詢

如果此記錄已被sql直接刪除 則iterate在執行id查詢時不會將此id查詢出來 所以 即便緩存中有此條記錄也不會被客戶獲得 也就不存在不一致的情況 (此情況經過測試驗證)

c 用get或load方法按id執行查詢

客觀上此時會查詢得到已過期的數據 但是又因為系統中執行sql批量刪除一般是針對中間關聯數據表 對於中間關聯表的查詢一般都是採用條件查詢 按id來查詢某一條關聯關系的幾率很低 所以此問題也不存在!

如果某個值對象確實需要按id查詢一條關聯關系 同時又因為數據量大使用 了sql執行批量刪除 當滿足此兩個條件時 為了保證按id 的查詢得到正確的結果 可以使用手動清楚二級緩存中此對象的數據的方法!!(此種情況出現的可能性較小)

建 議

建議不要使用sql直接執行數據持久化對象的數據的更新 但是可以執行 批量刪除 (系統中需要批量更新的地方也較少)

如果必須使用sql執行數據的更新 必須清空此對象的緩存數據 調用

SessionFactory evict(class)

SessionFactory evict(class id)等方法

在批量刪除數據量不大的時候可以直接採用hibernate的批量刪除 這樣就不存在繞開hibernate執行sql產生的緩存數據一致性的問題

不推薦採用hibernate的批量刪除方法來刪除大批量的記錄數據

原因是hibernate的批量刪除會執行 條查詢語句外加 滿足條件的n條刪除語句 而不是一次執行一條條件刪除語句!!當待刪除的數據很多時會有很大的性能瓶頸!!!如果批量刪除數據量較大 比如超過 條 可以採用JDBC直接刪除 這樣作的好處是只執行一條sql刪除語句 性能會有很大的改善 同時 緩存數據同步的問題 可以採用 hibernate清除二級緩存中的相關數據的方法

調 用

SessionFactory evict(class) ;

SessionFactory evict(class id)等方法

所以說 對於一般的應用系統開發而言(不涉及到集群 分布式數據同步問題等) 因為只在中間關聯表執行批量刪除時調用了sql執行 同時中間關聯表一般是執行條件查詢不太可能執行按id查詢 所以 此時可以直接執行sql刪除 甚至不需要調用緩存的清除方法 這樣做不會導致以後配置了二級緩存引起數據有效性的問題

退一步說 即使以後真的調用了按id查詢中間表對象的方法 也可以通過調用清除緩存的方法來解決

具體的配置方法

根據我了解的很多hibernate的使用者在調用其相應方法時都迷信的相信 hibernate會自行為我們處理性能的問題 或者 hibernate 會自動為我們的所有操作調用緩存 實際的情況是hibernate雖然為我們提供了很好的緩存機制和擴展緩存框架的支持 但是必須經過正確的調用其才有可能發揮作用!!所以造成很多使用hibernate的系統的性能問題 實際上並不是hibernate不行或者不好 而是因為使用者沒有正確的了解其使用方法造成的 相反 如果配置得當hibernate的性能表現會讓你有相當 驚喜的 發現 下面我講解具體的配置方法

ibernate提供了二級緩存的介面

net sf hibernate cache Provider

同時提供了一個默認的 實現net sf hibernate cache HashtableCacheProvider

也可以配置 其他的實現 比如ehcache jbosscache等

具體的配置位置位於hibernate cfg xml文件中

    <propertyname= hibernate cache use_query_cache >true</property><propertyname= hibernate cache provider_class >net sf hibernate cache HashtableCacheProvider</property>

    很多的hibernate使用者在 配置到 這一步 就以為 完事了

    注意 其實光這樣配 根本就沒有使用hibernate的二級緩存 同時因為他們在使用hibernate時大多時候是馬上關閉session 所以 一級緩存也沒有起到任何作用 結果就是沒有使用任何緩存 所有的hibernate操作都是直接操作的資料庫!!性能可以想見

    正確的辦法是除了以上的配置外還應該配置每一個vo對象的具體緩存策略 在影射文件中配置 例如

      <hibernate mapping><classname= sobey *** m model entitySystem vo DataTypeVO table= dcm_datatype ><cacheusage= read write /><idname= id column= TYPEID type= java lang Long ><generatorclass= sequence /></id><propertyname= name column= NAME type= java lang String /><propertyname= dbType column= DBTYPE type= java lang String /></class></hibernate mapping>

      關鍵就是這個<cache usage= read write /> 其有幾個選擇read only read write transactional 等

      然後在執行查詢時 注意了 如果是條件查詢 或者返回所有結果的查詢 此時session find()方法 不會獲取緩存中的數據 只有調用erate()方法時才會調緩存的數據

      同時 get 和 load方法 是都會查詢緩存中的數據

      對於不同的緩存框架具體的配置方法會有不同 但是大體是以上的配置(另外 對於支持事務型 以及支持集群的環境的配置我會爭取在後續的文章中中 發表出來)

lishixin/Article/program/Java/ky/201311/28715

熱點內容
s3哪個配置性價比高 發布:2025-03-17 13:06:09 瀏覽:317
氣體壓縮能量 發布:2025-03-17 13:00:16 瀏覽:75
壓縮油19 發布:2025-03-17 12:25:29 瀏覽:855
linux上網代理 發布:2025-03-17 12:23:56 瀏覽:359
c是高級語言嗎 發布:2025-03-17 12:16:31 瀏覽:523
python泛型 發布:2025-03-17 12:15:01 瀏覽:482
編程貓被盜 發布:2025-03-17 12:02:18 瀏覽:131
海關鎖密碼箱如何設置新密碼 發布:2025-03-17 11:53:50 瀏覽:560
農業卡號的密碼在哪裡改 發布:2025-03-17 11:48:57 瀏覽:966
楊瀾超級訪問 發布:2025-03-17 11:47:17 瀏覽:237