Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)

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  根据查询条件,查询匹配的文档返回,并从数据库中删除。

我们在查询时,这边默认是有使用到索引,对于数据量大的文档,需要建立合适的索引,加快查询效率。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-03 18:27:31

Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)的相关文章

SpringMVC MongoDB之“基本文档查询(Query、BasicQuery)”

一.简介 spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作. 我们回顾一下,我们在之前介绍了MongoDB的基本文档查询,MongoDB的查询语法: db.orders.find({{<field1>:<value1>,<field2>

Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)

一.简介 Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作. 我们回顾一下,我们在之前介绍了MongoDB的基本文档查询,MongoDB的查询语法: db.orders.find({{<field1>:<value1>,<field2>

Spring Data MongoDB 分页查询

在上篇文章 Spring Data MongoDB 环境搭建 基础上进行分页查询 定义公用分页参数类,实现 Pageable 接口 import java.io.Serializable; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; public class SpringDataPageable implements Serializable, Page

springboot Spring Data MongoDB 操作 mongodb

Spring Data MongoDB 3.1生成的查询方法(Generated Query Methods) 我们将通过探索findBy类型的查询来简单地开始 - 在这种情况下,通过名称查找: List<User> findByName(String name); 3.2 StartingWith and endingWith. List<User> users = userRepository.findByNameStartingWith("A"); Lis

Spring Data MongoDB 四:基本文档修改(update)(一)

Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 二:MongoDB添加.删除.修改 一.简介 Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的update的操作,可以对在存储数据时是以键-值对的集合键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档进行修改,我们今天介绍对基本文档的修改的方法.参数进

[Spring Data MongoDB]学习笔记--MongoTemplate查询操作

查询操作主要用到两个类:Query, Criteria 所有的find方法都需要一个query的object. 1. 直接通过json来查找,不过这种方式在代码中是不推荐的. BasicQuery query = new BasicQuery("{ age : { $lt : 50 }, accounts.balance : { $gt : 1000.00 }}"); List<Person> result = mongoTemplate.find(query, Perso

Spring Data MongoDB实战(上)

Spring Data MongoDB实战(上) 作者:chszs,版权所有,未经同意,不得转载.博主主页:http://blog.csdn.net/chszs 本文会详细展示Spring Data MongoDB是如何访问MongoDB数据库的.MongoDB是一个开源的文档型NoSQL数据库,而Spring Data MongoDB是Spring Data的模块之一,专用于访问MongoDB数据库.Spring Data MongoDB模块既提供了基于方法名的查询方式,也提供了基于注释的查询

Spring Data MongoDB 二:添加、删除操作

一.简介 Spring  Data  MongoDB 项目提供与MongoDB文档数据库的集成,Spring与Hibernate集成时,Spring提供了org.springframework.orm.hibernate3.HibernateTemplate实现了对数据的CRUD操作, Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,包括对集成的对象映射文件和PO

使用Spring访问Mongodb的方法大全——Spring Data MongoDB

1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongodb数据库的几种方法: 使用Query和Criteria类 JPA自动生成的查询方法 使用@Query 注解基于JSON查询 在开始前,首先需要引入maven依赖 1.1 添加Maven的依赖 如果您想使用Spring Data MongoDB,则需要将以下条目添加到您的pom.xml文件中: <de