设为首页 收藏本站
查看: 1607|回复: 0

[经验分享] Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)

[复制链接]

尚未签到

发表于 2017-12-16 13:25:29 | 显示全部楼层 |阅读模式
一.简单介绍
  Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作。
  我们回想一下。我们在之前介绍了MongoDB的基本文档查询,MongoDB的查询语法:
  db.orders.find({{<field1>:<value1>,<field2>: <value2>, ... } },{field1:<boolean>, field2: <boolean> ... })
  

  我们介绍是SpringData MongoDB 提供了find方法。方便我们通过java代码实现对MongoDB的查询操作:
  mongoTemplate.find (query, entityClass)
  參数说明:
  entityClass:实体class,也就是要把文档转换成相应的实体。
  query查询语句的实现的方式有两种:
  1.org.springframework.data.mongodb.core.query
  构造函数
  Query (Criteria criteria)
  接受的參数是org.springframework.data.mongodb.core.query.Criteria
  Criteria是标准查询的接口,能够引用静态的Criteria.where的把多个条件组合在一起,就能够轻松地将多个方法标准和查询连接起来,方便我们操作查询语句。
  比如: 查询条件onumber=&quot;002&quot;
  mongoTemplate.find (new Query(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;)),entityClass)
  

  多个条件组合查询时:
  比如:onumber=&quot;002&quot; and cname=&quot;zcy&quot;
  mongoTemplate.find (new Query(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;).and(&quot;cname&quot;).is(&quot;zcy&quot;)),entityClass)
  比如:onumber=&quot;002&quot; or cname=&quot;zcy&quot;
  mongoTemplate.findOne(newQuery(newCriteria().orOperator(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;),Criteria.where(&quot;cname&quot;).is(&quot;zcy&quot;))),entityClass);
  

  我们通过Criteria的and方法,把这个条件组合一起查询
  Criteria提供了非常多方法,我们这边先介绍基本文档的查询操作符。对于数组文档或者内嵌文档的操作符,我们下一篇在介绍。
  Criteria
  Mongodb
  说明
  Criteria and (String key)
  $and
  而且
  Criteria andOperator (Criteria…​ criteria)
  $and
  而且
  Criteria orOperator (Criteria…​ criteria)
  $or
  或者
  Criteria gt (Object o)
  $gt
  大于
  Criteria gte (Object o)
  $gte
  大于等于
  Criteria in (Object…​ o)
  $in
  包括
  Criteria is (Object o)
  $is
  等于
  Criteria lt (Object o)
  $lt
  小于
  Criteria lte (Object o)
  $lte
  小等于
  Criteria nin (Object…​ o)
  $nin
  不包括
  。。。。。。
  。。。。
  。。。
  。
  2、子类 org.springframework.data.mongodb.core.query.BasicQuery
  

  构造方法
  BasicQuery(DBObject queryObject)
  BasicQuery(DBObject queryObject, DBObject fieldsObject)
  BasicQuery(java.lang.String query)
  BasicQuery(java.lang.String query, java.lang.String fields)
  DBObject就是转换成JSON&#26684;式,提供了我们回想一下。MongoDB查询时,
  db.collection.find(query,projection)。query类型是document,所以。我们想使用JSON字符串查询时,我们使用DBObject创建查询实例。
DSC0000.jpg

  DBObject是接口。提供了几个子类。
