Hibernate基本知識(三)

1、 對象的狀態

<1>瞬時對象是new出來的,與Session和數據庫都無關;

<2>持久對象是放入Session中,與Session有關的,Hibernate可以檢測到,更新對象的值,可以影響到數據庫中的值;

<3>脫管對象是在存入數據庫,session關閉的時候由持久對象變換過來的,因此它只與數據庫有關,因此Hibernate檢測不到,數據庫要更新需要更新語句update。

<4>Hibernate只能檢測到Session中的對象變化情況。

<5>當不知道對象是瞬時的還是脫管的,如果要保存或更新數據庫中的值,這個時候就需要用到saveOrUpdate(),讓Hibernate去判斷該對象是什麼狀態。

2、 HQLCriteria

 

    <1>HQL查詢(官方推薦)

String hql = "from User as user where user.name=?";

    Query query = session.createQuery(hql);

    query.setString(0, name);

    List<User> list = query.list();      //如果有多條記錄,用list

    User u = (User)query.uniqueResult();//確定查到結果集只有一條記錄錄時使用

   

    對於上面的hql語句,我們可以這樣寫(爲name取別名):

    String hql = "from User as user where user.name=:n";

    query.setString(“n”, name);

 

    Hibernate中的分頁可以用以下語句:

    query.setFirstResult(100);   //從哪一條開始查詢

    query.setMaxResults(20);    //每頁顯示多少條

    <2>Criteria條件查詢(比較常用,功能有限)

    Criteria c = session.createCriteria(User.class);

    c.add(Restrictions.eq(“name”,name));     //從數據庫中查出等於name數據

    c.add(Restrictions.lt(“birthday”,new Date());//查出小於birthday數據

    分頁語句:

c.setFirstResult(0);   //從哪一條開始查詢

    c.setMaxResults(10);   //每頁顯示多少條

    List<User> list = c.list();       //如果有多條記錄,用list

    User u = (User)c.uniqueResult();//確定查到的結果集只有一條記錄時使用

 

<3>、外置命名查詢(很少用)

在實體映射文件的<class>標籤後加上如下配置:

<!-- 外置命名查詢(例子:TestOutName) -->

    <!--

    <query name="queryUser">

       <![CDATA[from User u where u.id>?]]>

    </query>

調用時如下:

Session session = HibernateUtil.getSession();

       Query query = null;

       session.beginTransaction();

       query = session.getNamedQuery("queryUser");

       List<User> urs = query.setParameter(0, 5).list();

       for(User u : urs) {

           System.out.println("id:"+u.getId()+" name:"+u.getName()+"   createTime:"+u.getCreateTime());

       session.getTransaction().commit();

 

<4>、過濾器(很少用)

過濾器配置如下:

<class>標籤中加入如下代碼:

<filter name="idFilter" condition="id &gt;:uid"></filter>

<class>標籤外加入如下代碼:

<filter-def name="idFilter">

    <filter-param name="uid" type="integer"/>

</filter-def>

例子代碼:

session.beginTransaction();

session.enableFilter("idFilter").setParameter("uid", 4);

query = session.createQuery(“from User”);

List<User> urs = query.list();

for(User u : urs) {

System.out.println("id:"+u.getId()+"   name:"+u.getName()+"   createTime:"+u.getCreateTime());

    }

session.getTransaction().commit();

<5>內、外連接問題

內連接

內連接就是滿足Document中的uid等於User的id時,將兩個表的數據連接成類似一張表信息的過程。

from Document d inner join d.user on d.uid=d.user.id

l  外連接

外連接分爲左外連、右外連和全外連。

外連接是將兩個表的信息都一一對應後進行連接,得到結果行數可能是兩錶行數的乘積。下面兩個HQL語句功能相同。

select * from User u,Document d where u.id=d.user.id

select * from User u outter join Document d on u.id = d.user.id

<6>、聚合函數和子查詢

在HQL*只能出現在count(*)中。

select d.user.name, count(*) from Document d group by d.user having count(*)>1 order by d.user.id";

 

<7>、Iterator查詢與N+1問題

Session session = HibernateUtil.getSession();

       Query query = null;

       try {

           session.beginTransaction();

           query = session.createQuery("from User u where u.id>=4 and u.id<=6");

           List<User> urs = query.list();

           for(User u : urs) {

              System.out.println("id:"+u.getId()+"   name:"+u.getName()+"   createTime:"+u.getCreateTime());

           }

    //上面通過List查詢過的那些User將會在緩存中存在,當下面的Iterator再查詢的時候,它會先從數據庫查出所有User的ID,然後再用ID從緩存中找,如果緩存中有的話,就從緩存中取,不用向數據庫發select語句。

    System.out.println("======================================");

           query = session.createQuery("from User");

           Iterator<User> iter = query.iterate();

           while(iter.hasNext()) {

              User u = iter.next();

              System.out.println("id:"+u.getId()+"   name:"+u.getName()+"   createTime:"+u.getCreateTime());

           }

           session.getTransaction().commit();

       } catch (HibernateException e) {

           session.getTransaction().rollback();

           e.printStackTrace();

       } finally {

           HibernateUtil.closeSession();

       }

    <8>、導航查詢

    給個例子如下:(利用本對象中另外對象的屬性條件來查詢本對象的信息)

String hql = "from Document d where d.user.name=?";

       Session session = HibernateUtil.getSession();

       Query query = null;

       session.beginTransaction();

       query = session.createQuery(hql);

       query.setParameter(0, "user5");

       List<Document> ds = query.list();

       for(Document d : ds) {

           System.out.println("id:"+d.getId()+"   title:"+d.getTitle()+"    content:"+d.getContent()+createTime:"+d.getCreateTime());

    <9>、HQL中的DML(很少用)

    hql的DML語句不受緩存管理,所以很少使用

示例代碼:

3、 HibernateCURD的模板代碼如下:

4、 Hibernate中對象狀態圖

flush()可以清除臨時緩存,以保證執行的順序。

evict()可以將對象從緩存中剔除,使其從持久態變爲脫管態。

clear()可以將緩存中的所有對象剔除。

lock()可以爲某對象加鎖機制。

發佈了32 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章