摘要: 在hql中關(guān)鍵字不區(qū)分大小寫,但是屬性和類名區(qū)分大不寫
簡單屬性查詢[重要]
1 單一屬性查詢,返回結(jié)果集屬性列表,元素類型和實體類中相應(yīng)的屬性類型一致
List students=session.createQuery("select name from Student").list();
&nb...
閱讀全文
posted @
2009-11-03 17:14 junly 閱讀(506) |
評論 (0) |
編輯 收藏
一級緩存
* 一級緩存是緩存實體對象的
* 如果管理一級緩存
一級緩存無法取消,但可以管理clear(),evict()
* 一級緩存和session的生命周期一致,一級緩存也叫session級的緩存或事務(wù)級緩存
* 如何避免一次性大量的實體數(shù)據(jù)入庫導(dǎo)至內(nèi)存溢出
先flush,再clear
* 如何管理一級緩存
load,get,iterate,save都支持一級緩存
如果數(shù)據(jù)量特別大,考慮采用jdbc實現(xiàn),如查jdbc也不能滿足要求可以考慮采用數(shù)據(jù)本身的特定導(dǎo)入工具
Student student=(Student)session.load(Student.class,1);
System.out.println("studnet.name="+student.getName());
//不會發(fā)出sql,因為load使用緩存
Student student=(Student)session.load(Student.class,1);
System.out.println("studnet.name="+student.getName());
二級緩存
* 二級緩存是緩存實體對象的,普通屬性不會緩存
* 二級緩存是進程級的緩存,也稱為SessionFactory級的緩存,可以被所有的session共享
二級緩存的生命周期和SessionFactory是一致的,可以用SessionFactory管理二級緩存
* 二級緩存的配置和使用
1 加入ehcache的jar包;
2 拷貝ehcache.xml文件到src目錄下;
3 開啟二級緩存,默認是打開的。配置hibernate.cfg.xml
hibernate.cfg.xml文件
開啟二級緩存
<property name="hibernate.cache.use_second_level_cache">true</property>
指定緩存產(chǎn)品提供商
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
4 指定那些對象使用二級緩存(兩種方運河)
* 在映射文件中采用<cache>標(biāo)簽
<class name="com.my.hibernate.User" table="t_user">
<cache usage="read-only"/>
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>
* 在hibernate.cfg.xml文件中,采用<class-cache/>標(biāo)簽
<class-cache class="com.bjsxt.hibernate.Studnet" usage="read-only"/>
管理二級緩存
factory.evict(Student.class);
factory.evict(Student.class,1);
一級緩存和二級緩存的交互問題
1 不設(shè)置(默認)會寫入二級緩存,也會讀出
2 GET只讀而不寫入二級緩存
session.setCacheMode(CacheMode.GET);
Student student=(Student)session.load(Student.class,1);
3 PUT只寫入二級緩存頁不讀取
session.setCacheMode(CacheMode.PUT);
Student student=(Student)session.load(Student.class,1);
查詢緩存
查詢緩存是針對普通屬性結(jié)果集的緩存
對實體對象的結(jié)果只緩存id
查詢緩存的生命周期,當(dāng)前關(guān)聯(lián)的表發(fā)生修改,那么查詢緩存生命周期結(jié)束
查詢緩存的配置和使用
1 起用查詢緩存
* 配置hibernate.cfg.xml文件
<property name="hibernate.cache.use_second_level_cache">true</property>
* 在程序中顯式起用
query.setCacheable(true);
2 Session和查詢緩存生命周期沒有關(guān)系
3 查詢緩存對query.iterate()不起作用,只用對query.list()起作用
posted @
2009-11-03 16:49 junly 閱讀(339) |
評論 (0) |
編輯 收藏
悲觀鎖
悲觀鎖的實現(xiàn),通常依賴于數(shù)據(jù)庫機制,在整個過程中將數(shù)據(jù)鎖定,其它任何用戶都不能讀取或修改
session.load(Inventory.class, 1, LockMode.UPGRADE);
樂觀鎖
大多數(shù)基于數(shù)據(jù)版本記錄機制(version)實現(xiàn),一般是在數(shù)據(jù)庫表中加入一個version字段
讀取數(shù)據(jù)時將版本號一同讀出,之后更新數(shù)據(jù)時版本號加一,如果提交數(shù)據(jù)時片本號小于
或等于數(shù)據(jù)庫表中的版本號,則認為數(shù)據(jù)是過期的,否則給予更新。
1 Inventory.java:
private int id;
private String name;
private int count;
private int version;
//version版本號由數(shù)據(jù)庫維護,我們不用管
2 Inventory.hbm.xml
<class name="Inventory" table="t_inventory2" optimistic-lock="version">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="count"/>
<property name="version"/>
</class>
posted @
2009-11-03 16:40 junly 閱讀(216) |
評論 (0) |
編輯 收藏
session flush測試:
session flush方法主要做了兩件事:
1 清理緩存
2 執(zhí)行sql(不是提交事務(wù))
session在什么情況下執(zhí)行flush
1 默認在事務(wù)提交時
2 顯式的調(diào)用flush
3 在執(zhí)行查詢前,如:iterate
hibernate按照save(insert),update,delete順序提交相關(guān)的操作
------------------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
因為id的主鍵生成策略采用的是uuid,所以調(diào)用完save后,只是將user對象納入到session的管理
不會發(fā)出insert語句,但是id已經(jīng)生成,session中existsInDatebase狀態(tài)為false
session.save(user);
調(diào)用flush,hibernate會清理緩存,執(zhí)行sql
如果數(shù)據(jù)庫的隔離級別為提交讀,那么我們可以看到flush過的數(shù)據(jù)
并且session中existsInDatebase狀態(tài)變?yōu)閠rue
session.flush();
默認情況下commit操作會先執(zhí)行者flush清理緩存,所以不用顯式的調(diào)用flush
commit后數(shù)據(jù)無法回滾
session.getTransaction().commit();
<id name="id">
<generator class="native"/>
</id>
如果id的主鍵生成策略采用的是native,調(diào)用save(user)時會發(fā)出insert語句,返回由數(shù)據(jù)庫生成的id,
user對象納入到session的管理,session中existsInDatebase狀態(tài)為true
-----------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
session.save(user);
將user對象從session中逐出,即session的EntiryEntries屬性中逐出
session.evict(user);//清理緩存
無法成功提交,因為hibernate在清理緩存時,在session的insertions集合中取出user對象進行insert操作后
需要更新entityEntries屬性中的existsnDatabase為true,而我們采用evict已經(jīng)將user從session中
逐出了,所以找不到相關(guān)數(shù)據(jù),無法更新,拋出異常
session.getTransaction().commit();
----------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
session.save(user);
flush后hibernate會清理緩存,會將user對象保存到數(shù)據(jù)庫中,將session中的insertions中的user
清除,并且設(shè)置session中existsInDatabase的狀態(tài)為true
session.flush(user);
將user對象從session中逐出,即session的EntityEntries屬性中逐出
session.evict(user);//清理緩存
可以成功提交,因為hibernate在清理緩存時,在session的insertions集合中無法找到user對象
所以就不會發(fā)出insert語句,也不會更新session中的existsInDatabase的狀態(tài)
session.getTransaction().commit();
-----------------------------------------------------------------
<id name="id">
<generator class="native"/>
</id>
session.save(user);
將user對象從session中逐出,即session的EntityEntries屬性中逐出
session.evict(user);//清理緩存
可以成功提交,因為hibernate在清理緩存時,在session的insertions集合中無法找到user對象
所以就不會發(fā)出insert語句,也不會更新session中的existsInDatabase的狀態(tài)
session.getTransaction().commit();
-----------------------------------------------------------------
<id name="id">
<generator class="assigned"/>
</id>
session.save(user);
user.setName("張三");
session.update(user);
User user2=new User();
user2.setId("003");
user2.setName("李四");
session.getTransaction().commit();
結(jié)果:
insert into ...
insert into ...
update t_user ...
hibernate按照save(insert),update,delete順序提交相關(guān)的操作
-----------------------------------------------------------------
<id name="id">
<generator class="assigned"/>
</id>
session.save(user);
user.setName("張三");
session.update(user);
因為我們在session.update(user)后執(zhí)行了flush,所以在以commit清理緩存時執(zhí)行flush前的sql就不會發(fā)出.
session.flush();//在這里flush操作就可以了
User user2=new User();
user2.setId("003");
user2.setName("李四");
session.getTransaction().commit();
結(jié)果:
insert into ...
update t_user ...
insert into ...
按照我們想要順序save(insert),update,save(insert)的順序提交操作
-----------------------------------------------------------------
posted @
2009-11-03 16:37 junly 閱讀(1230) |
評論 (1) |
編輯 收藏
抓取策略(單端代理的批量抓取)
1 保持默認,也就是fetch="select"
<many-to-one name="classes" column="classesid" cascade="save-update"/>
fetch="select",另外發(fā)送一條select語句抓取當(dāng)前對象關(guān)聯(lián)實體或集合
2 設(shè)置fetch="jion"
<many-to-one name="classes" column="classesid" cascade="save-update" fetch="join"/>
fetch="jion",hibernate會通過select語句會使用外聯(lián)接來加載其關(guān)聯(lián)實體或集合,此時lazy會失效
------------------------------------------------------------
抓取策略(集合代理的批量抓取)
1 保持默認,也就是fetch="select"
<set name="students" fetch="select">
fetch="select",另外發(fā)送一條select語句抓取當(dāng)前對象關(guān)聯(lián)實體或集合
2 設(shè)置fetch="jion"
<set name="students" fetch="jion">
fetch="jion",hibernate會通過select語句會使用外聯(lián)接來加載其關(guān)聯(lián)實體或集合,此時lazy會失效
3 設(shè)置fetch="subselect"
<set name="students" fetch="subselect">
fetch="subselect",用于createQuery()查詢,另外發(fā)送一條select語句抓取在前面查詢到的所有實體對象的關(guān)聯(lián)集合
----------------------------------------------------------------
抓取策略,batch-size在<class>上的應(yīng)用
batch-size屬性,可能批量加載體類,參見:Classes.hbm.xml
<class name="Classes" table="t_classes" batch-size="3">
在hibernate.cfg.xml中設(shè)置
<property name="hibernate.jdbc.fetch_size">50</property>
posted @
2009-11-03 16:34 junly 閱讀(777) |
評論 (0) |
編輯 收藏
摘要: lazy策略可以使用在:
* <class>標(biāo)簽上,可以取值:true/false
* <property>標(biāo)簽上,可以取值:true/false需要類增強工具
* <set><list>標(biāo)簽上,可以取值:true/false/extra
...
閱讀全文
posted @
2009-11-03 16:33 junly 閱讀(534) |
評論 (0) |
編輯 收藏
Component映射(值對象映射)
在hibernate中,component是某個實體的邏輯組成部分,它與實體的根本區(qū)別是沒有oid,
component可以稱為是值對象(DDD)
采用component映射的好處:它實現(xiàn)了對象模型的細粒度劃分,層次會更分明,復(fù)用率會更高
<!--
User: Comtact:
private int id; private String email;
private String name; private String address;
private Comtact comtact; private String phone;
-->
<class name="User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<component name="comtact">
<property name="email"/>
<property name="address"/>
<property name="phone"/>
</component>
</class>
復(fù)合(聯(lián)合)主鍵映射
通常將復(fù)合主鍵相關(guān)的屬性,單獨放到一個類中
* 此類必須實現(xiàn)序列化接口
* 覆寫hashcode和equals方法
<class name="com.bjsxt.hibernate.FiscalYearPeriod" table="t_fiscal_year_period">
<composite-id name="fiscalYearPeriodPK">
<key-property name="fiscalYear"/>
<key-property name="fiscalPeriod"/>
</composite-id>
<property name="beginDate"/>
<property name="endDate"/>
<property name="periodSts"/>
</class>