DSC0001.jpg

  watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">
  

  

  我们比較常常使用的比較底层子类。扩展了自己的方法和继承父类,所以功能会比較多。
  1. BasicDBObject
  BasicBSONObject extendsLinkedHashMap<String,Object> implements BSONObject
  BasicDBObject extends BasicBSONObject implementsDBObject
  

  比如:查询条件onumber=&quot;002&quot;
  

  DBObject obj = new BasicDBObject();
  obj.put( &quot;onumber&quot;,&quot;002&quot; );
  相当于
  db.collect.find({&quot;onumber&quot;:&quot;002&quot;})
  2. BasicDBList
  BasicBSONList extendsArrayList<Object> implements BSONObject
  BasicDBList extends BasicBSONList implements DBObject
  

  BasicDBList能够存放多个BasicDBObject条件
  比如:我们查询onumber=002OR cname=zcy1
                         BasicDBList basicDBList=new BasicDBList();

                         basicDBList.add(new BasicDBObject(&quot;onumber&quot;,&quot;002&quot;));

                         basicDBList.add(new BasicDBObject(&quot;cname&quot;,&quot;zcy1&quot;));

                        DBObjectobj =newBasicDBObject();

                       obj.put(&quot;$or&quot;, basicDBList);

  Query query=new BasicQuery(obj);
  相当于
  db.orders.find({$or:[{&quot;onumber&quot;:&quot;002&quot;},{&quot;cname&quot;:&quot;zcy1&quot;}]})
  basicDBList.add方法是加入一个文档的查询条件
  

  3. com.mongodb. QueryBuilder
  

  QueryBuilder默认构造函数,是初始化BasicDBObject,QueryBuilder多个方法标准和查询连接起来,方便我们操作查询语句。
  跟Criteria是标准查询的接口一样。
DSC0002.jpg

  QueryBuilder和BasicDBObject配合使用
  QueryBuilder帮我们实现了  $and等操作符,我们查看部分的源码:QueryBuilder部分的源码:
  

publicclassQueryBuilder {  /**
  * Creates a builder with an empty query
  */
  publicQueryBuilder() {
  _query = new BasicDBObject();
  }
  publicQueryBuilder or( DBObject ... ors ){
  List l = (List)_query.get( &quot;$or&quot; );
  if ( l == null ){
  l = new ArrayList();
  _query.put( &quot;$or&quot; , l );
  }
  for ( DBObject o : ors )
  l.add( o );
  return this;
  }
  /**
  * Equivalent to an $and operand
  * @param ands
  * @return
  */
  @SuppressWarnings(&quot;unchecked&quot;)
  publicQueryBuilder and( DBObject ... ands ){
  List l = (List)_query.get( &quot;$and&quot; );
  if ( l == null ){
  l = new ArrayList();
  _query.put( &quot;$and&quot; , l );
  }
  for ( DBObject o : ands )
  l.add( o );
  return this;
  }
  
}
  
                      接下来我们介绍查询的实现。Criteria提供了非常多方法,我们这边就不在一个一个的操作符运行一遍,这跟学习MongoDB 四: MongoDB查询(一)基本文档的操作符介绍的一样。
  

  二.findOne查询
  findOne返回满足指定查询条件的文档,假设多个文档满足查询,该方法返回第一个文档,依据自然顺序返回文件在磁盘上的顺序,在覆盖的集合中,自然顺序与插入顺序同样。
  假设没找到相应的文档。会返回null。
  方法:
  mongoTemplate.findOne(query,entityClass)
  1.      介绍接口以及方法的实现
  我们在上一篇有介绍了实现主要的加入,对整个结构有介绍了,我们这边就不在介绍了,直接介绍往里面加入方法
  第一步:我们在基础接口MongoBase.java类新增一个findOne的接口
  

            //依据条件查询  public T findOne(Query query,String collectionName);
  

           第二步:我们在OrdersDaoImpl类加入一个详细findOne的实现方法  

        @Override  public Orders findOne(Query query, String collectionName) {
  return mongoTemplate.findOne(query, Orders.class, collectionName);
  }
  

  

  第三步:实现測试方法
         

  

   /測试testFindOne方法加入  @Test
  public void testFindOne() throws ParseException
  {
  Queryquery=newQuery(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;));
  Ordersorder=ordersDao.findOne(query,collectionName);
  System.out.println(JSONObject.fromObject(order));
  }
  

  我们到MongoDB查询时,有两条onumber&#20540;同样的文档
  

> db.orders.find()  
{ &quot;_id&quot; : ObjectId(&quot;55b3ae9bee10ded9390d0b97&quot;),&quot;_class&quot; : &quot;com.mongo.model.Orders&quot;, &quot;onumber&quot; : &quot;002&quot;, &quot;date&quot; :ISODate(&quot;2015-01-24T16:07:00Z&quot;), &quot;cname&quot; : &quot;zcy1&quot;, &quot;items&quot; : [ { &quot;quantity&quot; : 5,&quot;price&quot; : 4, &quot;pnumber&quot; : &quot;p001&quot; }, {&quot;quantity&quot; : 6, &quot;price&quot; : 8, &quot;pnumber&quot; :&quot;p002&quot; } ] }
  
{ &quot;_id&quot; : ObjectId(&quot;55b3aea5ee10f970a2da7017&quot;),&quot;_class&quot; : &quot;com.mongo.model.Orders&quot;, &quot;onumber&quot; : &quot;002&quot;, &quot;date&quot; :ISODate(&quot;2015-01-24T16:07:00Z&quot;), &quot;cname&quot; : &quot;zcy2&quot;, &quot;items&quot; : [ { &quot;quantity&quot; : 5,&quot;price&quot; : 4, &quot;pnumber&quot; : &quot;p003&quot; }, { &quot;quantity&quot; : 6, &quot;price&quot; : 8, &quot;pnumber&quot; :&quot;p004&quot; } ] }
  

  

  我们运行findOne时查询条件为onumber=002,返回第一个记录  

  

{&quot;cname&quot;:&quot;zcy1&quot;,&quot;date&quot;{&quot;date&quot;:25,&quot;day&quot;:0,&quot;hours&quot;:0,&quot;minutes&quot;:7,&quot;month&quot;:0,&quot;seconds&quot;:0,&quot;time&quot;:1422115620000,&quot;timezoneOffset&quot;:-480,&quot;year&quot;:115},&quot;id&quot;:&quot;55b3ae9bee10ded9390d0b97&quot;,&quot;items&quot;:[{&quot;pnumber&quot;:&quot;p001&quot;,&quot;price&quot;:4,&quot;quantity&quot;:5},{&quot;pnumber&quot;:&quot;p002&quot;,&quot;price&quot;:8,&quot;quantity&quot;:6}],&quot;onumber&quot;:&quot;002&quot;}  

  

  三.find查询
  1.org.springframework.data.mongodb.core.query
  构造函数
  Query (Criteria criteria)
  接受的參数是org.springframework.data.mongodb.core.query.Criteria
  样例:查询onumber=&quot;002&quot; 而且cname=&quot;zcy&quot;
  OrdersDaoImpl类实现了find的方法
  

       @Override  publicList<Orders> find(org.springframework.data.mongodb.core.query.Queryquery, String collectionName) {
  return mongoTemplate.find(query, Orders.class, collectionName);
  }
  

  

  实现測试方法
            Query query=new Query(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;).and(&quot;cname&quot;).is(&quot;zcy1&quot;));
     

  

@Test  public void testFind() throws ParseException
  {
  Queryquery=newQuery(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;).and(&quot;cname&quot;).is(&quot;zcy1&quot;));
  List<Orders>orders=ordersDao.find(query,collectionName);
  System.out.println(JSONArray.fromObject(orders));
  }
  

       我们查看转换成Query 时。是怎么样的,我们断点跟踪一下

             DSC0003.jpg

  watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

  

           会转换成相应的文档查询


   查询的结果


  

   [{&quot;cname&quot;:&quot;zcy1&quot;,&quot;date&quot;:{&quot;date&quot;:25,&quot;day&quot;:0,&quot;hours&quot;:0,&quot;minutes&quot;:7,&quot;month&quot;:0,&quot;seconds&quot;:0,&quot;time&quot;:1422115620000,&quot;timezoneOffset&quot;:-480,&quot;year&quot;:115},&quot;id&quot;:&quot;55b3ae9bee10ded9390d0b97&quot;,&quot;items&quot;:[{&quot;pnumber&quot;:&quot;p001&quot;,&quot;price&quot;:4,&quot;quantity&quot;:5},{&quot;pnumber&quot;:&quot;p002&quot;,&quot;price&quot;:8,&quot;quantity&quot;:6}],&quot;onumber&quot;:&quot;002&quot;}]  

  

  相当于MongoDB
  b.orders.find({&quot;onumber&quot; : &quot;002&quot; ,&quot;cname&quot; : &quot;zcy1&quot;})
  

  还能够第二种写法Criteria andOperator(Criteria…​ criteria)
      Queryquery=newQuery(Criteria.where(&quot;onumber&quot;).is(&quot;002&quot;).andOperator(Criteria.where(&quot;cname&quot;).is(&quot;zcy1&quot;)));

  一个Criteria中仅仅能有一个andOperator,and能够多个,我们查询并列条件时,比較建议使用and方法。
  

  2、org.springframework.data.mongodb.core.query.BasicQuery
  构造方法
  BasicQuery(DBObject queryObject)
  BasicQuery(DBObject queryObject, DBObject fieldsObject)
  BasicQuery(java.lang.String query)
  BasicQuery(java.lang.String query, java.lang.String fields)
  样例:查询onumber=&quot;002&quot; or cname=&quot;zcy&quot;
  OrdersDaoImpl类实现了find的方法
  

        @Override  publicList<Orders> find(org.springframework.data.mongodb.core.query.BasicQueryquery, String collectionName) {
  returnmongoTemplate.find(query, Orders.class, collectionName);
  }
  

  实现測试方法

  

public voidtestFind() throwsParseException  {
  BasicDBListbasicDBList=newBasicDBList();
  basicDBList.add(new BasicDBObject(&quot;onumber&quot;,&quot;002&quot;));
  basicDBList.add(new BasicDBObject(&quot;cname&quot;,&quot;zcy1&quot;));
  DBObjectobj = newBasicDBObject();
  obj.put(&quot;$or&quot;, basicDBList);
  Queryquery=newBasicQuery(obj);
  List<Orders>orders=ordersDao.find(query,collectionName);
  System.out.println(JSONArray.fromObject(orders));
  }
  

  查询的结果:
  

[{&quot;cname&quot;:&quot;zcy1&quot;,&quot;date&quot;:{&quot;date&quot;:25,&quot;day&quot;:0,&quot;hours&quot;:0,&quot;minutes&quot;:7,&quot;month&quot;:0,&quot;seconds&quot;:0,&quot;time&quot;:1422115620000,&quot;timezoneOffset&quot;:-480,&quot;year&quot;:115},&quot;id&quot;:&quot;55bb9a3c27547f55fef9a10f&quot;,&quot;items&quot;:[{&quot;pnumber&quot;:&quot;p001&quot;,&quot;price&quot;:5,&quot;quantity&quot;:6},{&quot;pnumber&quot;:&quot;p002&quot;,&quot;price&quot;:9,&quot;quantity&quot;:7}],&quot;onumber&quot;:&quot;001&quot;},{&quot;cname&quot;:&quot;zcy1&quot;,&quot;date&quot;:{&quot;date&quot;:25,&quot;day&quot;:0,&quot;hours&quot;:0,&quot;minutes&quot;:7,&quot;month&quot;:0,&quot;seconds&quot;:0,&quot;time&quot;:1422115620000,&quot;timezoneOffset&quot;:-480,&quot;year&quot;:115},&quot;id&quot;:&quot;55bb9a2727544d40b95156e1&quot;,&quot;items&quot;:[{&quot;pnumber&quot;:&quot;p001&quot;,&quot;price&quot;:5,&quot;quantity&quot;:6},{&quot;pnumber&quot;:&quot;p002&quot;,&quot;price&quot;:9,&quot;quantity&quot;:7}],&quot;onumber&quot;:&quot;001&quot;}]  

  

  相当于MongoDB
  { &quot;$or&quot; : [ { &quot;onumber&quot; :&quot;002&quot;} , { &quot;cname&quot; : &quot;zcy1&quot;}]}
  

  

  QueryBuilder和BasicDBObject配合使用
          QueryBuilder queryBuilder= newQueryBuilder();

         queryBuilder.or(new BasicDBObject(&quot;onumber&quot;,&quot;002&quot;),newBasicDBObject(&quot;cname&quot;,&quot;zcy1&quot;));

  Query query=new BasicQuery(queryBuilder.get());

四.find查询时指定返回的须要的字段
  org.springframework.data.mongodb.core.query.BasicQuery提供了
  构造方法
  BasicQuery(DBObject queryObject, DBObject fieldsObject)
  BasicQuery(java.lang.String query, java.lang.String fields)
  

  

  BasicQuery查询语句能够指定返回字段。构造函数
  BasicQuery(DBObject queryObject, DBObject fieldsObject)
  fieldsObject 这个字段能够指定返回字段
  fieldsObject.put(key,value)
  key:字段
  value:
  说明:
  1或者true表示返回字段
  0或者false表示不返回该字段
  _id:默认就是1。没指定返回该字段时。默认会返回,除非设置为0是,就不会返回该字段。
  指定返回字段,有时文档字段多并数据大时,我们指定返回我们须要的字段。这样既节省数据传输量,降低了内存消耗,提高了性能,在数据大时。性能非常明显的。

  

        QueryBuilder queryBuilder = new QueryBuilder();  queryBuilder.or(new BasicDBObject(&quot;onumber&quot;, &quot;002&quot;), new BasicDBObject(&quot;cname&quot;,&quot;zcy1&quot;));
  BasicDBObject fieldsObject=new BasicDBObject();
  fieldsObject.put(&quot;onumber&quot;, 1);
  fieldsObject.put(&quot;cname&quot;, 1);
  Query query=new BasicQuery(queryBuilder.get(),fieldsObject);
  

  返回结果:
  

[{&quot;cname&quot;:&quot;zcy1&quot;,&quot;date&quot;:null,&quot;id&quot;:&quot;55bb9a3c27547f55fef9a10f&quot;,&quot;items&quot;:[],&quot;onumber&quot;:&quot;001&quot;},{&quot;cname&quot;:&quot;zcy1&quot;,&quot;date&quot;:null,&quot;id&quot;:&quot;55bb9a2727544d40b95156e1&quot;,&quot;items&quot;:[],&quot;onumber&quot;:&quot;001&quot;}]  

  相当于MongoDB
  db.orders.find({&quot;$or&quot; : [ { &quot;onumber&quot; : &quot;002&quot;} , {&quot;cname&quot; : &quot;zcy1&quot;}]},{&quot;onumber&quot;:1,&quot;cname&quot;:1})  
  

  

  总结:
  我们常常比較使用的是org.springframework.data.mongodb.core.query.BasicQuery,首先提供了4个构造函数,在构造查询语句时。使用的是文档形式,方便我们对复杂查询的语句构造,并且还提供了指定使用投影运算符返回的字段省略此參数返回匹配文档中的全部字段。指定返回字段,有时文档字段多并数据大时,我们指定返回我们须要的字段,这样既节省数据传输量,降低了内存消耗,提高了性能。在数据大时,性能非常明显的。
  我们今天介绍了主要的文档操作,我们先了解怎么构造查询语句,并使用介绍了这两种方法。方便我们对查询的主要的理解。思路会更加清晰。
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-424696-1-1.html 上篇帖子: MongoDB的数据备份与恢复 下篇帖子: 使用moogose连接MongoDB 并用ajax获取数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表