Hibernate 為提高性能,提供了緩存與快照機制。
事務執行 SQL 時,結果存入 Session 內部 Map 集合(含快照)。同一 Session 內重複查詢同一對象,直接返回緩存對象,不發 SQL。
Configuration config = new Configuration().configure();
SessionFactory sf = config.buildSessionFactory();
Session s = sf.openSession();
Transaction tran = null;
try {
tran = s.beginTransaction();
// 1. get() 查詢
User u = (User) s.get(User.class, 1); // 生成 SQL,放入緩存
User u1 = (User) s.get(User.class, 1); // 無 SQL,取自緩存
System.out.println(u == u1); // true
// 2. HQL 查詢
Query q = s.createQuery("from User where id=1");
User u2 = (User) q.uniqueResult(); // 生成 SQL,但結果取自緩存
System.out.println(u2 == u); // true
// 3. 原生 SQL
SQLQuery q1 = s.createSQLQuery("select * from User where id=1");
q1.addEntity(User.class);
User u3 = (User) q1.uniqueResult(); // 生成 SQL,結果取自緩存
System.out.println(u3 == u); // true
// 4. Criteria 查詢
Criteria c = s.createCriteria(User.class);
c.add(Restrictions.eq("id", 1));
User u4 = (User) c.uniqueResult(); // 生成 SQL,結果取自緩存
System.out.println(u4 == u); // true
tran.commit();
} catch (HibernateException e) {
if (tran != null) tran.rollback();
e.printStackTrace();
} finally {
s.close(); sf.close();
}
| 查詢方式 | SQL 緩存 | 對象緩存 |
|---|---|---|
| get()/load() | ✓ | ✓ |
| HQL | ✗ | ✓ |
| 原生 SQL | ✗ | ✓ |
| Criteria | ✗ | ✓ |
User user = new User();
user.setName("xiaobai");
user.setAge(121);
s.save(user); // 立即執行 INSERT,返回生成的 ID,對象變持久態
s.persist(user); // 不保證立即生成 ID,可能延遲到 flush,不返回 ID
關鍵差異:
save():立即插入,返回標識符persist():不保證立即賦值 ID,不返回標識符s.save(user); // 插入並放入緩存 User u1 = (User) s.get(User.class, user.getId()); // 無 SQL,取自緩存 System.out.println(u1 == user); // true
// 方式一:先查詢再刪除 User u = (User) s.get(User.class, 10); s.delete(u); // 持久態 → 游離態 // 方式二:僅設置 ID(性能更好) User u = new User(); u.setId(5); s.delete(u);
// 持久態對象修改屬性,提交事務自動更新(無需調用 update)
User u = (User) s.get(User.class, 1);
u.setName("set"); // 事務 commit 時,Hibernate 拿快照比較,不同則自動 UPDATE
// 游離態對象需手動 update
User u = new User(); // 瞬時態
u.setId(1);
u.setName("1");
s.update(u); // 手動觸發更新
快照機制:持久態對象修改時,框架對比快照,相同無動作,不同自動生成 UPDATE SQL。
save() 返回 ID,persist() 不返回;get() 立即查詢,load() 延遲加載(代理)