首頁  >  文章  >  类库下载  >  Hibernate總結

Hibernate總結

高洛峰
高洛峰原創
2016-10-31 14:24:171505瀏覽

Hibernate為了提高效能,提供了快取與快照機制。

它的快取分為一級快取與二級快取。

Hibernate一級快取:當一個事務中執行一次Sql語句時,就將傳回的結果儲存在Session中的Map集合中(當然,還有快照)。

測試:(以下所有程式碼處於try/catch區塊中)

Configuration config=new Configuration().configure();//configure()方法是加载src/hibernate.cfg.xml配置文件
        SessionFactory sf=config.buildSessionFactory();
        Session s=sf.openSession();//Session是高一级的对Connection的封装
        Transaction tran=null;
        try {
            tran=s.beginTransaction();
            
            //代码在此

            tran.commit();
        } catch (HibernateException e) {
            if(tran!=null){
                tran.rollback();
            }
            e.printStackTrace();
        } finally{
            s.close();
            sf.close();
        }

查詢:包含get(),load(),原生Sql,HQL,Criteria(比HQL更物件導向的查詢方式)

//1.get(),load()方法测试
            User u=(User) s.get(User.class, 1);//第一次查询生成SQL语句,并将结果放入缓存
            User u1=(User) s.get(User.class, 1);//第二次查询并无生成SQL语句,但结果取自缓存
            p(u==u1);//true

            //2.HQL查询
            Query q=s.createQuery("from domain.User where id=1");
            User u2=(User) q.uniqueResult();//第三次查询生成了SQL语句,但结果取自缓存
            p(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语句,但结果取自缓存
            p(u3==u);//true

            //4.Criteria查询
            Criteria c=s.createCriteria(User.class);
            c.add(Restrictions.eq("id", 1));
            User u4=(User) q1.uniqueResult();//第五次查询生成了SQL语句,但结果取自缓存
            p(u4==u);//true

總結查詢:

Hibernate總結

增加:save(),persist()

            User user = new User();//对象的瞬态
                user.setName("xiaobai");
                user.setAge(121);
                s.save(user);//对象的持久态
          s.persist(user);

這裡兩個方法的差別是:執行方法之前設定主鍵問題與執行方法之後傳回主鍵問題。

1,persist(),把一個瞬態的實例持久化,但是並"不保證"標識符(identifier主鍵對應的屬性)被立刻填入到持久化實例中,標識符的填入可能被推遲到flush的時候。

2,save(), 把一個瞬態的實例持久化標識符,及時的產生,它要返回標識符,所以它會立即執行Sql insert。

User u = new User();
                u.setName("xiaobai");
                u.setAge(121);
                s.save(u);//插入数据库,并将对象瞬态转为持久态,将返回对象存入缓存
                User u1=(User) s.get(User.class, u.getId());//这次查询没有生成SQL语句,结果取自Session的缓存
                p(u1==u);//true

刪除:delete()

User u=(User) s.get(User.class, 10);//執行查詢操作
s.delete(u);//將物件持久性轉為遊離態

當然,如果感覺為了刪除一個數據,還的執行查詢操作降低性能,可以這樣:

User u=new User();
u.setId(5);
s.delete(u);

更新:update()

User u=(User) s.get(User.class, 1);
u.setName("set");

但有時候,我們不需要執行s.update(對象)方法,這涉及到對象的持久態一個特性(也有【快照】作用其中):

當對象為持久態時,當它更新數據時,框架會拿它與之前的快照作比較,若相同,則無動作;若不同,則自動更新至資料庫。

//当然,也可以这么做
User u=new User();//对象的瞬态,不具备自动更新功能,需要我们手动update()
u.setAge(1);
u.setId(1);
u.setName("1");
s.update(u);

總結:

有一點非常重要:在事務中雖然形成了Sql語句,但只有事務.commit()之後才會真正操作資料庫。

Hibernate關於資料庫的操作,需要弄清楚【緩存,快照,物件三態】等等些許東西。

物件三態:

* 瞬時態:和hibernate沒關聯,在資料庫表中沒有對應的id
* 持久態:和hibernate有關聯,在資料庫表中有對應的id---OID
* 遊離態:和hibernate沒關聯,在資料庫表中有對應的id


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn