一.簡單介紹
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部分的源碼:
publicclassQueryBuilder {
/**
* Creates a builder with an empty query
*/
publicQueryBuilder() {
_query = new BasicDBObject();
}
publicQueryBuilder or( DBObject ... ors ){
List l = (List)_query.get( "$or" );
if ( l == null ){
l = new ArrayList();
_query.put( "$or" , l );
}
for ( DBObject o : ors )
l.add( o );
return this;
}
/**
* Equivalent to an $and operand
* @param ands
* @return
*/
@SuppressWarnings("unchecked")
publicQueryBuilder and( DBObject ... ands ){
List l = (List)_query.get( "$and" );
if ( l == null ){
l = new ArrayList();
_query.put( "$and" , 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("onumber").is("002"));
Ordersorder=ordersDao.findOne(query,collectionName);
System.out.println(JSONObject.fromObject(order));
}
我們到MongoDB查詢時,有兩條onumber值同樣的文檔
> db.orders.find()
{ "_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" } ] }
{ "_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,返回第一個記錄
{"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的方法
@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("onumber").is("002").and("cname").is("zcy1"));
@Test
public void testFind() throws ParseException
{
Queryquery=newQuery(Criteria.where("onumber").is("002").and("cname").is("zcy1"));
List<Orders>orders=ordersDao.find(query,collectionName);
System.out.println(JSONArray.fromObject(orders));
} 我們查看轉換成Query 時。是怎么樣的,我們斷點跟蹤一下

會轉換成相應的文檔查詢
查詢的結果
[{"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的方法
@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("onumber","002"));
basicDBList.add(new BasicDBObject("cname","zcy1"));
DBObjectobj = newBasicDBObject();
obj.put("$or", basicDBList);
Queryquery=newBasicQuery(obj);
List<Orders>orders=ordersDao.find(query,collectionName);
System.out.println(JSONArray.fromObject(orders));
}查詢的結果:
[{"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"},{"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是,就不會返回該字段。
指定返回字段,有時文檔字段多並數據大時,我們指定返回我們須要的字段。這樣既節省數據傳輸量,降低了內存消耗,提高了性能,在數據大時。性能非常明顯的。
QueryBuilder queryBuilder = new QueryBuilder();
queryBuilder.or(new BasicDBObject("onumber", "002"), new BasicDBObject("cname","zcy1"));
BasicDBObject fieldsObject=new BasicDBObject();
fieldsObject.put("onumber", 1);
fieldsObject.put("cname", 1);
Query query=new BasicQuery(queryBuilder.get(),fieldsObject);返回結果:
[{"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})
總結:
我們常常比較使用的是org.springframework.data.mongodb.core.query.BasicQuery,首先提供了4個構造函數,在構造查詢語句時。使用的是文檔形式,方便我們對復雜查詢的語句構造,並且還提供了指定使用投影運算符返回的字段省略此參數返回匹配文檔中的全部字段。指定返回字段,有時文檔字段多並數據大時,我們指定返回我們須要的字段,這樣既節省數據傳輸量,降低了內存消耗,提高了性能。在數據大時,性能非常明顯的。
我們今天介紹了主要的文檔操作,我們先了解怎么構造查詢語句,並使用介紹了這兩種方法。方便我們對查詢的主要的理解。思路會更加清晰。
