先說下實驗項目環境:
hibernate項目jar包
hibernate-3.2.6.ga.jar
proxool-0.9.0RC3.jar
JDK1.6
Mysql資料庫
項目介紹
主要是通過Hibernate所謂資料庫的持久層,其中用串連池proxool來管理Hibernate的Session。
項目搭建
1.建立hibernateDemo項目
2.添加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> <property name="proxool.pool_alias">proxoolPool</property> <property name="proxool.xml">proxool.xml</property> <property name="connection.provider_class"> org.hibernate.connection.ProxoolConnectionProvider </property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="show_sql">true</property> <property name="format_sql">false</property> </session-factory></hibernate-configuration>
3.添加proxool.xml
<?xml version="1.0" encoding="utf-8"?><something-else-entirely> <proxool> <!-- 串連池名稱 與 hibernate 設定的 proxool.pool_alias 參數要一致 --> <alias>proxoolPool</alias> <!-- proxool只能管理由自己產生的串連 --> <driver-url> jdbc:mysql://127.0.0.1:3306/web3_plus?characterEncoding=UTF-8 </driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root"/> <property name="password" value="12344"/> </driver-properties> <!-- proxool自動偵察各個串連狀態的時間間隔(毫秒), 偵察到閒置串連就馬上回收,逾時的銷毀 --> <house-keeping-sleep-time>120000</house-keeping-sleep-time> <!-- 指因未有空閑串連可以分配而在隊列中等候的最大請求數, 超過這個請求數的使用者串連就不會被接受 --> <maximum-new-connections>20</maximum-new-connections> <!-- 最少保持的空閑串連數 --> <prototype-count>5</prototype-count> <!-- 允許最大串連數,超過了這個串連,再有請求時,就排在隊列中等候 ,最大的等待請求數由maximum-new-connections決定 --> <maximum-connection-count>300</maximum-connection-count> <!-- 最小串連數 --> <minimum-connection-count>10</minimum-connection-count> <!-- 同時最大串連數 --> <simultaneous-build-throttle>30</simultaneous-build-throttle> <!-- 一次產生串連的數量 --> <prototype-count>10</prototype-count> <!-- 串連最大時間活動 預設5分鐘 --> <maximum-active-time>36000000</maximum-active-time> <!-- 串連最大生命時間 預設4小時 --> <maximum-connection-lifetime>43200000</maximum-connection-lifetime> </proxool></something-else-entirely>
以上就已經配置好了hibernate的基礎環境。
4.建立Hibernate的SessionFactory,進行初始化Hibernate。
/* * 文 件 名 : com.qisentech.data.hibernate.HibernateSessionFactory.java * 建立日期 : 2013-08-25 0:24:58 * 創 建 者 : qsyang */package com.qisentech.data.hibernate;import java.util.HashMap;import java.util.Map;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;/** * * @author qsyang */public class HibernateSessionFactory { private static boolean inited = false; private static SessionFactory factory = null; private static Configuration cfg = null; /** * 初始化 */ public static synchronized void init() { if (!inited) { try { cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); factory = cfg.buildSessionFactory(); inited = true; } catch (Exception ex) { log.error("初始化hibernate出錯", ex); throw new RuntimeException(ex); } } else { throw new java.lang.IllegalStateException( "HibernateSessionFactory already initialized"); } } public static Session openSession() { return factory.openSession(); } public static void destory() { factory.close(); }}
好了,我們需要在系統運行之前,需要調用init方法來初始化HibernateSessionFactory。
當然也可以在測試的時候在建立,不過建立sessionFactory是很耗時的。
5.下面進行建立對象測試。
TFunction 與 TToolsBox(關係是一對多)
/* * 文 件 名 : com.qisentech.webplus.entity.TFunction.java * 建立日期 : 2013-8-23 15:40:01 * 創 建 者 : qsyang */package com.qisentech.webplus.entity;import java.util.List;/** * <p>Title: </p> * * <p>Description: </p> * * @author qsyang * @version 1.0 */public class TFunction { private int id; private String name; private String img; private int sort; private boolean isSystem; private List<TToolsBox> toolsBoxList; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the img */ public String getImg() { return img; } /** * @param img the img to set */ public void setImg(String img) { this.img = img; } /** * @return the sort */ public int getSort() { return sort; } /** * @param sort the sort to set */ public void setSort(int sort) { this.sort = sort; } /** * @return the isSystem */ public boolean isIsSystem() { return isSystem; } /** * @param isSystem the isSystem to set */ public void setIsSystem(boolean isSystem) { this.isSystem = isSystem; } /** * @return the toolsBoxList */ public List<TToolsBox> getToolsBoxList() { return toolsBoxList; } /** * @param toolsBoxList the toolsBoxList to set */ public void setToolsBoxList(List<TToolsBox> toolsBoxList) { this.toolsBoxList = toolsBoxList; }}
/* * 文 件 名 : com.qisentech.webplus.entity.TToolsBox.java * 建立日期 : 2013-7-30 16:53:25 * 創 建 者 : qsyang */package com.qisentech.webplus.entity;/** * <p>Title: </p> * * <p>Description: </p> * * @author qsyang * @version 1.0 */public class TToolsBox { private int id; private String name; private String implClass; private int functionId; private String img; private int sort; private String url; private boolean isValid; private String target; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the implClass */ public String getImplClass() { return implClass; } /** * @param implClass the implClass to set */ public void setImplClass(String implClass) { this.implClass = implClass; } /** * @return the img */ public String getImg() { return img; } /** * @param img the img to set */ public void setImg(String img) { this.img = img; } /** * @return the sort */ public int getSort() { return sort; } /** * @param sort the sort to set */ public void setSort(int sort) { this.sort = sort; } /** * @return the url */ public String getUrl() { return url; } /** * @param url the url to set */ public void setUrl(String url) { this.url = url; } /** * @return the target */ public String getTarget() { return target; } /** * @param target the target to set */ public void setTarget(String target) { this.target = target; } /** * @return the isValid */ public boolean isIsValid() { return isValid; } /** * @param isValid the isValid to set */ public void setIsValid(boolean isValid) { this.isValid = isValid; } /** * @return the functionId */ public int getFunctionId() { return functionId; } /** * @param functionId the functionId to set */ public void setFunctionId(int functionId) { this.functionId = functionId; }}
好了,對象建立好了之後,需要建立對應的實體配置對應檔,主要是映射對象屬性和資料庫表欄位的關係。
T.Function.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="com.qisentech.webplus.entity"> <class name="TFunction" table="t_function"> <id column="Id" name="id"> <generator class="native"/> </id> <property column="Name" name="name"/> <property column="Img" name="img"/> <property column="Sort" name="sort"/> <property column="IsSystem" name="isSystem"/> <bag cascade="all" inverse="false" lazy="true" name="toolsBoxList" table="t_toolsbox"> <key column="FunctionId"/> <one-to-many class="TToolsBox"/> </bag> </class></hibernate-mapping>
T.TToolsBox.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="com.qisentech.webplus.entity"> <class name="TToolsBox" table="t_toolsbox"> <id column="Id" name="id"> <generator class="native"/> </id> <property column="Name" name="name"/> <property column="ImplClass" name="implClass"/> <property column="Url" name="url"/> <property column="Img" name="img"/> <property column="Sort" name="sort"/> <property column="IsValid" name="isValid"/> <property column="Target" name="target"/> <property column="FunctionId" name="functionId"/> </class></hibernate-mapping>
好了,設定檔也寫好了,需要將設定檔添加到hibernate.cfg.xml中映射進來。
<mapping resource="com/qisentech/webplus/entity/T.Function.hbm.xml"/><mapping resource="com/qisentech/webplus/entity/T.TToolsBox.hbm.xml"/>
6.開始做擷取第一個對象測試
資料庫t_function表資料如下:
| 1 |
系統管理 |
box_title_xtgl.gif |
10 |
1 |
| 2 |
基礎功能 |
box_title_jlgl.gif |
20 |
1 |
| 3 |
相關組件 |
box_title_xgzj.gif |
30 |
1 |
資料庫t_toolsbox表資料如下:
| 1 |
個人資訊 |
NULL |
box_xgmm.gif |
50 |
main.jsp |
1 |
_self |
1 |
| 2 |
人員管理 |
NULL |
box_idsgl.gif |
50 |
index.jsp |
1 |
_self |
2 |
| 3 |
院系管理 |
NULL |
box_yxsz.gif |
50 |
test.jsp |
1 |
_blank |
3 |
Session的get方法測試:
Session session = null;try { session = HibernateSessionFactory.openSession(); Object obj = session.get(TFunction.class, id); return obj == null ? null : (TFunction) obj;} catch (HibernateException ex) { throw ex;}finally{ session.close();}
Session的load方法測試:
Session session = null;try { session = HibernateSessionFactory.openSession(); Object obj = session.load(TFunction.class, id); return (TFunction) obj;} catch (HibernateException ex) { throw ex;}finally{ session.close();}
小插曲:Hibernate get和load區別?
1.從返回結果上對比:
load方式檢索不到的話會拋出org.hibernate.ObjectNotFoundException異常
get方法檢索不到的話會返回null
2.從檢索執行機制上對比:
get方法和find方法都是直接從資料庫中檢索 而load方法的執行則比較複雜首先尋找session的persistent Context中是否有緩衝,如果有則直接返回 如果沒有則判斷是否是lazy,如果不是直接存取資料庫檢索,查到記錄返回,查不到拋出異常 如果是lazy則需要建立代理對象,對象的initialized屬性為false,target屬性為null 在訪問獲得的代理對象的屬性時,檢索資料庫,如果找到記錄則把該記錄的對象複製到代理對象的target上,並將initialized=true,如果找不到就拋出異常。
簡單總結
總之對於get和load的根本區別,一句話,hibernate對於load方法認為該資料在資料庫中一定存在,可以放心的使用代理來消極式載入,如果在使用過程中發現了問題,只能拋異常;而對於get方法,hibernate一定要擷取到真實的資料,否則返回null。
關於Hibernate,還有很多需要探索,我會繼續跟帖說明,大家一起學習吧!