mongoTemplate通过Query条件指定查询条件和返回字段

本文转自 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>: <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="002"

        mongoTemplate.find (new Query(Criteria.where("onumber").is("002")),entityClass)

 

        多个条件组合查询时:

       例如:onumber="002" and cname="zcy"

     

         mongoTemplate.find (new Query(Criteria.where("onumber").is("002").and("cname").is("zcy")),entityClass)

 

       例如:onumber="002" or cname="zcy"

         mongoTemplate.findOne(newQuery(newCriteria().orOperator(Criteria.where("onumber").is("002"),Criteria.where("cname").is("zcy"))),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格式,提供了我们回顾一下,MongoDB查询时,

             db.collection.find(query,projection),query类型是document,所以,我们想使用JSON字符串查询时,我们使用DBObject创建查询实例。

                 

               DBObject是接口,提供了几个子类,

                            

                  

 

 

            我们比较经常使用的比较底层子类,扩展了自己的方法和继承父类,所以功能会比较多。

 

           1. BasicDBObject

                BasicBSONObject extendsLinkedHashMap<String,Object> implements BSONObject

                BasicDBObject extends BasicBSONObject implementsDBObject

 

               例如:查询条件onumber="002"

 

                DBObject obj = new BasicDBObject();

               obj.put( "onumber","002" );

             

               相当于

                db.collect.find({"onumber":"002"}) 

 

 

             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("onumber","002"));

                         basicDBList.add(new BasicDBObject("cname","zcy1"));

                        DBObjectobj =newBasicDBObject();

                       obj.put("$or", basicDBList);

                       Query query=new BasicQuery(obj);

           相当于

                  db.orders.find({$or:[{"onumber":"002"},{"cname":"zcy1"}]})

                

                      basicDBList.add方法是添加一个文档的查询条件

                     

 

             3. com.mongodb. QueryBuilder

 

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

                    

              QueryBuilder和BasicDBObject配合使用

 

              QueryBuilder帮我们实现了  $and等操作符,我们查看部分的源代码:QueryBuilder部分的源代码:

 

[java]  view plain  copy

  1. publicclassQueryBuilder {  
  2.    
  3.   /** 
  4.     * Creates a builder with an empty query 
  5.     */  
  6.   publicQueryBuilder() {  
  7.        _query = new BasicDBObject();  
  8.    }  
  9.   publicQueryBuilder or( DBObject ... ors ){  
  10.        List l = (List)_query.get( "$or" );  
  11.        if ( l == null ){  
  12.            l = new ArrayList();  
  13.            _query.put( "$or" , l );  
  14.        }  
  15.        for ( DBObject o : ors )  
  16.            l.add( o );  
  17.        return this;  
  18.   }  
  19.   
  20.   /** 
  21.     * Equivalent to an $and operand 
  22.     * @param ands 
  23.     * @return 
  24.     */  
  25.   @SuppressWarnings("unchecked")  
  26.   publicQueryBuilder and( DBObject ... ands ){  
  27.        List l = (List)_query.get( "$and" );  
  28.        if ( l == null ){  
  29.            l = new ArrayList();  
  30.            _query.put( "$and" , l );  
  31.        }  
  32.        for ( DBObject o : ands )  
  33.            l.add( o );  
  34.        return this;  
  35.    }  


                      接下来我们介绍查询的实现, Criteria提供了很多方法,我们这边就不在一个一个的操作符执行一遍,这跟学习MongoDB 四: MongoDB查询(一)基本文档的操作符介绍的一样。

 

    

 二.findOne查询

         findOne返回满足指定查询条件的文档,如果多个文档满足查询,该方法返回第一个文档,根据自然顺序返回文件在磁盘上的顺序,在覆盖的集合中,自然顺序与插入顺序相同。如果没找到对应的文档,会返回null。

方法:

       mongoTemplate.findOne(query,entityClass)

 

       1.      介绍接口以及方法的实现

               我们在上一篇有介绍了实现基本的添加,对整个结构有介绍了,我们这边就不在介绍了,直接介绍往里面添加方法

                 

              第一步:我们在基础接口MongoBase.java类新增一个findOne的接口

 

[java]  view plain  copy

  1. //根据条件查询  
  2. blic T findOne(Query query,String collectionName);  

           第二步:我们在OrdersDaoImpl类添加一个具体findOne的实现方法

 

 

[java]  view plain  copy

  1.       @Override  
  2. ublic Orders findOne(Query query, String collectionName) {  
  3. return mongoTemplate.findOne(query, Orders.class, collectionName);  

 

 

      第三步:实现测试方法

         

[java]  view plain  copy

  1. /测试testFindOne方法添加  
  2.    @Test  
  3.    public void testFindOne() throws ParseException  
  4.    {  
  5.       
  6.      Queryquery=newQuery(Criteria.where("onumber").is("002"));  
  7.      Ordersorder=ordersDao.findOne(query,collectionName);  
  8.      System.out.println(JSONObject.fromObject(order));  
  9.       
  10.   }  

 

 

 

   我们到MongoDB查询时,有两条onumber值相同的文档

      

[sql]  view plain  copy

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

 

 

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

 

[sql]  view plain  copy

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

 

 

  三.find查询

 

      1.org.springframework.data.mongodb.core.query

       构造函数

        Query (Criteria criteria)

      接受的参数是org.springframework.data.mongodb.core.query.Criteria

 

        例子:查询onumber="002" 并且cname="zcy"

           OrdersDaoImpl类实现了find的方法

 

[java]  view plain  copy

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

 

 

         实现测试方法

            Query query=new Query(Criteria.where("onumber").is("002").and("cname").is("zcy1"));       

 

[java]  view plain  copy

  1. @Test  
  2.    public void testFind() throws ParseException  
  3.    {  
  4.       Queryquery=newQuery(Criteria.where("onumber").is("002").and("cname").is("zcy1"));  
  5.       List<Orders>orders=ordersDao.find(query,collectionName);  
  6.       System.out.println(JSONArray.fromObject(orders));  
  7.      }  

 

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

            

 

           会转换成对应的文档查询

 

   查询的结果

 

[java]  view plain  copy

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

 

 

  相当于MongoDB

     b.orders.find({"onumber" : "002" ,"cname" : "zcy1"}) 

 

    还可以另外一种写法Criteria andOperator(Criteria…​ criteria)

 

      Queryquery=newQuery(Criteria.where("onumber").is("002").andOperator(Criteria.where("cname").is("zcy1")));

     一个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="002" or cname="zcy"

           OrdersDaoImpl类实现了find的方法

 

[java]  view plain  copy

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

 

 

      实现测试方法

 

[java]  view plain  copy

  1. public voidtestFind() throwsParseException  
  2.    {  
  3.        
  4.       BasicDBListbasicDBList=newBasicDBList();  
  5.        
  6.       basicDBList.add(new BasicDBObject("onumber","002"));  
  7.       basicDBList.add(new BasicDBObject("cname","zcy1"));  
  8.       DBObjectobj = newBasicDBObject();  
  9.       obj.put("$or", basicDBList);  
  10.       Queryquery=newBasicQuery(obj);  
  11.       List<Orders>orders=ordersDao.find(query,collectionName);  
  12.       System.out.println(JSONArray.fromObject(orders));  
  13.    }  

 

 

   查询的结果:

       

[sql]  view plain  copy

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

[sql]  view plain  copy

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

 

 

     相当于MongoDB

         { "$or" : [ { "onumber" :"002"} , { "cname" : "zcy1"}]}

 

     QueryBuilder和BasicDBObject配合使用

          QueryBuilder queryBuilder= newQueryBuilder(); 

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

        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是,就不会返回该字段。

               指定返回字段,有时文档字段多并数据大时,我们指定返回我们需要的字段,这样既节省传输数据量,减少了内存消耗,提高了性能,在数据大时,性能很明显的。

 

[java]  view plain  copy

  1. QueryBuilder queryBuilder = new QueryBuilder();   
  2. queryBuilder.or(new BasicDBObject("onumber", "002"), new BasicDBObject("cname","zcy1"));   
  3. BasicDBObject fieldsObject=new BasicDBObject();  
  4. fieldsObject.put("onumber", 1);  
  5. fieldsObject.put("cname", 1);  
  6. uery query=new BasicQuery(queryBuilder.get(),fieldsObject);  

 

 

   返回结果:

            

[java]  view plain  copy

  1. [{"cname":"zcy1","date":null,"id":"55bb9a3c27547f55fef9a10f","items":[],"onumber":"001"},{"cname":"zcy1","date":null,"id":"55bb9a2727544d40b95156e1","items":[],"onumber":"001"}]  

 

 

 相当于MongoDB

          db.orders.find({"$or" : [ { "onumber" : "002"} , {"cname" : "zcy1"}]},{"onumber":1,"cname":1})  

热门文章

暂无图片
编程学习 ·

那些年让我们目瞪口呆的bug

程序员一生与bug奋战&#xff0c;可谓是杀敌无数&#xff0c;见怪不怪了&#xff01;在某知识社交平台中&#xff0c;一个“有哪些让程序员目瞪口呆的bug”的话题引来了6700多万的阅读&#xff0c;可见程序员们对一个话题的敏感度有多高。 1、麻省理工“只能发500英里的邮件” …
暂无图片
编程学习 ·

redis的下载与安装

下载redis wget http://download.redis.io/releases/redis-5.0.0.tar.gz解压redis tar -zxvf redis-5.0.0.tar.gz编译 make安装 make install快链方便进入redis ln -s redis-5.0.0 redis
暂无图片
编程学习 ·

《大话数据结构》第三章学习笔记--线性表(一)

线性表的定义 线性表&#xff1a;零个或多个数据元素的有限序列。 线性表元素的个数n定义为线性表的长度。n为0时&#xff0c;为空表。 在比较复杂的线性表中&#xff0c;一个数据元素可以由若干个数据项组成。 线性表的存储结构 顺序存储结构 可以用C语言中的一维数组来…
暂无图片
编程学习 ·

对象的扩展

文章目录对象的扩展属性的简洁表示法属性名表达式方法的name属性属性的可枚举性和遍历可枚举性属性的遍历super关键字对象的扩展运算符解构赋值扩展运算符AggregateError错误对象对象的扩展 属性的简洁表示法 const foo bar; const baz {foo}; baz // {foo: "bar"…
暂无图片
编程学习 ·

让程序员最头疼的5种编程语言

世界上的编程语言&#xff0c;按照其应用领域&#xff0c;可以粗略地分成三类。 有的语言是多面手&#xff0c;在很多不同的领域都能派上用场。大家学过的编程语言很多都属于这一类&#xff0c;比如说 C&#xff0c;Java&#xff0c; Python。 有的语言专注于某一特定的领域&…
暂无图片
编程学习 ·

写论文注意事项

参考链接 给研究生修改了一篇论文后&#xff0c;该985博导几近崩溃…… 重点分析 摘要与结论几乎重合 这一条是我见过研究生论文中最常出现的事情&#xff0c;很多情况下&#xff0c;他们论文中摘要部分与结论部分重复率超过70%。对于摘要而言&#xff0c;首先要用一小句话引…
暂无图片
编程学习 ·

安卓 串口开发

上图&#xff1a; 上码&#xff1a; 在APP grable添加 // 串口 需要配合在项目build.gradle中的repositories添加 maven {url "https://jitpack.io" }implementation com.github.licheedev.Android-SerialPort-API:serialport:1.0.1implementation com.jakewhart…
暂无图片
编程学习 ·

2021-2027年中国铪市场调研与发展趋势分析报告

2021-2027年中国铪市场调研与发展趋势分析报告 本报告研究中国市场铪的生产、消费及进出口情况&#xff0c;重点关注在中国市场扮演重要角色的全球及本土铪生产商&#xff0c;呈现这些厂商在中国市场的铪销量、收入、价格、毛利率、市场份额等关键指标。此外&#xff0c;针对…
暂无图片
编程学习 ·

Aggressive cows题目翻译

描述&#xff1a; Farmer John has built a new long barn, with N (2 < N < 100,000) stalls.&#xff08;John农民已经新建了一个长畜棚带有N&#xff08;2<N<100000&#xff09;个牛棚&#xff09; The stalls are located along a straight line at positions…
暂无图片
编程学习 ·

剖析组建PMO的6个大坑︱PMO深度实践

随着事业环境因素的不断纷繁演进&#xff0c;项目时代正在悄悄来临。设立项目经理转岗、要求PMP等项目管理证书已是基操&#xff0c;越来越多的组织开始组建PMO团队&#xff0c;大有曾经公司纷纷建造中台的气质&#xff08;当然两者的本质并不相同&#xff0c;只是说明这个趋势…
暂无图片
编程学习 ·

Flowable入门系列文章118 - 进程实例 07

1、获取流程实例的变量 GET运行时/进程实例/ {processInstanceId} /变量/ {变量名} 表1.获取流程实例的变量 - URL参数 参数需要值描述processInstanceId是串将流程实例的id添加到变量中。变量名是串要获取的变量的名称。 表2.获取流程实例的变量 - 响应代码 响应码描述200指…
暂无图片
编程学习 ·

微信每天自动给女[男]朋友发早安和土味情话

微信通知&#xff0c;每天给女朋友发早安、情话、诗句、天气信息等~ 前言 之前逛GitHub的时候发现了一个自动签到的小工具&#xff0c;b站、掘金等都可以&#xff0c;我看了下源码发现也是很简洁&#xff0c;也尝试用了一下&#xff0c;配置也都很简单&#xff0c;主要是他有一…
暂无图片
编程学习 ·

C语言二分查找详解

二分查找是一种知名度很高的查找算法&#xff0c;在对有序数列进行查找时效率远高于传统的顺序查找。 下面这张动图对比了二者的效率差距。 二分查找的基本思想就是通过把目标数和当前数列的中间数进行比较&#xff0c;从而确定目标数是在中间数的左边还是右边&#xff0c;将查…
暂无图片
编程学习 ·

项目经理,你有什么优势吗?

大侠被一个问题问住了&#xff1a;你和别人比&#xff0c;你的优势是什么呢? 大侠听到这个问题后&#xff0c;脱口而出道&#xff1a;“项目管理能力和经验啊。” 听者抬头看了一下大侠&#xff0c;显然听者对大侠的这个回答不是很满意&#xff0c;但也没有继续追问。 大侠回家…
暂无图片
编程学习 ·

nginx的负载均衡和故障转移

#注&#xff1a;proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_temp_path /data0/proxy_temp_dir; #设置Web缓存区名称为cache_one&#xff0c;内存缓存空间大小为200MB&#xff0c;1天没有被访问的内容自动清除&#xff0c;硬盘缓存空间大小为30GB。 pro…
暂无图片
编程学习 ·

业务逻辑漏洞

身份认证安全 绕过身份认证的几种方法 暴力破解 测试方法∶在没有验证码限制或者一次验证码可以多次使用的地方&#xff0c;可以分为以下几种情况︰ (1)爆破用户名。当输入的用户名不存在时&#xff0c;会显示请输入正确用户名&#xff0c;或者用户名不存在 (2)已知用户名。…