国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - 詳解Java的Hibernate框架中的緩存與二級緩存

詳解Java的Hibernate框架中的緩存與二級緩存

2020-03-14 15:22cxshun JAVA教程

這篇文章主要介紹了Java的Hibernate框架中的緩存與二級緩存,Hibernate是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下 cxshun

緩存

今天我們就來講一下hibernate中實體狀態(tài)和hibernate緩存。
 1)首先我們先來看一下實體狀態(tài):
 實體狀態(tài)主要分三種:transient,persitent,detached。
 看英文應(yīng)該就大概明白了吧。
 transient:是指數(shù)據(jù)還沒跟數(shù)據(jù)庫中的數(shù)據(jù)相對應(yīng)。
 persistent:是指數(shù)據(jù)跟數(shù)據(jù)庫中的數(shù)據(jù)相對應(yīng),它的任何改變都會反映到數(shù)據(jù)庫中。
 detached:是指數(shù)據(jù)跟數(shù)據(jù)庫中的數(shù)據(jù)相對應(yīng),但由于session被關(guān)閉,它所做的修改不會對數(shù)據(jù)庫的記錄造成影響。
 下面我們直接代碼來:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Transaction tx = session.beginTransaction();
User user = new User();
user.setName("shun");
//這里的user還未保存到數(shù)據(jù)庫,數(shù)據(jù)庫表中并沒有與之對應(yīng)的記錄,它為transient狀態(tài)
session.save(user);
tx.commit();
//提交之后user變?yōu)閜ersistent狀態(tài)
session.close();
//由于session關(guān)閉,此時的user為detached狀態(tài),它的所有修改都不會反映到數(shù)據(jù)庫中。
     
Session session2 = sessionFactory.openSession();
tx = session2.beginTransaction();
user.setName("shun123");
session2.saveOrUpdate(user);
tx.commit();
//當(dāng)我們調(diào)用了saveOrUpdate之后,user重新變?yōu)閜ersistent狀態(tài),它的所有修改都會反映到數(shù)據(jù)庫中。
session2.close();

  我們看到代碼,首先我們定義了一個對象user,在未保存之前,它就是transient狀態(tài),在數(shù)據(jù)庫中并沒有與它相應(yīng)的記錄。而當(dāng)我們進行保存并提交修改后,user成為persistent狀態(tài),在數(shù)據(jù)庫中有相應(yīng)的一條記錄。而當(dāng)我們把session關(guān)閉后,user就變成了detached狀態(tài)了,它的更改并不會反映到數(shù)據(jù)庫中,除非我們手動調(diào)用saveOrUpdate等相應(yīng)的更新和添加方法。而當(dāng)我們直接想讓它從persistent到transient狀態(tài),怎么辦呢?直接刪除就可以了,刪除后對象就在數(shù)據(jù)庫中沒有對應(yīng)的記錄,也就成transient狀態(tài)了。
 
 hibernate的狀態(tài)轉(zhuǎn)換還是比較簡單的,當(dāng)是transient狀態(tài)時,數(shù)據(jù)庫沒有記錄對應(yīng),而persistent和detached時都有對應(yīng)的記錄,但唯一的區(qū)別是detached是在session關(guān)閉之后才有的狀態(tài)。那么transient和detached的區(qū)別又是什么呢?就是有沒有數(shù)據(jù)庫表記錄對應(yīng)的問題。
 
 2)看完了狀態(tài)我們來看一下hibernate的緩存
 hibernate的緩存分兩種,一級緩存和二級緩存。
 一級緩存:所謂的一級緩存也就是內(nèi)部緩存。
 二級緩存:它包括應(yīng)用級緩存,在hibernate就是所謂的SessionFactory緩存,另外一個是分布式緩存,這個是最安全的緩存方式。
 直接來看程序:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
 
  Configuration cfg = new Configuration().configure();
  SessionFactory sessionFactory = cfg.buildSessionFactory();
  Session session = sessionFactory.openSession();
     
  User user = (User)session.load(User.class,new Long(29));
  System.out.println(user.getName());
     
  User user2 = (User)session.load(User.class,new Long(29));
  System.out.println(user2.getName());
     
  session.close();
}

  看結(jié)果:

?
1
2
3
Hibernate: select user0_.USER_ID as USER1_0_0_, user0_.USER_NAME as USER2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=?
shun123123
shun123123

 例子中我們用了兩次load,但結(jié)果中只有一句SQL語句,這表明它只查詢了一次。
 為什么呢?這也就是hibernate的緩存起作用了。第一次查詢完畢后,hibernate后把查出來的實體放在緩存中,下一次查的時候首先會查緩存,看有沒有對應(yīng)ID的實體存在,如果有則直接取出,否則則進行數(shù)據(jù)庫的查詢。
 
 下面我們把代碼修改成:

