hibernate總結

  1. orm:對象映射

  2. 默認值問題
    在數據庫中,某個表的某個屬性有默認值的情況下。在不用set方法賦值的情況下,默認值不生效爲空。需要改動.cfg.xml中表的屬性。Dynamic-update=”true”
    舉例:

<class name="wyn.hibernate.entity.User" table="user" catalog="book" optimistic-lock="version" dynamic-insert="true">

3 hibernate的一級緩存(session緩存,只支持對象緩存(非list),不支持查詢緩存)
(驗證:(未開啓二級緩存的情況下)先查詢全體成員,再查詢單個成員(如果再次查 詢全體,則執行2次sql語句),最後關閉session。
結果:sql一句只執行一次(查詢全體的),查詢單個成員時,會先從session中查 找(session中已有全部的成員信息),找到之後就不會再從數據庫中尋找。如果 未找到,再從數據庫中查找。)舉例:
未關閉session時:sql語句只執行一次。
舉例:

Query q=session.createQuery("from User");
     List<User> users=q.list();
     System.out.println("一級緩存測試........................"+users.size());
     User user1=(User) session.get(User.class,1);
     System.out.println(user1.getUsername());
     session.close();
關閉session時:sql語句執行2次
Query q=session.createQuery("from User");
     List<User> users=q.list();
     System.out.println("一級緩存測試........................"+users.size());
     session.close();
     session=sf.openSession();
     User user1=(User) session.get(User.class,1);//對象緩存
     System.out.println(user1.getUsername());
     session.close();

session的3種狀態
3.1 臨時(瞬時)狀態(User user=new User(),不被session關聯)
3.2 持久化狀態(調用save或者save0rUpdate方法或者直接調用get方法等,並commit)
持久化狀態session域中的數據是在被提交時更新(即和數據庫中的數據同步),在此之前 連續對某個屬性的更改,並不會全部被變爲sql語句執行,只會執行最後一條更該語句。
數據存放在sesion中,如果不close()掉,則會一直存在,可以直接使用,一直和session 關聯
3.3遊離狀態(在close()之後,不被session關聯)

4 hibernate的延時加載
4.1 Hibernate默認情況下是不會查詢所有外鍵關聯的表的數據的(在從表中設置中lazy屬性爲false就可延時查詢外鍵關聯表的數據)(多對一的情況)
在hbm.xml文件中關聯外鍵的表

<many-to-one name="teacher" class="wyn.hibernate.entity1.Teacher" fetch="select" lazy="false">
<column name="tid" /></many-to-one>
在test(實現類中)的代碼:
public static void main(String [] args){
    Configuration cfg=new Configuration().configure();
    ServiceRegistry sr=new ServiceRegistryBuilder()                 .applySettings(cfg.getProperties()).buildServiceRegistry();  
    //SessionFactory類似數據庫庫的一個Connection  
    SessionFactory sf =cfg.buildSessionFactory(sr);
    Session session=sf.openSession();
    //開啓一個事務
    Transaction t=session.beginTransaction();
    Student s=(Student) session.get(Student.class,1);
    t.commit();
    System.out.println(s.getName());
    session.close();
    System.out.println(s.getTeacher().getName());
    }

4.2 在主表中,實現延時查詢

<set name="students" table="student" inverse="true" lazy="false"        fetch="select">
            <key>
                <column name="tid" />
            </key>
            <one-to-many class="wyn.hibernate.entity1.Student"  />
  </set>

(一對多,此時這個one並沒有layz這個屬性,需要在set屬性中修改,並且在Teacher這個類中會自動生成private Set students = new HashSet(0);)

5 主表和從表
主表(父表)
在數據庫中建立的表格即Table,其中存在主鍵(primary key)用於與其它表相關聯,並且作爲在主表中的唯一性標識。
從表(子表)
以主表的主鍵(primary key)值爲外鍵 (Foreign Key)的表,可以通過外鍵與主表進行關聯查詢。從表與主表通過外鍵進行關聯查詢。
關係及用法概述
從表數據依賴於主表,一般最後查詢數據時把主表與從表進行關聯查詢。

6 hql(hibernate query language) 跨數據庫語言的查詢方式
第一種方式

Query q=session.createQuery("from Student where name='王'");//Student是javabean的類名,而不是數據庫的表名
        List<Student> lists=q.list();
        System.out.println(lists.size());

第二種方式

