Spring Data MongoDB 五:進階文檔查詢(分頁、Morphia)(二)

來源:互聯網
上載者:User

標籤:mongodb   spring data mongodb   spring   

    Spring Data MongoDB 三:基本文檔查詢(Query、BasicQuery)(一)

    學習MongoDB 六: MongoDB查詢(遊標操作、遊標資訊)(三)

     

一.簡介

 

     SpringData  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate對MongoDB的find的操作,我們上一篇介紹了基本文檔的查詢,我們今天介紹分頁查詢,分頁查詢是返回到匹配文檔的遊標,可以隨意修改查詢限制、跳躍、和排序次序的功能。

     我們在查詢時find()方法接受Query類型有org.springframework.data.mongodb.core.query和org.springframework.data.mongodb.core.query.BasicQuery

     Query類提供方法有limit、skip、sort查詢限制、跳躍、和排序次序的功能,BasicQuery繼承了Query類。

 

Query

Mongodb

說明

Query limit (int limit)

limit

方法是限制遊標返回結果的數量

Query skip (int skip)

skip

方法可以跳過指定值的條數,返回剩下的條數的結果,可以跟limit()方法進行組合可以實現分頁的效果

Sort sort () 已淘汰

現在是用query.with(sort)

sort

方法來對資料進行排序,根據指定的欄位,並使用1或-1來指定排序方式是升序或降序,類似於SQL的order by。

 

二.基本分頁

 

    Query類提供方法有limit、skip、sort查詢限制、跳躍、和排序次序的功能,我們實現Query查詢分頁

 

     第一步:實現分頁工具類