public class FiscalYearPeriodPK implements Serializable
{
//核算年
private int fiscalYear;
//核算月
private int fiscalPeriod;

public int getFiscalYear()
{
return fiscalYear;
}

public void setFiscalYear(int fiscalYear)
{
this.fiscalYear = fiscalYear;
}

public int getFiscalPeriod()
{
return fiscalPeriod;
}

public void setFiscalPeriod(int fiscalPeriod)
{
this.fiscalPeriod = fiscalPeriod;
}

@Override

public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + fiscalPeriod;
result = prime * result + fiscalYear;
return result;
}

@Override

public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final FiscalYearPeriodPK other = (FiscalYearPeriodPK) obj;
if (fiscalPeriod != other.fiscalPeriod)
return false;
if (fiscalYear != other.fiscalYear)
return false;
return true;
}
}


public class FiscalYearPeriod
{
private FiscalYearPeriodPK fiscalYearPeriodPK;
//開始日期
private Date beginDate;
//結(jié)束日期
private Date endDate;
//狀態(tài)
private String periodSts;
}
posted @
2009-11-03 16:22 junly 閱讀(199) |
評論 (0) |
編輯 收藏
1 class Node:
private int id;
private String name;
private Node parent;//交節(jié)點
private Set children;//子節(jié)點
2 Node.hbm.xml:
<class name="node" class="com.my.hibernate.Node">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="parent" column="pid"/>
<set name="children" lazy="false" inverse="true" cascade="all">
<key column="pid"/>
<one-to-many class="com.my.hibernate.Node"/>
</set>
</class>
posted @
2009-11-03 16:19 junly 閱讀(596) |
評論 (1) |
編輯 收藏
set、list、array、map
Collection:
private int id;
private String name;
private Set setValue;
private List listValue;
private String[] arrayValue;
private Map mapValue;
<class name="Collection">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="setValue" table="t_setvalue">
<key column="setid"/>
<element type="string" column="setvalue"/>
</set>
<list name="listValue" table="t_listvalue">
<key column="listid"/>
<list-index column="listindex"/>
<element type="string" column="listvalue"/>
</list>
<array name="arrayValue" table="t_arrayvalue">
<key column="arrayid"/>
<list-index column="arrayindex"/>
<element type="string" column="arrayvalue"/>
</array>
<map name="mapValue" table="t_mapvalue">
<key column="mapid"/>
<map-key type="string" column="mapkey"/>
<element type="string" column="mapvalue"/>
</map>
</class>
posted @
2009-11-03 16:17 junly 閱讀(180) |
評論 (0) |
編輯 收藏
摘要: 繼承映射的三種策略:
* 單表繼承,每棵類繼承樹使用一個表
* 具體表繼承,每個子類一個表
* 類表繼承,每個具體類一個表
-----------------------------------------------------------------
每棵類繼承樹映射成一張表
1、理解如何映射
因為類繼承樹肯定是對...
閱讀全文
posted @
2009-11-03 16:15 junly 閱讀(189) |
評論 (0) |
編輯 收藏