?
1
2
3
4
5
6
7
8
9
User user = (User)session.load(User.class,new Long(29));
System.out.println(user.getName());
     
session.evict(user);//把user從緩存中刪掉
     
User user2 = (User)session.load(User.class,new Long(29));
System.out.println(user2.getName());
     
session.close();

  看到結(jié)果:

?
1
2
3
4
Hibernate: select user0_.USER_ID as USER1_0_0_, user0_.USER_NAME as USER2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=?
shun123123
Hibernate: select user0_.USER_ID as USER1_0_0_, user0_.USER_NAME as USER2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=?
shun123123

  自己我們把user從緩存中刪除后,第二次的查詢也直接從數(shù)據(jù)庫中取出。

二級緩存小談
先看實體類:

?
1
2
3
4
5
6
7
public class User implements Serializable{
 
  public Long id;
  private String name;
  private int age;
   
}

  映射文件就省略啦,大家應(yīng)該都會寫的。
 再來看看hibernate配置文件:

?
1
2
3
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>

   我們看到provider_class中我們指定了ehcache這個提供類,所以我們也需要ehcache.xml放在classpath中:

?
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
  <diskStore path="java.io.path"/>
  <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    overflowToDisk="true"
    />
</ehcache>

 接下來,我們直接看一下測試方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
 
  Configuration cfg = new Configuration().configure();
  SessionFactory sessionFactory = cfg.buildSessionFactory();
  Session session = sessionFactory.openSession();
 
  Query query = session.createQuery("from User user where name = 'shun123'");
  Iterator iter = query.iterate();
  while(iter.hasNext()) {
    System.out.println(((User)iter.next()).getName());
  }
   
  session.close();
   
  Session session2 = sessionFactory.openSession();
  Query query2 = session2.createQuery("from User user where name='shun123'");
  Iterator iter2 = query2.iterate();
  while(iter2.hasNext()) {
    System.out.println(((User)iter2.next()).getName());
  }
   
  session2.close();
 
}

  運行后可以看到:

?
1
2
3
4
5
Hibernate: select user0_.USER_ID as col_0_0_ from USER user0_ where user0_.USER_NAME='shun123'
Hibernate: select user0_.USER_ID as USER1_0_0_, user0_.USER_NAME as USER2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=?
shun123
Hibernate: select user0_.USER_ID as col_0_0_ from USER user0_ where user0_.USER_NAME='shun123'
shun123

  我們可以看到它只執(zhí)行了一句搜索,而在第二次查詢時并沒有取出ID進行搜索,這主要歸功于二級緩存。
 
 下面我們先分析一下測試方法中的代碼。測試方法中我們分別打開了兩個Session并且分別創(chuàng)建兩個Query進行相同的查詢。但兩次Session可以共用緩存,這也就是二級緩存,SessionFactory級的緩存。只要我們的Session由同一個SessionFactory創(chuàng)建,那么我們就可以共用二級緩存減少與數(shù)據(jù)庫的交互。
 我們再來看一下配置文件中的意思:

?
1
2
3
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>

  如果我們需要使用二級緩存,首先需要配置:

?
1
<property name="hibernate.cache.use_second_level_cache">true</property>

  進行開戶二級緩存,然后通過:

?
1
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

  指定二級緩存的提供類,一般情況下我們都用ehcache,其他我的暫時沒用到,也不太清楚,所以暫時不講了。
 像我們剛才的例子,我們只需要配置上面兩個,完全可以正常運行,利用二級緩存。
 那么第三句是干什么用的呢?

?
1
<property name="hibernate.cache.use_query_cache">true</property>

  這個配置指明了我們在查詢時需要利用緩存,如果我們需要用到這個要事先調(diào)用query.setCacheable(true)這個方法來進行啟用。
 
 我們一起來看代碼(我們先不啟用緩存):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
 
  Configuration cfg = new Configuration().configure();
  SessionFactory sessionFactory = cfg.buildSessionFactory();
  Session session = sessionFactory.openSession();
 
  Query query = session.createQuery("from User user where name = 'shun123'");
  List list = query.list();
  for (int i = 0; i < list.size(); i++){
    System.out.println(((User)list.get(i)).getName());
  }
   
  session.close();
   
  Session session2 = sessionFactory.openSession();
  Query query2 = session2.createQuery("from User user where name='shun123'");
  List list2 = query2.list();
  for (int i = 0; i < list2.size(); i++){
    System.out.println(((User)list.get(i)).getName());
  }
   
  session2.close();
 
}

  這里輸出的結(jié)果是:

?
1
2
3
4
Hibernate: select user0_.USER_ID as USER1_0_, user0_.USER_NAME as USER2_0_, user0_.age as age0_ from USER user0_ where user0_.USER_NAME='shun123'
shun123
Hibernate: select user0_.USER_ID as USER1_0_, user0_.USER_NAME as USER2_0_, user0_.age as age0_ from USER user0_ where user0_.USER_NAME='shun123'
shun123

  我們看到,它并沒有利用緩存,因為我們這里用了list,而list對緩存是只寫不讀的。所以這里會進行兩次查詢。
 那么我們來修改一下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) {
 
  Configuration cfg = new Configuration().configure();
  SessionFactory sessionFactory = cfg.buildSessionFactory();
  Session session = sessionFactory.openSession();
 
  Query query = session.createQuery("from User user where name = 'shun123'");
  <span style="background-color: #ffffff;"><span style="color: #ff0000;">query.setCacheable(true);</span></span>
  List list = query.list();
  for (int i = 0; i < list.size(); i++){
    System.out.println(((User)list.get(i)).getName());
  }
   
  session.close();
   
  Session session2 = sessionFactory.openSession();
  Query query2 = session2.createQuery("from User user where name='shun123'");
  <span style="color: #ff0000;">query2.setCacheable(true);</span>
  List list2 = query2.list();
  for (int i = 0; i < list2.size(); i++){
    System.out.println(((User)list.get(i)).getName());
  }
   
  session2.close();
 
}

  看到紅色的兩句代碼,這是我們進行添加的兩個開啟查詢緩存的代碼,現(xiàn)在我們看到結(jié)果:

?
1
2
3
Hibernate: select user0_.USER_ID as USER1_0_, user0_.USER_NAME as USER2_0_, user0_.age as age0_ from USER user0_ where user0_.USER_NAME='shun123'
shun123
shun123

  只剩一次查詢了,為什么呢?就在那兩句紅色代碼處,我們開啟了緩存,記住,需要使用兩次。把兩個query都設(shè)成可緩存的才能使用查詢緩存。
 Criteria也是類似的做法,為免有些童鞋忘記了Criteria怎么寫了,我還是放一下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void main(String[] args) {
 
  Configuration cfg = new Configuration().configure();
  SessionFactory sessionFactory = cfg.buildSessionFactory();
  Session session = sessionFactory.openSession();
 
  Criteria criteria1 = session.createCriteria(User.class);
  criteria1.setCacheable(true);
  criteria1.add(Restrictions.eq("name","shun123"));
  List list = criteria1.list();
  for (int i = 0; i < list.size(); i++){
    System.out.println(((User)list.get(i)).getName());
  }
   
  session.close();
   
  Session session2 = sessionFactory.openSession();
  Criteria criteria2 = session2.createCriteria(User.class);
  criteria2.setCacheable(true);
  criteria2.add(Restrictions.eq("name","shun123"));
  List list2 = criteria2.list();
  for (int i = 0; i < list2.size(); i++){
    System.out.println(((User)list.get(i)).getName());
  }
   
  session2.close();
 
}

  我們看結(jié)果:

?
1
2
3
Hibernate: select this_.USER_ID as USER1_0_0_, this_.USER_NAME as USER2_0_0_, this_.age as age0_0_ from USER this_ where this_.USER_NAME=?
shun123
shun123

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一区二区视频在线 | 毛片免费观看 | 日韩一区二区在线观看 | 久久久久久久91 | 不卡一二三区 | 偷拍一区二区三区四区 | 国产精品一二 | 91精品国产日韩91久久久久久 | 欧美一级二级视频 | 亚洲 欧美 国产 制服 动漫 | 一区二区久久 | 在线观看亚洲免费视频 | 在线视频一区二区 | 免费观看黄视频 | 成人精品视频一区二区三区 | 18毛片 | 久草电影在线 | 亚洲一区二区三区 | 中文字幕av在线播放 | 久久国产免费 | 久久久久久久久久久久久久av | 免费看黄色电影 | 日本黄色一级 | 一区二区三区在线免费播放 | 久久亚洲一区二区三区明星换脸 | 午夜影院在线观看 | 91亚洲国产成人久久精品网站 | 欧美日韩一区二区三区免费视频 | 成人久久久久久久久 | 亚洲欧美高清 | 亚洲一区二区三区四区的 | 中文字幕一区二区三区乱码图片 | 在线激情视频 | 日韩欧美视频一区 | 日韩欧美在线观看视频 | 日韩精品日韩激情日韩综合 | 日韩在线 中文字幕 | 99视频精品 | 成人久 | 欧美一级网站 | 欧美日韩激情在线 |