/** * 分頁 * @author zhengcy * * @param<T> */public classPageModel<T>{    //結果集    privateList<T> datas;    //查詢記錄數    privateintrowCount;    //每頁多少條資料    privateintpageSize=20;   //第幾頁    privateintpageNo=1;   //跳過幾條數   privateintskip=0;    /**     * 總頁數     * @return     */    publicintgetTotalPages(){         return(rowCount+pageSize-1)/pageSize;    }      public List<T>getDatas() {      return datas;   }   public void setDatas(List<T>datas) {      this.datas = datas;   }   public int getRowCount() {      return rowCount;   }   public void setRowCount(int rowCount) {      this.rowCount = rowCount;   }   public int getPageSize() {      return pageSize;   }   public void setPageSize(int pageSize) {      this.pageSize = pageSize;   }   public int getSkip() {      skip=(pageNo-1)*pageSize;      return skip;   }   public void setSkip(int skip) {      this.skip = skip;   }    public int getPageNo() {      return pageNo;   }    public void setPageNo(int pageNo) {      this.pageNo = pageNo;   }         }


   第二步:實現分頁

       

   @Override   public PageModel<Orders>getOrders(PageModel<Orders> page, DBObject queryObject,StringcollectionName) {      Queryquery=newBasicQuery(queryObject);      //查詢總數      int count=(int) mongoTemplate.count(query,Orders.class);      page.setRowCount(count);           //排序         query.with(new Sort(Direction.ASC, "onumber"));        query.skip(page.getSkip()).limit(page.getPageSize());      List<Orders>datas=mongoTemplate.find(query,Orders.class);      page.setDatas(datas);      return page;   }


說明:

   Sort :sort () 已淘汰,現在是用query.with(sort),with參數是sort類

   Sort提供了幾種建構函式

      

   方法的描述

      (1)一個欄位的排序

          例如onumber欄位升序

        query.with(new Sort(Direction.ASC,"onumber"));


     (2)如果是多個欄位時同時升序或者降序時

       //排序

        query.with(new Sort(Direction.ASC,"a","b","c"));

 

   (3)不同的欄位按照不同的排序

       List<Sort.Order>orders=new ArrayList<Sort.Order>();       orders.add(newSort.Order(Direction.ASC, "a"));       orders.add(newSort.Order(Direction.DESC, "b"));       query.with(newSort(orders ));

          a升序在按b降序


   第三步:測試類別

        

       @Test      public void testList() throws ParseException      {        PageModel<Orders>page=newPageModel<Orders>();        page.setPageNo(1);        page=ordersDao.getOrders(page, new BasicDBObject("cname","zcy"),collectionName);        System.out.println("總數:"+page.getRowCount());        System.out.println("返回條數:"+page.getDatas().size());        System.out.println(JSONArray.fromObject(page.getDatas()));      }

 

   查詢條件是cname=zcy

            

        

      skip方法是跳過條數,而且是一條一條的跳過,如果集合比較大時(如書頁數很多)skip會越來越慢, 需要更多的處理器(CPU),這會影響效能。

三、進階的查詢分頁

 

      返回到匹配文檔的遊標,可以隨意修改查詢限制、跳躍、和排序次序的功能,我們這邊對指標返回的結果,我用到Morphia架構。

       Morphia是一個開放原始碼的對象關係映射架構,它對MongoDB資料庫 java版驅動進行了非常輕量級的對象封裝。我們需要通過DBCurosr擷取的DBObject轉換成我們對應的實體物件,方便我們操作實體。

     DBCurosr 是 DBCollection 的 find 方法返回的對象,可以設定 skip、limit 、sot等屬性執行分頁查詢

 

   第一步:在實體id要註解@id

      importcom.google.code.morphia.annotations.Id;

           @Id

         privateString id;

 

     @Id 注釋指示Morphia哪個欄位用作文檔 ID

 

     如果沒加的話,會出現這樣的錯誤

    ...27 more

Caused by: com.google.code.morphia.mapping.validation.ConstraintViolationException: Number of violations: 1

NoId complained aboutcom.mongo.model.Orders. : No field is annotated with @Id; but it is required

    atcom.google.code.morphia.mapping.validation.MappingValidator.validate(MappingValidator.java:66)

    atcom.google.code.morphia.mapping.validation.MappingValidator.validate(MappingValidator.java:155)

    atcom.google.code.morphia.mapping.MappedClass.validate(MappedClass.java:259)

    atcom.google.code.morphia.mapping.Mapper.addMappedClass(Mapper.java:154)

    atcom.google.code.morphia.mapping.Mapper.addMappedClass(Mapper.java:142)

    atcom.google.code.morphia.Morphia.map(Morphia.java:55)

    atcom.mongo.dao.impl.OrdersDaoImpl.<init>(OrdersDaoImpl.java:37)

    atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    atsun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

    atsun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

    atjava.lang.reflect.Constructor.newInstance(Unknown Source)

    atorg.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)

    ... 29more

 

 

  第二步:實現:

   privateMorphia  morphia;     public OrdersDaoImpl(){      morphia= new Morphia();      morphia.map(Orders.class);   }   @Override   public PageModel<Orders>getOrders(PageModel<Orders> page, DBObject queryObject,StringcollectionName) {       DBObjectfilterDBObject=newBasicDBObject();      filterDBObject.put("_id", 0);      filterDBObject.put("cname",1);      filterDBObject.put("onumber",1);             DBCursordbCursor=mongoTemplate.getCollection(collectionName).find(queryObject,filterDBObject);           //排序      DBObjectsortDBObject=newBasicDBObject();      sortDBObject.put("onumber",1);      dbCursor.sort(sortDBObject);      //分頁查詢      dbCursor.skip(page.getSkip()).limit(page.getPageSize());           //總數      int count=dbCursor.count();      //迴圈指標      List<Orders>datas=newArrayList<Orders>();      while (dbCursor.hasNext()) {        datas.add(morphia.fromDBObject(Orders.class, dbCursor.next()));      }           page.setRowCount(count);      page.setDatas(datas);      return page;}

   我們開始執行DAO時,先初始化Morphia,並往裡面添加我們需要轉換的實體類CLASS

      morphia=new Morphia();

      morphia.map(Orders.class);

      

   dbCursor.hasNext()判斷是否還有下一個文檔(DBObject),  dbCursor.Next()擷取DBObject時,我們通過Morphia把DBObject對應的實體類。

  查詢時通過filterDBObject 設定返回需要的欄位

     

 

      MongoDB伺服器返回的查詢結果,當調用cursor.hasNext()時,MongoDB批量的大小不會超過最大BSON文檔大小,然而對於大多數查詢,第一批返回101文檔或足夠的檔案超過1 MB,後續的批大小為4 MB。如果第一批是返回101個文檔時,遍曆完時,執行hasNext,會到資料庫查詢結果,直到所有結果都被返回,遊標才會結關閉。

 


 

四.其他的查詢方法

     mongoTemplate .findAll   查詢集合所有的文檔 相當於MongoDB的db.collect.find()。

     mongoTemplate .findById  根據文檔_ID查詢對應的文檔。

     mongoTemplate .findAndRemove  根據查詢條件,查詢匹配的文檔返回,並從資料庫中刪除。


     我們在查詢時,這邊預設是有使用到索引,對於資料量大的文檔,需要建立合適的索引,加快查詢效率。





著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Spring Data MongoDB 五:進階文檔查詢(分頁、Morphia)(二)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.