Student student=new Student();
        student.setChengji(100.0);
        String sql="from Student where 1=1 ";//記得”1=1”後邊留空格
        if(!student.equals("")||student!=null){
            if(student.getChengji()!=null){
                sql+=" and chengji='"+student.getChengji()+"'";
            }//記得’and’之前留空格
            Query q1=session.createQuery(sql);
            List<Student> lists1=q1.list();
            System.out.println(lists1.size());

第三種方式,根據位置綁定數據/根據名稱綁定數據

Query q1=session.createQuery("from Student where chengji=? 
//根據位置
        and kecheng=:a ");//根據名稱
        q1.setDouble(0, 100.0);
        q1.setString("a", "高數");
        List<Student> lists1=q1.list();
        System.out.println(lists1.size());
第四種方式 分頁查詢
Query q1=session.createQuery("from Student where chengji=?  and kecheng=:a ");
        q1.setFirstResult(0);//從查詢結果中的哪一行開始結算
        q1.setMaxResults(8);//從查詢結果中取出多少行結算
        q1.setDouble(0, 100.0);
        q1.setString("a", "高數");
        List<Student> lists1=q1.list();
        for(Student student:lists1){
            System.out.println(student.getName());
        }
        System.out.println(lists1.size());

7 Hbc javabean的查詢方式
Cri.add//後面添加約束條件(就像sql中where條件後的語句)
第一種方式(等值查詢)

Criteria cri=session.createCriteria(Student.class);
        cri.add(Restrictions.eq("kecheng", "高數"));//等值查詢
        List<Student> lists=cri.list();//查詢結過、果被封裝成javabean
        System.out.println(lists.get(1).getName());

第二種方式(模糊查詢)

Criteria cri=session.createCriteria(Student.class);
cri.add(Restrictions.like("kecheng", "高%"));
        List<Student> lists=cri.list();//查詢結過果被封裝成javabean
        System.out.println(lists.size());
        for(Student student:lists){
            System.out.println(student.getName());
        }

第三種方式 between

cri.add(Restrictions.between("id", 0, 10));

第四種方式 in

cri.add(Restrictions.in("kecheng", new String[]{"高數 ","java"}));

第五種方式 組合查詢條件

方法1第五種方式 組合查詢條件

cri.add(Restrictions.like("name", "王%"));
        cri.add(Restrictions.eq("kecheng", "高數"));
方法2
cri.add(Restrictions.and(Restrictions.like("name"," 王%"),Restrictions.eq("kecheng", "高數")));
方法3 
cri.add(Restrictions.or(Restrictions.like("name", "     王%"),Restrictions.eq("kecheng", "java")));
//andor的區別:and滿足所有條件的行,or每一個滿足條件的  行集合
        List<Student> lists=cri.list();//查詢結過果被封裝成javabean
        System.out.println(lists.size());
        for(Student student:lists){
            System.out.println(student.getName());
        }

7 <!--是否將運行期生成的SQL輸出到日誌以供調試-->
<property name="hibernate.show_sql">true</property>

8 hibernate的數據庫連接池
8.1導入jar包(3個c3p0包)
8.2 在hibernate.cfg.xml中配置數據庫連接池必要的配置

<!--****************** 【連接池配置】****************** -->
        <!-- 配置連接驅動管理類 -->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionPro<!--是否將運行期生成的SQL輸出到日誌以供調試-->
vider</property>
        <!-- 配置連接池參數信息 -->
        <!-- 連接池中數據庫連接的最小數目 -->
        <property name="hibernate.c3p0.min_size">2</property>
        <!--連接池中數據庫連接的最大數目? -->
        <property name="hibernate.c3p0.max_size">4</property>
        <!-- 獲得連接的超時時間,如果超過這個時間,會拋出異常,單位毫秒 --> 
        <property name="hibernate.c3p0.timeout">5000</property>
        <!-- 可以被緩存的PreparedStatement實例的最大數目。
        緩存適量的PreparedStatement實例,能夠大大提高Hibernate的性能。 -->
        <property name="hibernate.c3p0.max_statements">10</property>
        <!-- 在使數據庫連接自動生效之前處於空閒狀態的時間,以秒爲單位 -->
        <property name="hibernate.c3p0.idle_test_period">30000</property>
        <!-- 當連接池裏面的連接用完的時候,C3P0一下獲取的新的連接數 --> 
        <property name="hibernate.c3p0.acquire_increment">2</property>

9 hibernate二級緩存(sessionFactory緩存,支持可插拔式的緩存,支持查詢緩存)
9.1 導二級緩存需要的jar包(3個ehcache包)
9.2 在hibernate.cfg.xml文件中配置開啓二級緩存的語句

<!--****************** 【二級緩存配置】****************** -->
        <!-- 開啓二級緩存 -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!-- 開啓查詢緩存 -->
        <property name="hibernate.cache.use_query_cache">true</property> 
        <!-- 二級緩存的提供類 在hibernate4.0版本以後我們都是配置這個屬性來指定二級緩存的提供類-->
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        <!-- 二級緩存配置文件的位置 -->
        <property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>

9.3 在數據庫中對象的映射xml文件中配置語句

<!-- 配置二級緩存開啓的條件 -->
        <cache usage="read-write"/> 

9.4 在調用sql語句的後面開啓二級緩存

 Query q=session.createQuery("from User").setCacheable(true);
     List<User> users=q.list();
     System.out.println("一級緩存測試........................"+users.size());
     session.close();
     session=sf.openSession();
     Query q2=session.createQuery("from User").setCacheable(true);
//開啓自己的二級緩存,從上面語句的二級緩存中查詢值
     List<User> users1=q2.list();
     System.out.println("一級緩存測試2........................"+users1.size());
     /*User user1=(User) session.get(User.class,1);
     System.out.println(user1.getUsername());*/
     session.close();

10 當hibernate通過id訪問數據庫對象的時候,先從session中查找,然後從二級緩存中查找,再從數據庫中查找

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章