摘要: 在hql中關鍵字不區分大小寫,但是屬性和類名區分大不寫
簡單屬性查詢[重要]
1 單一屬性查詢,返回結果集屬性列表,元素類型和實體類中相應的屬性類型一致
List students=session.createQuery("select name from Student").list();
&nb...
閱讀全文
posted @
2009-11-03 17:14 junly 閱讀(502) |
評論 (0) |
編輯 收藏
一級緩存
* 一級緩存是緩存實體對象的
* 如果管理一級緩存
一級緩存無法取消,但可以管理clear(),evict()
* 一級緩存和session的生命周期一致,一級緩存也叫session級的緩存或事務級緩存
* 如何避免一次性大量的實體數據入庫導至內存溢出
先flush,再clear
* 如何管理一級緩存
load,get,iterate,save都支持一級緩存
如果數據量特別大,考慮采用jdbc實現,如查jdbc也不能滿足要求可以考慮采用數據本身的特定導入工具
Student student=(Student)session.load(Student.class,1);
System.out.println("studnet.name="+student.getName());
//不會發出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>
指定緩存產品提供商
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
4 指定那些對象使用二級緩存(兩種方運河)
* 在映射文件中采用<cache>標簽
<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/>標簽
<class-cache class="com.bjsxt.hibernate.Studnet" usage="read-only"/>
管理二級緩存
factory.evict(Student.class);
factory.evict(Student.class,1);
一級緩存和二級緩存的交互問題
1 不設置(默認)會寫入二級緩存,也會讀出
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);
查詢緩存
查詢緩存是針對普通屬性結果集的緩存
對實體對象的結果只緩存id
查詢緩存的生命周期,當前關聯的表發生修改,那么查詢緩存生命周期結束
查詢緩存的配置和使用
1 起用查詢緩存
* 配置hibernate.cfg.xml文件
<property name="hibernate.cache.use_second_level_cache">true</property>
* 在程序中顯式起用
query.setCacheable(true);
2 Session和查詢緩存生命周期沒有關系
3 查詢緩存對query.iterate()不起作用,只用對query.list()起作用
posted @
2009-11-03 16:49 junly 閱讀(337) |
評論 (0) |
編輯 收藏
悲觀鎖
悲觀鎖的實現,通常依賴于數據庫機制,在整個過程中將數據鎖定,其它任何用戶都不能讀取或修改
session.load(Inventory.class, 1, LockMode.UPGRADE);
樂觀鎖
大多數基于數據版本記錄機制(version)實現,一般是在數據庫表中加入一個version字段
讀取數據時將版本號一同讀出,之后更新數據時版本號加一,如果提交數據時片本號小于
或等于數據庫表中的版本號,則認為數據是過期的,否則給予更新。
1 Inventory.java:
private int id;
private String name;
private int count;
private int version;
//version版本號由數據庫維護,我們不用管
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 閱讀(214) |
評論 (0) |
編輯 收藏
session flush測試:
session flush方法主要做了兩件事:
1 清理緩存
2 執行sql(不是提交事務)
session在什么情況下執行flush
1 默認在事務提交時
2 顯式的調用flush
3 在執行查詢前,如:iterate
hibernate按照save(insert),update,delete順序提交相關的操作
------------------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
因為id的主鍵生成策略采用的是uuid,所以調用完save后,只是將user對象納入到session的管理
不會發出insert語句,但是id已經生成,session中existsInDatebase狀態為false
session.save(user);
調用flush,hibernate會清理緩存,執行sql
如果數據庫的隔離級別為提交讀,那么我們可以看到flush過的數據
并且session中existsInDatebase狀態變為true
session.flush();
默認情況下commit操作會先執行者flush清理緩存,所以不用顯式的調用flush
commit后數據無法回滾
session.getTransaction().commit();
<id name="id">
<generator class="native"/>
</id>
如果id的主鍵生成策略采用的是native,調用save(user)時會發出insert語句,返回由數據庫生成的id,
user對象納入到session的管理,session中existsInDatebase狀態為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已經將user從session中
逐出了,所以找不到相關數據,無法更新,拋出異常
session.getTransaction().commit();
----------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
session.save(user);
flush后hibernate會清理緩存,會將user對象保存到數據庫中,將session中的insertions中的user
清除,并且設置session中existsInDatabase的狀態為true
session.flush(user);
將user對象從session中逐出,即session的EntityEntries屬性中逐出
session.evict(user);//清理緩存
可以成功提交,因為hibernate在清理緩存時,在session的insertions集合中無法找到user對象
所以就不會發出insert語句,也不會更新session中的existsInDatabase的狀態
session.getTransaction().commit();
-----------------------------------------------------------------
<id name="id">
<generator class="native"/>
</id>
session.save(user);
將user對象從session中逐出,即session的EntityEntries屬性中逐出
session.evict(user);//清理緩存
可以成功提交,因為hibernate在清理緩存時,在session的insertions集合中無法找到user對象
所以就不會發出insert語句,也不會更新session中的existsInDatabase的狀態
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();
結果:
insert into ...
insert into ...
update t_user ...
hibernate按照save(insert),update,delete順序提交相關的操作
-----------------------------------------------------------------
<id name="id">
<generator class="assigned"/>
</id>
session.save(user);
user.setName("張三");
session.update(user);
因為我們在session.update(user)后執行了flush,所以在以commit清理緩存時執行flush前的sql就不會發出.
session.flush();//在這里flush操作就可以了
User user2=new User();
user2.setId("003");
user2.setName("李四");
session.getTransaction().commit();
結果:
insert into ...
update t_user ...
insert into ...
按照我們想要順序save(insert),update,save(insert)的順序提交操作
-----------------------------------------------------------------
posted @
2009-11-03 16:37 junly 閱讀(1225) |
評論 (1) |
編輯 收藏
抓取策略(單端代理的批量抓取)
1 保持默認,也就是fetch="select"
<many-to-one name="classes" column="classesid" cascade="save-update"/>
fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
2 設置fetch="jion"
<many-to-one name="classes" column="classesid" cascade="save-update" fetch="join"/>
fetch="jion",hibernate會通過select語句會使用外聯接來加載其關聯實體或集合,此時lazy會失效
------------------------------------------------------------
抓取策略(集合代理的批量抓取)
1 保持默認,也就是fetch="select"
<set name="students" fetch="select">
fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
2 設置fetch="jion"
<set name="students" fetch="jion">
fetch="jion",hibernate會通過select語句會使用外聯接來加載其關聯實體或集合,此時lazy會失效
3 設置fetch="subselect"
<set name="students" fetch="subselect">
fetch="subselect",用于createQuery()查詢,另外發送一條select語句抓取在前面查詢到的所有實體對象的關聯集合
----------------------------------------------------------------
抓取策略,batch-size在<class>上的應用
batch-size屬性,可能批量加載體類,參見:Classes.hbm.xml
<class name="Classes" table="t_classes" batch-size="3">
在hibernate.cfg.xml中設置
<property name="hibernate.jdbc.fetch_size">50</property>
posted @
2009-11-03 16:34 junly 閱讀(774) |
評論 (0) |
編輯 收藏
摘要: lazy策略可以使用在:
* <class>標簽上,可以取值:true/false
* <property>標簽上,可以取值:true/false需要類增強工具
* <set><list>標簽上,可以取值:true/false/extra
...
閱讀全文
posted @
2009-11-03 16:33 junly 閱讀(533) |
評論 (0) |
編輯 收藏
Component映射(值對象映射)
在hibernate中,component是某個實體的邏輯組成部分,它與實體的根本區別是沒有oid,
component可以稱為是值對象(DDD)
采用component映射的好處:它實現了對象模型的細粒度劃分,層次會更分明,復用率會更高
<!--
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>
復合(聯合)主鍵映射
通常將復合主鍵相關的屬性,單獨放到一個類中
* 此類必須實現序列化接口
* 覆寫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;
//結束日期
private Date endDate;
//狀態
private String periodSts;
}
posted @
2009-11-03 16:22 junly 閱讀(196) |
評論 (0) |
編輯 收藏
1 class Node:
private int id;
private String name;
private Node parent;//交節點
private Set children;//子節點
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 閱讀(595) |
評論 (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 閱讀(177) |
評論 (0) |
編輯 收藏
摘要: 繼承映射的三種策略:
* 單表繼承,每棵類繼承樹使用一個表
* 具體表繼承,每個子類一個表
* 類表繼承,每個具體類一個表
-----------------------------------------------------------------
每棵類繼承樹映射成一張表
1、理解如何映射
因為類繼承樹肯定是對...
閱讀全文
posted @
2009-11-03 16:15 junly 閱讀(187) |
評論 (0) |
編輯 收藏