Hibernate 筆記大全四
1. 簡單的安裝與使用
拷貝jar、用到的配置文件(hibernate.cfg.xml、hibernate.properties、xxx.hbm.xml)
C添加:save、persist、saveOrUpdate、megre
R查詢:get(持久化類,主鍵id)、load(持久化類,主鍵id)、
三套查詢:
第一套:hql查詢(Query)
a. hql查詢 : hql語句面向: 持久化類 對象 屬性。
b. 隱式關聯: 關聯的屬性是一個實體。 @ManyToOne、@OneToOne
c. 顯示關聯: 關聯的屬性是一個集合。 @OneToMany、@ManyToMany 級聯刪除、mappby:加了mappby代表不維護關聯關係。
d. 抓取連接: join fetch可以提高查詢性能。
第二套:Criteria查詢(Criteria)
-- add() : 添加查詢條件
-- setProjection() : 查詢哪些列
-- addOrder() : 排序
-- createAlais() : 創建關聯查詢
-- createCriteria() : 創建關聯查詢
-- setFetchMode() : 抓取連接
DetachedCriteria離線查詢。
第三套:原生的sql查詢(SQLQuery)
-- addEntity() : 實體查詢
-- addSalcar() : 標量查詢
-- addJoin() : 關聯查詢
-- NamedNativeQuery : 命名查詢
U修改:update、saveOrUpdate、megre
D刪除:delete
持久化類映射:
1. 基礎的映射(類上) @Entity、 @Table
2. 主鍵映射: @Id (四種主鍵生成器) 複合主鍵、 複合屬性做爲主鍵@EmbeddId
3. 基本的屬性映射:
@Column、 @Lob、 @Basic(fetch=FetchType.EARGR|FetchType.LAZY)
@Temporal() java.util.Date
4. 集合映射:
@ElementCollection
@CollectionTable
List: @OrderColumn
Map: @MapKeyColumn
Set
5. 複合屬性映射
6. 關聯映射: 單向關聯、雙向關聯(1-N、1-1、N-N)
一、批量處理(性能調優):
1. 批量插入: 當你有10w條數據需要批量插入到數據庫時,就會出現以下問題?
循環10w次調用save方法添加數據。
當調用save方法後,對象,它的狀態將轉化爲持久化狀態。
持久化狀態的對象都是放在一級緩存中(內存中),這樣有可能會出現內存溢出!
session.save(u); // 就會把u放到一級緩存(內存)
// 當達到一定數量session.flush()與session.clear()。
if (i % 10 == 0){
session.flush(); // 把一級緩存裏的對象刷到底層數據庫表中.
session.clear(); //清空一級緩存中所有的持久化狀態的對象
}
2. 批量修改|刪除:
當你有10w條數據需要批量修改, 循環10w次在循環裏面寫:
Teacher t = session.get(Teacher.class, 1); // 當調用get方法時,該對象又會放到一級緩存中,這樣有可能會出現內存溢出!
t.setAge(100);|session.delete(t);
// 當達到一定數量session.flush()與session.clear()。
if (i % 10 == 0){
session.flush(); // 把一級緩存裏的對象刷到底層數據庫表中.
session.clear(); //清空一級緩存中所有的持久化狀態的對象
}
// jvm內存:-Xms64m -Xmx64m -XX:PermSize=64m -XX:MaxPermSize=64m
3. DML風格的批量處理 Data Manipulation Language : 數據操作語言.
DML (select、insert、update、delete)
DML風格的hql語法:( UPDATE | DELETE ) FROM? EntityName (WHERE where_conditions)?.
a. update from 持久化類 set 屬性 = ?, 屬性 = ? where 屬性 = ?
b. delete from 持久化類 where 屬性 = ?
操作步驟:
a. 獲取Session。
b. 定義hql語句
c. Query query = 調用session.createQuery(hql);
d. 調用query爲hql語句中的佔位符設置參數。
e. 調用query.executeUpdate();
二、數據過濾:
當你做任何查詢時,有一個查詢條件永遠是固定的,那這個時候就要想到用數據過濾。
數據過濾操作步驟:
1. 定義數據過濾:@FilterDef(name="名字|ageFilter")
2. 使用數據過濾:@Filter(name="ageFilter", condition="stu_age > :minAge")
-- condition部分:寫sql語句 引用過濾器中的參數前面加“:”
3. 通過session開啓數據過濾:session.enableFilter("ageFilter").setParameter();
-- session.enableFilter("ageFilter").setParameter("minAge", 20);
三、緩存:
1. 一級緩存(所有持久化狀態的對象都放在一級緩中).
a. 一級緩存與Session相關.
操作一級緩存的方法:
-- contains(Object object): 判斷一級緩存中是否存在該對象.
-- clear() : 把一級緩存中所的持久化對象清空。
-- evict(Object object) : 從一級緩存中踢出一個持久化對象.
-- flush() : 把一級緩存中所有的持久化對象同步到底層數據庫表中。
2. 二級緩存(SessionFactory 默認不是開啓的)
配置開啓二級緩存的步驟:
a. 在hiberante.cfg.xml文件中配置
-- hibernate.cache.use_second_level_cache : true
-- hibernate.cache.region.factory_class : 二級提供商。(ehcache第三方緩存框架).
b. 拷貝jar:
ehcache-core-2.4.3.jar
hibernate-ehcache-4.3.1.Final.jar
slf4j-api-1.7.2.jar (全部是接口)
slf4j-jdk14-1.7.2.jar (實現商)
slf4j : Simple Logging Facade for Java: 簡單的java日誌門面。
c. ehcache.xml緩存配置文件。
d. 配置哪些持久化使用二級緩存
第一種: @Cache()
第二種:hiberante.cfg.xml文件中配置
<class-cache usage="read-only" class="持久化類"/>
e. 操作二級緩存的方法:
1. 獲取二級緩存對象:
Cache secondCache = sessionFactory.getCache();
2. 判斷二級緩存裏面是否包含一個實體.
boolean containsEntity(Class entityClass, Serializable identifier)
boolean containsEntity(String entityName, Serializable identifier)
3. 從二級緩存中踢出所有的實體
secondCache.evictAllRegions();
4. 從二級緩存中踢出指定單個的實體
void evictEntity(Class entityClass, Serializable identifier)
void evictEntity(String entityName, Serializable identifier)
5. 從二級緩存中踢出該類型所有的實體
void evictEntityRegion(Class entityClass)
void evictEntityRegion(String entityName)
6. 獲取統計信息:
要獲取統計信息: 需要在hibernate.cfg.xml文件進行配置
<property name="hibernate.generate_statistics">true</property> // 生成統計信息
<!-- 讓Hibernate4更友好的顯示統計信息 -->
<property name="hibernate.cache.use_structured_entries">true</property>
a. 命中的的次數.
b. 錯失的次數.
Statistics s = sessionFactory.getStatistics();
System.out.println("二級緩存命中的次數:" + s.getSecondLevelCacheHitCount());
System.out.println("二級緩存錯失的次數:" + s.getSecondLevelCacheMissCount());
7. 對象以什麼樣的格式存儲在二級緩存中:
// 獲取單個對象的二級緩存統計信息
SecondLevelCacheStatistics sc = s.getSecondLevelCacheStatistics("org.fkjava.domain.Student");
// 對象以什麼樣的格式存儲在二級緩存中
System.out.println(sc.getEntries());
// 它是以map結構存儲的,key: 主鍵id value : map(存入該對象的信息[屬性名=屬性值])
3. 查詢緩存
使用查詢緩存的步驟:
a. 在hibernate.cfg.xml文件中配置
<property name="hibernate.cache.use_query_cache">true</property>
b. 在做查詢時:
query.setCacheable(true)
二級緩存與查詢緩存的區別:
二級緩存: 存放得是全是對象 {1={}, 2={}}
查詢緩存: 存放的結構{"查詢語句", [1,2,3,4]}
查詢緩存要想命中的話: 查詢語句與佔位符參數值都要一致!
注意:查詢緩存是在二級緩存基礎之上。(必須先開啓二級緩存).
四、Session線程安全問題:
Hibernate3.1之前話,我們會提供一個HibernateUtils工具類,來保證session是線程安全的。
用ThreadLocal線程局部變量,來會每一條線程複製一個同等功能的Session.
Hibernate3.1以後,它提供了一種可插拔的方式來配置Session成爲"上下文"線程相關的Session.
步驟:
1. 在hibernate.cfg.xml文件中配置:
<property name="hibernate.current_session_context_class">thread|jta</property>
thread : org.hibernate.context.internal.ThreadLocalSessionContext (jdbc事務)
jta : org.hibernate.context.internal.JTASessionContext (jta事務)
2. 獲取session的方式:
sessionFactory.getCurrentSession();
3. 不需要自已關閉session.
五、面向JPA規範編程:
Hibernate編程 JPA編程
Configuration Persistence
SessionFactory EntityManagerFactory
Session EntityManager(持久化操作)
Transaction EntityTransaction
Query - createQuery(hql) Query -- createQuery(jpql);
SQLQuery - createSQLQuery(sql) Query -- createNativeQuery(sql);
Criteria - createCriteria() Query -- createQuery(CriteriaQuery);
src/hiberante.cfg.xml src/META-INF/persistence.xml
1. CRUD操作:
添加:entityManager.persist(t1);
修改:
a. Teacher t = entityManager.find(Teacher.class, 1);
t.setXxx(); // 修改
// entityManager.flush();
// entityManager.detach(t1); // 從一級緩存中踢出一個持久化對象 session.evict().
b. Teacher t = new Teacher();
t.setId(1);
entityManager.merge(t1); // 修改
刪除:
Teacher t1 = entityManager.find(Teacher.class, 3);
entityManager.remove(t1); // 刪除
根據主鍵查詢 :
Teacher t1 = entityManager.find(Teacher.class, 2);
2. Query查詢:
一. Query query = entityManager.createQuery(jpql);
jpql查詢: 持久類 對象 屬性 (select s from Student as s)
操作步驟:
a. 得到EntityManager.
b. 定義jpql語句。
c. Query query = 調用entityManager.createQuery(jpql)創建查詢.
爲jpql語句中的佔位符設置參數setParameter(int position, Object val).
如果要分頁查詢的話調用:
query.setFirstResult((當前頁碼 - 1) * 每頁顯示的數量); limit ?,? 的第一個問號。
query.setMaxResults(每頁顯示的數量); limit ?,? 的第二個問號。
d. 調用query的getResultList()得到查詢結果,如果你明確知道只有一條記錄返回那就可以調用getSingleResult();
二. 原生的sql查詢
Query query = entityManager.createNativeQuery(sql);
操作步驟:
a. 得到EntityManager.
b. 定義sql語句。
c. Query query = 調用entityManager.createQuery(sql)創建查詢.
爲jpql語句中的佔位符設置參數setParameter(int position, Object val).
如果要分頁查詢的話調用:
query.setFirstResult((當前頁碼 - 1) * 每頁顯示的數量); limit ?,? 的第一個問號。
query.setMaxResults(每頁顯示的數量); limit ?,? 的第二個問號。
d. 調用query的getResultList()得到查詢結果,如果你明確知道只有一條記錄返回那就可以調用getSingleResult();
三 .Query query = entityManager.createQuery(CriteriaQuery);
CriteriaBuilder : Criteria構建類
-- 創建CriteriaQuery. createQuery().
-- 生成查詢條件。
CriteriaQuery : 條件查詢對象
-- from : 指明查詢哪個持久化類
-- orderBy
-- groupBy
-- multiselect : 查詢多列
-- select : 查詢一列
-- where : 添加查詢條件
Root : 封裝持久化實體的所有屬性。
-- fetch: 抓取連接
-- join : 關聯查詢
Path : 代表一個屬性
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.