?? hibernate.txt
字號:
七、如何實現hibernate的annotation
1、annotation將相關的配置寫在代碼中,而不是寫在xml中
這樣可以減少xml文件,方便維護。
2、當用到hibernate3.2的注解時,不能用Configuration而是用
AnnotationConfiguration加載相關的配置文件,其可以加載
*.hbm.xml也以加載有注解的類,一個表只能用一種方式加載,
如果用兩種就會出錯。
3、在hibernate.cfg.xml說明注解類的位置
<mapping class="hibernate.Users"></mapping>
一、為什么用annotation
annotation通過注解可以更方便的進行開發,也是將來spring、hibernate、strust轉化的方向。
二、hibernate中annotation的特點
hibernate3.2以上版本支持annotation,其注解與ejb3.0幾乎一樣,
配置及方法操作與已有的hibernate是一樣,只是核心類中的Configuration要改成
AnnotationConfiguration加載核心配置文件hibernate.cfg.xml文件。
hibernate.cfg.xml中可以加載*.hbm.xml也可以加載有注解的類
<mapping resource="hibernate/customer.hbm.xml"/>:加載customer.hbm.xml文件
<mapping class="hibernate/Buy"/>:加載Buy類
三、具體的注解
1、類名類的說明:
@Entity
@Table(name = "users")
1、主鍵:在get方法之前說明
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
若沒有@GeneratedValue注解,主鍵的值需要開發人員在編程中給定,不能自動生成。
若有@GeneratedValue,主鍵的值不需要開發人員給定,由數據庫自動生成。
2、字段:
1、@Transient //聲明其是一個屬性,不存于數據庫中
2、若沒寫任何說明,字段名與數據庫字段名相同
3、字段具體說明:
@Column(name = "email") //屬性名與數據庫字段名不同,通過name說明具體字段
@Basic(fetch = FetchType.LAZY) //說明當前字段是延遲加載
4、OneToMany:如果有兩個表,一個是one,另一個是many,該注解在one中,mappedBy="role"
"role"與many中Role類型屬性要一致,否則報錯。
@OneToMany(mappedBy = "role") //
@OrderBy("name")
5、ManyToOne:該注釋在many對象中設置,CascadeType.PERSIST代表主增從增,CascadeType.MERGE代表
主改從改。
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = "role_id") //role_id是many表對應的外鍵列名
hibernate高級應用
事務的四大特點?
原子性:要么全成功,要么全失敗
隔離性:事務與事務之間不影響
一致性:代碼實現所有業務相關的操作
持久性:保存到數據庫中
對于一個表,hibernate對應的主鍵生成機制有很多種?
assigned:主鍵值需要手動給定,開發人員必須手動給值
native:主鍵由數據庫自動生成,hibernate不管,開發人員也不用管。
七、如何實現hibernate的annotation
1、annotation將相關的配置寫在代碼中,而不是寫在xml中
這樣可以減少xml文件,方便維護。
2、當用到hibernate3.2的注解時,不能用Configuration而是用
AnnotationConfiguration加載相關的配置文件,其可以加載
*.hbm.xml也以加載有注解的類,一個表只能用一種方式加載,
如果用兩種就會出錯。
3、在hibernate.cfg.xml說明注解類的位置
<mapping class="hibernate.Users"></mapping>
沒有鎖出現的問題?
1、臟讀:后一個事務處理的數據是前一事務修改但沒有提交的數據。
事務1:
update buy set amount=amount+100 where buyID=1;
sleep(1000);
rollback;
事務2:數據來源事務1修改的數據
update buy set amount=amount+100 where buyID=1;
commit;
2、覆蓋更新:兩個事務同時讀取數據,
后一處事務將前一個事務修改的數據覆蓋了。
事務1:
update buy set amount=amount+100 where buyID=1;
sleep(1000);
commit;
事務2:數據來源事務1修改的數據
update buy set amount=amount+100 where buyID=1;
commit;
3、不可重復讀:一個事務兩個相同的select語句,第一次讀取的數據
與第二次讀取的數據不一樣,主要針對select語句。
事務1:
select * from buy;
sleep(1000);
select * from buy;
commit;
事務2:數據來源事務1修改的數據
update buy set amount=amount+100 where buyID=1;
commit;
4、幻想讀:第一次讀有,第二讀沒有,反之亦然。
與第二次讀取的數據不一樣,主要針對insert、delete。
事務1:
select * from buy;
sleep(1000);
select * from buy;
commit;
事務2:數據來源事務1修改的數據
delete from buy where buyID=1;
commit;
鎖的分類?
1、讀未提交
2、讀已提交(數據庫的默認方式)
1、讀取的數據是已提交的,防止臟讀。
2、對于更新,在提交之前會將當前行的版本與數據庫的版本
比較,若小于數據庫的版本報錯,回退。若等于數據庫的版
本提交。
3、分類:
樂觀鎖:一個游標取出的行,另一個事務可以更新,
如前游標所在事務更新另一事務已更新的數據時會
與數據庫的版本比較,發現版本小于數據庫的版本,
報錯,回退。
增強了并發性,不能保證當前游標一定修改成功。
悲觀鎖:一個游標取出行后,對所有的行加鎖,其余的事務只可
以查,不可以改。
弱化了并發性,但能保證當前游標一定修改成功。
3、可重復讀:將上一個select取出的數據保存一個副本,下一個select語句直接從
副本中取。
4、串行化:一個事務對一個表select后,針對該表其余的事務只能讀,不可
增刪改。
事務的實現方式?
1、代碼式
con.setAutoCommit(false);
con.commit();
Transaction trans=session.beginTransaction();
trans.commit();
trans.rollback();
2、聲明式:通過注解或xml文件配置具體的事務處理
1、spring
2、ejb2
3、ejb3
spring/ejb2/ejb3選擇事務的方式?
1、required:默認的方式,有則用已有的事務,沒有則產生一個新的事務。
2、mandanory:有則用,沒有則報錯
3、required_new:不管前面有沒有都產生一個新的,
如果有將前一個事務掛起用新的事務
如果沒有用新的事務。
4、support:有則用,沒有則不用。
5、not supported:有則報錯,沒有正常運行。
hibernate緩存的分類:
1、事務級:就是session級,即一級緩存,緩存的數據在當前事務內有效,
當前事務結束,緩存結束。
2、應用級:就是SessionFactory,即二級緩存,緩存的數據在整個應用程序內
有效,所有事務都可以共享二級緩存。
人為控制SessionFacatory只有一個實例。
3、集群級:有多個應用服務器,每一個應用服務有一個SessionFactory,
服務器與服務器可以通信。
要慎用,因為服務器與服務器通信及交互會占用大量的資源。
緩存的原則:
1、數據的大小在可接收的范圍內。
2、重復查詢使用率的。
3、更新小或并發更新小。
緩存的實現(ehcache):
1、將ehcache.jar包拷入到lib目錄下
2、在src根目錄下加入ehcache.xml文件
3、在hibernate.cfg.xml中加入ehcache的驅動屬性
及支持查詢的緩存
4、在*.hbm.xml文件中加入<cache usage="read-write"/>
5、在執行query之前設置setCacheable(true)
iterator與list方法之間的區別
1、list只執行一次sql,利用緩存的前提是Hql必須相等。
如果hql相等,在緩存中沒有會通過主鍵查找對應的對象。
2、如果沒有緩存iterator會執行(n行+1)將sql,第一個sql是查詢
出所有的主鍵,第二種sql是根據主鍵查找到得每一個對象,有多少
行就要執行對應行數的sql
只要緩存中有iterator就會用。
3、第一次查詢用list方法,以后的查詢用iterator
六、hibernate中的manyToMany
power:權力
private Set<Role> roles;//及get、set方法
配置文件信息:
<set name="roles" table="powerrole">
<key column="powerID"/>//powerID是中間的外鍵列
<many-to-many class="hibernate.Role" column="roleID"/>
</set>
select * from role where roleID in
{
select roleID from powerrole where powerID="當前對象的主鍵";
}
role:角色
private Set<power> powers;//及get、set方法
配置信息
<set name="powers" table="powerrole">
<key column="roleID">
<many-to-many class="hibernate.Power" column="powerID"/>
</set>
powerrole:中間表
get方法與load方法區別
1、相同點
get/load都根據類說明及主鍵查找
在hibernate3.2都會利用二級緩存
2、不同點
get:
1、返回的是一真實的對象
2、如果沒有找到返回null
load:
1、返回的是一個代理
2、如果沒有找到返回ObjectNotFoundException
緩存的特點:
1、load、get、update、saveOrUpdate、save、delete都會自動更新緩存
2、query.exeuteUpdate()執行效率但不同步緩存
3、刪除緩存中的數據
--一級緩存
session.evict(Customer.class)
--二級緩存
sessionFactory.evict(Customer.class)
4、利用緩存的過程
首先在一級緩存中找,如果沒找到在二級緩存中找,
如果還沒有找到執行sql數據庫中查找。
hibernate的優化策略:
1、選擇適當的緩存機制,如那些表需要二級緩存
2、管理好session的生命周期,一般是一個線程一個session
3、使用延遲加載
OneToMany或ManyToOne可以用延遲加載
大文本或大字節也用延遲加載
4、盡量使用樂觀鎖而不表悲觀鎖。
非觀鎖:
1、
Query query1=session.createQuery("select * from Customer for update");
2、
Query query1=session.createQuery("select * from Customer");
query1.setLockMode("Customer",LockMode.UPGRADE);
樂觀鎖:默認的方式
<class
optimistic-lock="version/none"
/>
5、如果可能主鍵使用uuid,而不是identity或native
在增加時對于類型是identity主鍵,會生成兩個sql
第一個sql是取最大的主鍵
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -