<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    風雨無阻

    hibernate二級緩存的實現

    于Hibernate這類ORM而言,的尤重要,是持久性能提升的關鍵.簡單來講Hibernate就是JDBC行封裝,以實現內狀態的管理,OR系的映射等,但帶來的就是訪問效率的降低,和性能的下降,而存就是彌補這一缺點的重要方法.

        
    存就是庫數據在存中的臨時容器,包括庫數據在存中的臨時,位于庫與數庫訪問層.ORM查詢數首先根據自身的存管理策略,在存中找相關數據,如發現所需的據,直接據作為結果加以利用,而避免了庫調用性能的開銷.而相對內存操作而言,庫調用是一代價高程.

        一般
    來講ORM中的存分以下幾:

            1.
    務級緩存:即在前事圍內存.就Hibernate來講,務級緩存是基于Session的生命周期實現的,每Session存在一個數存,它隨著Session的建而存在,著Session的毀而亡,因此也稱為Session Level Cache.

            2.
    級緩存:即在某個應用中或用中某個獨庫訪問子集中的共享存,此存可由多共享(用事),存共享策略與應用的事隔離機制密切相.在Hibernate中,級緩存由SessionFactory實現,所有由一SessionFactory建的Session例共享此存,因此也稱為SessionFactory Level Cache.

            3.
    分布式存:即在多個應例,多JVM共享的存策略.分布式存由多個應級緩成,通種遠程機制(RMI,JMS)實現個緩據同步,任何一個實例的據修改,將導致整集群狀態同步.

        Hibernate
    存:

            1.
    存(Session Level Cache也級緩存):

            
    明:

    java 代

    public class Test {    
      
          public void get(){    
      
                Session session = HibernateSessionFactory.getSession();    
                TUser t = (TUser)session.get("hibernate.TUser", 2);    
                System.out.println(t.getName());    
                session.close();    
                }    
      
    }    
      

                
    測試:在控制臺打印出一SQL句:Hibernate: select tuser0_.id as id0_0_, tuser0_.name as name0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=? 行了一次調用.

          代
    更改如下:

    public class Test {    
        
          public void get(){    
      
                Session session = HibernateSessionFactory.getSession();    
                TUser t = (TUser)session.get("hibernate.TUser", 2);    
                System.out.println(t.getName());    
                TUser tt = (TUser)session.get("hibernate.TUser", 2);    
                System.out.println(tt.getName());    
                session.close();    
      
          }    
      
    }    
      

           再
    測試:行了查詢,控制臺仍然只打出一SQL句:Hibernate: select tuser0_.id as id0_0_, tuser0_.name as name0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=?  是只行了一次調用.

           再
    更改如下:

    public class Test {    
        
          public void get(){    
      
                Session session = HibernateSessionFactory.getSession();    
                TUser t = (TUser)session.get("hibernate.TUser", 2);    
                System.out.println(t.getName());    
                session.close();    
                Session session1 = HibernateSessionFactory.getSession();    
                TUser tt = (TUser)session1.get("hibernate.TUser", 2);    
                System.out.println(tt.getName());    
                session1.close();    
      
          }    
      
    }    

          
    繼續測試:查詢控制臺打印兩條SQL句:Hibernate: select tuser0_.id as id0_0_, tuser0_.name as name0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=?
    Hibernate: select tuser0_.id as id0_0_, tuser0_.name as name0_0_, tuser0_.sex as sex0_0_ from test.t_user tuser0_ where tuser0_.id=?

          
    結論:Hibernate查詢時總是先在存中查詢,存中有所需據才查詢.Hibernate存是基于Session的生命周期的,也就是存在于每Session部,它隨著Session的建而存在,著Session的毀而亡,存一般由Hibernate自動維護,不需要人,然我也可以根據需要行相操作:Session.evict(Object)(指定從內除),Session.clear()(存).(如在查詢間加入Session.clear()將會清存,使得一Sesion部的次相同的查詢對數庫進次操作).

          2.二
    級緩存:(有時稱為SessionFactory Level Cache)

          Hibernate
    本身未提供二級緩存的品化實現(只提供了一基于HashTable的簡單緩存以供調試),里我使用的是第三方件:EHcache.Hibernate的二級緩實現需要行以下配置(Hibernate3):

          首先在hibernate.cfg.xml
    添加:



    <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  
    <property name="hibernate.cache.use_query_cache">true</property>  

    然后在映射文件中添加:
    <cache usage="read-only"/>  

                
    測試上面代:控制臺出多了這樣一句[ WARN] (CacheFactory.java:43) - read-only cache configured for mutable class: hibernate.TUser,二級緩用成功!!      

    java 代

    public class Test {    
        
          public void executeQuery(){    
          
                List list = new ArrayList();    
                Session session = HibernateSessionFactory.getSession();    
                Query query = session.createQuery("from TUser t");    
                query.setCacheable(true);//
    激活查詢緩存    
                list = query.list();    
                session.close();    
      
          }    
          public void get(){    
      
                Session session = HibernateSessionFactory.getSession();    
                TUser t = (TUser)session.get("hibernate.TUser", 2);    
                System.out.println(t.getName());    
                session.close();    
      
         }    
      
    }    

          
    測試:控制臺只出一SQL句:Hibernate: select tuser0_.id as id0_, tuser0_.name as name0_, tuser0_.sex as sex0_ from test.t_user tuser0_(即Query query = session.createQuery("from TUser t")句代對應的SQL).  executeQuery()方法get()方法使用的是不同的Session!!可是executeQuery()方法get()方法只對數庫進行了一次操作,就是二級緩存在起作用了.  

          
    結論:Hibernate級緩存是SessionFactory存,Session共享,使用需要使用第三方的件,新版HibernateEHcache的二級緩實現.

          
    存同步策略:存同步策略定了象在存中的存取規則,須為個實指定相存同步策略.Hibernate中提供了4不同的存同步策略:(暫時記個概)

          1.read-only:
    .于不會發生改據可使用(對數據只能查詢,其他的增刪改都會報錯不關是1或2緩存中.

          2.nonstrict-read-write:
    如果程序對并發訪問下的據同步要求不格,且據更新低,采用本存同步策略可好性能.(不能在二級緩存進行增刪改都會報錯)

          3.read-write:
    格的讀寫緩存.基于時間戳判定機制,實現了"read committed"事隔離等.用于對數據同步要求的情,但不支持分布式存,實際應用中使用最多的存同步策略.(都可以比較常用的)

          4.transactional:
    存,必須運行在JTA事務環境中.此存中,存的相操作被添加到事中(此似于一個內),如事,則緩沖池的一同回到事始之前的狀態.實現了"Repeatable read"事隔離等,有效保據的合法性,適對關鍵數據的存,Hibernate存中,只有JBossCache支持事存.


    create table teamEH (id varchar(32),teamname varchar(32));

    create table studentEH (id varchar(32),name varchar(32),team_id varchar(32));

    POJO:

     

    package EHCache;

    public class Student ...{

        private String id; //標識id

        private String name; //學生姓名

        private Team team;//班級

        public String getName() ...{

            return name;

        }

       

        public void setId(String id) ...{

            this.id = id;

        }

       

        public void setName(String stuName) ...{

            this.name = stuName;

        }

      

        public String getId() ...{

            return id;

        }

        public Student() ...{ //無參的構造函數

        }

       

        public Team getTeam() ...{

            return team;

        }

        public void setTeam(Team team) ...{

            this.team = team;

        }

    }

    package EHCache;

    import java.util.HashSet;

    import java.util.Set;

    public class Team ...{

        private String id;

        private Set students;

        private String teamName;

        public String getId() ...{

            return id;

        }

        public void setId(String id) ...{

            this.id = id;

        }

        public String getTeamName() ...{

            return teamName;

        }

        public void setTeamName(String name) ...{

            this.teamName = name;

        }

        public Set getStudents() ...{

            return students;

        }

        public void setStudents(Set students) ...{

            this.students = students;

        }

    }

     Team.hbm.xml

    其中<cache>標簽表示對student集合緩存,但只緩存id,如果需要緩存student實例,則需要在student.hbm.xml中的

    class標簽中配置<cache>

     

    <?xml version="1.0" encoding="utf-8"?>

    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    <!-- 

        Mapping file autogenerated by MyEclipse - Hibernate Tools

    -->

    <hibernate-mapping package="EHCache" >

        <class name="EHCache.Team" table="teamEH" lazy="false">

           <id name="id" column="id">

             <generator class="uuid.hex"></generator>

           </id>

           <property name="teamName" column="teamName"></property>

           

           <set name="students" 

                lazy="true" 

                inverse="true" 

                outer-join="false"

                batch-size="2"

                cascade="save-update"

               >

               <!-- 對students集合緩存,但只是緩存student-id如果要對整個對象緩存,

                    還需要在Student.hbm.xml的class標簽中加入<cache>標簽 -->

             <cache usage="read-write"/>

             <key column="team_id"></key>

             <one-to-many class="EHCache.Student"/>

           </set>

          </class>

    </hibernate-mapping>

     

    Student.hbm.xml

     

    <?xml version="1.0" encoding="utf-8"?>

    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    <!-- 

        Mapping file autogenerated by MyEclipse - Hibernate Tools

    -->

    <hibernate-mapping package="EHCache" >

       

        <class name="EHCache.Student" table="studentEH" lazy="false">

           <cache usage="read-write"/>

           <id name="id" column="id" unsaved-value="null">

             <generator class="uuid.hex"></generator>

           </id>

           <property name="name" column="name"></property>

        

           <many-to-one name="team" 

                        column="team_id"

                        outer-join="true" 

                        cascade="save-update"

                        class="EHCache.Team"></many-to-one>

          </class>

    </hibernate-mapping>

     

    Hibernate.cfg.xml

    配置hibernate.cache.provider_class以啟用EHCache

    <?xml version='1.0' encoding='UTF-8'?>

    <!DOCTYPE hibernate-configuration PUBLIC

              "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

              "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

    <!-- Generated by MyEclipse Hibernate Tools.                   -->

    <hibernate-configuration>

    <session-factory>

        <property name="connection.username">root</property>

        <property name="connection.url">

            jdbc:mysql://localhost:3306/schoolproject?characterEncoding=gb2312&amp;useUnicode=true

        </property>

        <property name="dialect">

            org.hibernate.dialect.MySQLDialect

        </property>

        <property name="myeclipse.connection.profile">mysql</property>

        <property name="connection.password">1234</property>

        <property name="connection.driver_class">

            com.mysql.jdbc.Driver

        </property>

        <property name="hibernate.dialect">

            org.hibernate.dialect.MySQLDialect

        </property>

        <property name="hibernate.show_sql">true</property>

        <property name="current_session_context_class">thread</property>

        <property name="hibernate.cache.provider_class">

                org.hibernate.cache.EhCacheProvider

            </property>

        <mapping resource="EHCache/Student.hbm.xml" />

        <mapping resource="EHCache/Team.hbm.xml" />

    </session-factory>

    </hibernate-configuration>

    EHCache.xml(放在classpath下)

     

    <ehcache>

     

        <diskStore path="c:\cache"/>  <!--緩存文件存放位置-->

        <defaultCache

            maxElementsInMemory="10000"

            eternal="false"

            timeToIdleSeconds="120"

            timeToLiveSeconds="120"

            overflowToDisk="true"

            />

        <cache name="EHCache.Student"

            maxElementsInMemory="500"    <!---超過500實例,就將多出的部分放置緩存文件中->

            eternal="false"

            timeToIdleSeconds="120"

            timeToLiveSeconds="120"

            overflowToDisk="true"

            /> -->

        <!-- Place configuration for your caches following -->

    </ehcache>

     

    測試代碼(插入準備數據部分)

     

    package EHCache;

    import java.io.File;

    import java.util.List;

    import org.hibernate.Session;

    import org.hibernate.SessionFactory;

    import org.hibernate.Transaction;

    import org.hibernate.cfg.Configuration;

    public class Test ...{

        public static void main(String[] args) ...{

            String filePath=System.getProperty("user.dir")+File.separator+"src/EHCache"+File.separator+"hibernate.cfg.xml";

            File file=new File(filePath);

            SessionFactory sessionFactory=new Configuration().configure(file).buildSessionFactory();

            Session session=sessionFactory.openSession();

            Transaction tx=session.beginTransaction();

            

    //        Team team=new Team();

    //        team.setTeamName("team1");

    //        

    //        

    //        for(int i=0;i<1000;i++){

    //            Student stu=new Student();

    //            stu.setName("tom"+i);

    //            stu.setTeam(team);

    //            session.save(stu);

    //        }

    //        tx.commit();

    //        

        }

    }

     

    測試成功后,運行以下代碼

     

    package EHCache;

    import java.io.File;

    import java.util.List;

    import org.hibernate.Session;

    import org.hibernate.SessionFactory;

    import org.hibernate.Transaction;

    import org.hibernate.cfg.Configuration;

    public class Test ...{

        public static void main(String[] args) ...{

            String filePath=System.getProperty("user.dir")+File.separator+"src/EHCache"+File.separator+"hibernate.cfg.xml";

            File file=new File(filePath);

            SessionFactory sessionFactory=new Configuration().configure(file).buildSessionFactory();

            Session session=sessionFactory.openSession();

            Transaction tx=session.beginTransaction();

            

        

            //模擬多用戶訪問數據

            Session session1=sessionFactory.openSession();

            Transaction tx1=session1.beginTransaction();

            List list=session1.createQuery("from Student").list();

            for(int i=0;i<list.size();i++)...{

                Student stu=(Student)list.get(i);

                System.out.println(stu.getName());

            }

            tx1.commit();

            session1.close();    

        

            Session session2=sessionFactory.openSession();

            Transaction tx2=session2.beginTransaction();

                //這個uuid從剛才插入的數據中復制一個student的id

            Student stu=(Student)session2.get(Student.class, "4028818316d184820116d184900e0001");

            System.out.println(stu.getName());

            tx2.commit();

            session2.close();

        }

    }

     

    結果如下:

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).

    log4j:WARN Please initialize the log4j system properly.

    Hibernate: select student0_.id as id0_, student0_.name as name0_, student0_.team_id as team3_0_ from studentEH student0_

    Hibernate: select team0_.id as id1_0_, team0_.teamName as teamName1_0_ from teamEH team0_ where team0_.id=?

    tom0

    tom1

    tom2

    tom3

    tom4

    tom5

    tom6

    tom7

    tom8

    tom9

    tom10

    ........................................

    tom974

    tom975

    tom976

    tom977

    tom978

    tom998

    tom999

    Hibernate: select team0_.id as id1_0_, team0_.teamName as teamName1_0_ from teamEH team0_ where team0_.id=?

    tom0

     

    可以看到,第二次查詢,已經不再訪問數據庫了,而且,查看c:\cache文件夾,也可以看到,數據已經緩存成功了

    posted on 2008-04-16 18:17 秋楓故事 閱讀(1760) 評論(1)  編輯  收藏

    評論

    # re: hibernate二級緩存的實現 2009-09-15 17:56 jack.lxh@gmail.com

    您好文章中的說明 的hiberate 一級緩存與二級緩存的交互,我之前就知道,但是如果在一個web應用中 這個進程級別與 application 范圍有什么區別  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2008年4月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    導航

    統計

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    新聞檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 免费中文字幕不卡视频| 亚洲色偷偷综合亚洲AV伊人蜜桃| 一级黄色免费大片| 日本免费电影一区| 精品久久亚洲中文无码| 中文字幕在线观看免费视频| 亚洲精品国产美女久久久| www成人免费观看网站| 亚洲av手机在线观看| 亚洲av成人一区二区三区观看在线 | 久久久久亚洲AV成人无码| a毛片免费播放全部完整| 久久夜色精品国产亚洲av| 黄网站色视频免费观看45分钟| 日本无吗免费一二区| 亚洲精品无码一区二区| 成人黄动漫画免费网站视频 | 色拍自拍亚洲综合图区| 国内精品一级毛片免费看| 亚洲日韩中文无码久久| 丁香花在线观看免费观看图片| 亚洲无线一二三四区手机| 一区二区免费在线观看| 亚洲国产一区二区三区| 三年片在线观看免费观看大全中国 | 精品在线观看免费| 国产不卡免费视频| 精品免费AV一区二区三区| 国产亚洲福利一区二区免费看| 国产天堂亚洲精品| 免费在线不卡视频| 一级大黄美女免费播放| 国产中文在线亚洲精品官网| 成人毛片100免费观看| 亚洲成AV人片在线播放无码| 国产精品白浆在线观看免费| 337p欧洲亚洲大胆艺术| 青青青国产在线观看免费网站| 99热亚洲色精品国产88| 最好免费观看韩国+日本| 国产成人亚洲精品91专区高清|