MongoTemplate實現了java代碼與mongodb數據庫之間的連接,是現場安全的。
一.創建MongoTemplate實例。
1.java code創建
1.1)數據庫無密碼:
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
//"dbName":連接的數據庫集合名稱
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(mongoClient , "dbName");
DbRefResolver dbRefResolver = new DefaultDbRefResolver(dbFactory);
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
//加入converter是去掉數據庫文檔中_class字段
MongoTemplate template = new MongoTemplate(dbFactory, converter);
1.2)數據庫有密碼驗證
UserCredentials userCredentials = new UserCredentials( "username", "password" );
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(mongoClient , "dbName",userCredentials );
.....................(以下步驟同上).....................
二.MongoTemplate的Crud操作mongodb數據庫
/* 約定 */
/*object:新增的javaBean對象。collectionName:集合名稱,相當於表名。*/
/*Collection<? extends Object> collection:批量操作時,對象的集合。例如List<User> collection*/
/*Query query = new Query() query:條件*/
1.新增文檔
MongoTemplate提供了save()和insert()兩種方式。
save:新增文檔時,如果有_id文檔存在則修改,不存在則增加,相當於根據條件調用insert或update方法。
insert:新增文檔時,如果有_id文檔存在則會新增失敗,即不會修改之前的值,也不會重新增加。
用法:
template.save(object);
template.save(object,collectionName);
template.insert(object);
template.insert(object,collectionName);
//批量插入
template.insertAll(collection);
template.insert(collection,collectionName);
2.刪除文檔
template.remove(query,collectionName);
template.dropCollection(collectionName);//刪除集合,即該張表會被刪除
3.修改文檔
. updateFirst 只修改符合條件第一條數據
. updateMulti 修改符合條件的所有所有
. upsert 修改符合條件時如果不存在則會新增加一條數據,相當於執行了insert()方法
/************ Update update=new Update() : update 需要更新的內容 *****************************/
update.set("key1", "value1") | 把"key1"對應的值設置為"value1",如果數據中不存在"key1",則會新增加一條信息key1:value1 |
update.inc("sum", 100) | inc累加計算,即sum在原來基礎上加上100,相當於sum=sum+100 |
update.multiply("sum", 100) | 乘法計算,即sum在原來基礎上乘以100,相當於sum=sum*100 |
update.rename("key2", "k2") | rename用於修改鍵值, 即把"key2":"value2"修改為"k2":"value2" |
update.unset("key3") | 刪除鍵為"key3"的信息,即從文檔中移除該鍵 |
update.pull("array", "a1") | 刪除array數組中的"a1"。 例如"array":["a1","a2","a3"],刪除"a1"后的結果 "array":["a2","a3"] |
update.pullAll("array", Object[] values) | 可一次性刪除數組內多個值 |
update.push("array","a3") | 向array數組里添加"a3"(不會檢查數組中元素是否重復), 數組"array"不存在則會新建該數組。修改后結果"array":["a2","a3","a3"] |
update.pushAll("array", Object[] values) | 可一次性向數組內添加多個值 |
update.addToSet("array","a3") | 向array數組里添加"a3"(會檢查數組中元素是否重復), 數組"array"不存在則會新建該數組。修改后結果"array":["a2","a3"] |
update.pop("array",Update.Position.FIRST) | 從"array"數組 開頭/結尾(Update.Position.FIRST/Update.Position.LAST) 移除一個元素 |
/***************************** 執行更新操作 *************************************/
//更新符合query條件的第一條數據
template.updateFirst(query, update, collectionName);
//更新符合query條件的所有數據
template.updateMulti(query, update, collectionName);
//更新符合條件時如果不存在則會新增加一條數據,相當於執行了insert()方法
template. upsert(query, update, collectionName);
4.查詢操作
/**************************** 准備query *****************************************/
Query query=new Query();
Query query=new Query(CriteriaDefinition criteriaDefinition);
!CriteriaDefinition是接口,Criteria是其實現類
/**************************** 設置query條件 *****************************************/
返回類型 | 方法 | 說明 | 應用例子 |
Query | addCriteria(Criteria criteria) | 向query里追加查詢條件 | query.addCriteria(Criteria.where("name").is("jack")); |
Query | skip(int skip) | 從第skip下標數據開始查詢,跳過skip下標之前的數據,小標從0開始 | query.skip(skip); |
Query | limit(int limit) | 限制返回數據的最大條數 | query.limit(limit); |
Query | withHint(String name) | 做強迫索引查詢用 | |
Query | with(Sort sort) | 可用於排序用 | query.with(new Sort(Sort.Direction.DESC,"time")); query.with(new Sort(Sort.Direction.ASC,"time")); |
Query | with(Pageable pageable) | Pageable對象里有skip,limit,sort信息,所以做可以分頁和排序 | |
static Query | query(Criteria criteria) | Query.query(Criteria.where("name").is("jack")); | |
DBObject | getQueryObject() |
||
Field | fields() | Field 可用於做指定字段查詢query.fields().include("age").exclude("name"); 還可用做返回指定字段時的工具(后面有例子) |
query.fields() |
static Criteria | where(String key) | 創建一個key,即查詢的key鍵 | query.addCriteria(Criteria.where("name").is("jack")); |
static Criteria | byExample(Object example) |
() | |
static Criteria | byExample(Example<?> example) |
() | |
Criteria | is(Object obj) | 等於(==) obj | query.addCriteria(Criteria.where("name").is("obj")); |
Criteria | and(String key) | 並且,用於多個字段同時查詢 | query(where("key1").is("value1").and("key2").is("value2")); |
Criteria | ne(Object o) | 不為 (不等於) | query(where("siteId").ne(null));//查詢siteId不為空的數據 query(where("name").ne("不為該值"));// |
Criteria | lt(Object o) | 小於(<) | query.addCriteria(Criteria.where("insert_date").gte(Date1).lte(Date2)); query.addCriteria(Criteria.where("age").gte(20).lte(30)); |
Criteria | lte(Object o) | 小於等於(<=) | |
Criteria | gt(Object o) | 大於(>) | |
Criteria | gte(Object o) | 大於等於(>=) | |
Criteria | in(Object... co) |
在...里(key對應的數據被包含在 co 里) | String[] strs=... ; query.addCriteria(Criteria.where("name").in((Object[]) strs)); 或query.addCriteria(Criteria.where("name").in(obj1,obj2,obj3,...)); |
Criteria | in(Collection<?> co) |
List<Object> collec=...; query.addCriteria(Criteria.where("key").in(collec)); |
|
Criteria | nin(Object... o) |
不在...里(與in相反) | (略) |
Criteria | nin(Collection<?> o) |
||
Criteria | mod(Number value, Number remainder) | 取模(求余)運算 ,即:key對應的值%value==remainder(求余是否等於remainder) |
// {key:15} {key2:15} query.addCriteria(Criteria.where("key").mod(10,3)); //key條件不成立;key2條件成立 |
Criteria | all(Object... col) |
key鍵對應的集合包含col(all是包含關系,in是被包含關系) | query.addCriteria(Criteria.where("key").all("n1","n2"));//此時key對應的值應該是集合 query.addCriteria(Criteria.where("nameList").all((Object[]) names))); |
Criteria | all(Collection<?> col) |
List<Object> collec=...; query.addCriteria(Criteria.where("key").all(collec)); |
|
Criteria |
size(int s) |
匹配key所對應的集合的元素的指定數量(!!!不能進行像<5之類的范圍匹配) | // {key:["foo","lue","cua"]} query.addCriteria(Criteria.where("key").size(3)); |
Criteria | exists(boolean b) | 查詢字段是否存在(true:存在,false:不存在) | query.addCriteria(Criteria.where("confirmTime").exists(false)); |
Criteria | type(int t) | ||
Criteria | not() | 取反 | //注意:not().is()這樣是錯誤的,not()后面不用跟is() query.addCriteria(Criteria.where("number").not().lte(2)); //number<=2取反,即number>2 |
Criteria | regex(String re) | 模糊查詢用 | (例子見下) |
Criteria | regex(String re, String options) | options可選值:i/m/x/s //i表示不區分大小寫 //m能使用^以及$等正則表達式來識別數據庫中使用\n換行的每一行開始字符以及字符。 //x //s如果設置了這個修飾符,模式中的點號元字符匹配所有字符,包含換行符。如果沒有這個修飾符,點號不匹配換行符。 |
|
Criteria | regex(Pattern pattern) | Pattern pattern = Pattern.compile("正則表達式"); query.addCriteria(Criteria.where("resourceName").regex(pattern)); |
|
Criteria | orOperator(Criteria... criteria) | 多個Criteria多個條件的或(or)操作 (a || b) |
Criteria c1=Criteria.where("name").is("張三")); Criteria c2=Criteria.where("age").is(25)); query.addCriteria(new Criteria().orOperator(c1, c2)); |
Criteria | norOperator(Criteria... criteria) | 執行mongodb的$nor操作,意思是: 返回 不滿足$or條件 的文檔。 即返回 不滿足(a || b)的文檔 |
(語法同orOperator) |
Criteria | andOperator(Criteria... criteria) | 多條件與(and)操作 (a && b) |
(同orOperator) |
Criteria | elemMatch(Criteria c) | 對象數組里的參數查詢 "users":[{"name":"張三","age":20,"hobby":"internet"},{},...] |
Criteria cri=Criteria.where("name").is("張三")); query.addCriteria(Criteria.where(users).elemMatch(cri); |
Criteria | registerCriteriaChainElement(Criteria criteria) | ||
Criteria | alike(Example<?> sample) | ||
Criteria | withinSphere(Circle circle) | ||
Criteria | within(Shape shape) | ||
Criteria | near(Point point) | ||
Criteria | nearSphere(Point point) | ||
Criteria | intersects(GeoJson geoJson) | ||
Criteria | maxDistance(double maxDistance) | ||
Criteria | minDistance(double minDistance) | ||
boolean | lastOperatorWasNot() | ||
Pattern | toPattern(String regex, String options) | ||
String | getKey() | ||
DBObject | getCriteriaObject() | ||
DBObject | getSingleCriteriaObject() | ||
BasicDBList | createCriteriaList(Criteria[] criteria) | ||
void | setValue(DBObject dbo, String key, Object value) | ||
boolean | createNearCriteriaForCommand(String command, String operation, double maxDistance) | ||
boolean | simpleCriteriaEquals(Criteria left, Criteria right) | ||
boolean | isEqual(Object left, Object right) | ||
int | hashCode() | ||
static boolean | requiresGeoJsonFormat(Object value) |
/** 利用regex做迷糊查詢 **/
private String regexFilter(String regex) {
if (regex.equals("*")) {
return "\\" + regex;
} else {
return regex;
}
}
query.addCriteria(Criteria.where("name").regex(".*" + regexFilter("StringValue") + ".*"));
/****/
/**************************** 分頁 *****************************************/
方式一:
(單個字段排序)
query.with(new Sort(Sort.Direction.DESC,"time"));
query.with(new Sort(Sort.Direction.ASC,"time"));
(多個字段同事排序)
query.with(new Sort(Direction.ASC,"time1","time2","time3"));
(不同字段不同排序)
List<Sort.Order>orderList=new ArrayList<Sort.Order>();
orderList.add(new Sort.Order(Direction.ASC, "time1"));
orderList.add(new Sort.Order(Direction.DESC, "tim2"));
query.with(new Sort(orderList));
先按照time1升序,在按照time2降序
方式二:
int page=3;//第幾頁
int size=30;//每頁條數
Sort sort=new Sort(Sort.Direction.ASC, "update_time");//排序,多條件排序同上
Pageable pageable=new PageRequest(page, size, sort);
query.with(pageable);
/**************************** 排序 *****************************************/
方式一:
query.skip(skip);
query.limit(limit);
方式二:
(同上—分頁)
/**************************** 返回指定字段 *****************************************/
利用 BasicQuery指定返回的字段
方式一:
BasicDBObject queryObject=new BasicDBObject();
BasicDBObject fieldsObject=new BasicDBObject();//fieldsObject可以指定返回字段
fieldsObject.put(key,val);
//key:數據庫的字段
//val:1或true表示返回;0或false表示不返回。
!注:_id默認是1,沒指定返回該字段時,默認會返回,只有設置為0就不會返回該字段。
Query query=new BasicQuery(queryObject, fieldsObject)
方式二:(利用 Field 類)
BasicDBObject queryObject=new BasicDBObject();
Field field = new Field();
field.exclude("key1");//不返回key1,等同於把 fieldsObject.put(key,val)的val設置為0.
field.include("key2");//返回key2,等同於把 fieldsObject.put(key,val)的val設置為1.
BasicDBObject fieldsObject=field.getFieldsObject();
Query query=new BasicQuery(queryObject, fieldsObject);
/**************************** 執行template *****************************************/
collectionName:數據庫集合名,即表名。
query:上面生成的條件。
entityClass:返回的數據被映射成的類型。
返回類型 | 方法名 | example | 說明 |
<T> T | findOne(Query query, Class<T> entityClass, String collectionName) | User user=template.findOne(query, User.class, "collectionName"); | 查詢返回一條數據 |
<T> List<T> | find(Query query, Class<T> entityClass, String collectionName) | List<User> users= template.find(query, User.class, "collectionName"); | 查詢滿足條件的所有 |
<T> List<T> | findAll(Class<T> entityClass, String collectionName) | List<User> users= template.findAll(User.class, "collectionName"); | 查詢該張表所有數據 |
<T> List<T> | findAllAndRemove(Query query,Class<T> entityClass,String collectionName) |
||
<T> T | findAndRemove(Query query, Class<T> entityClass, String collectionName) | ||
<T> T | findAndModify(Query query, Update update, Class<T> entityClass, String collectionName) | ||
<T> T | findById(Object id, Class<T> entityClass, String collectionName) | ||
插入(新增)相關方法 | |||
void | save(Object objectToSave, String collectionName) | User user=.....; template.save(user, "collectionName"); |
|
void | insert(Object objectToSave, String collectionName) | template.insert(user, "collectionName"); | 存入單個對象 |
void | insert(Collection<? extends Object> batchToSave, String collectionName) | List<User> users=....; template.insert(users, "collectionName"); |
可以存入對象集合 |
刪除相關方法 | |||
void | dropCollection(String collectionName) | 該張表全部數據會被刪除 | |
WriteResult | remove(Query query, String collectionName) | template.remove(query, "collectionName"); | |
WriteResult | remove(Query query, Class<?> entityClass, String collectionName) | ||
修改文檔相關方法 | |||
WriteResult | updateFirst(Query query, Update update, String collectionName) | template.updateFirst(query, update, "collectionName"); | //更新符合query條件的第一條數據 |
WriteResult | updateFirst(Query query, Update update, Class<?> entityClass, String collectionName) | ||
WriteResult | updateMulti(Query query, Update update, String collectionName) | template.updateMulti(query, update, "collectionName"); | //更新符合query條件的所有數據 |
WriteResult | updateMulti(Query query, Update update, Class<?> entityClass, String collectionName) | ||
WriteResult | upsert(Query query, Update update, String collectionName) | template. upsert(query, update, collectionName); | //更新符合條件時如果不存在則會新增加一條數據,相當於執行了insert()方法 |
WriteResult | upsert(Query query, Update update, Class<?> entityClass, String collectionName) | ||
統計數據數量 |
|||
long | count(Query query, String collectionName) | ||
查詢是否存在 | |||
boolean | exists(Query query, String collectionName) | ||
/** 分組,聚合查詢group **/
方法一:利用 類 DBCollection 的 group 方法。
方法:1.DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce);
2.DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce, String finalize);
3.DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce, String finalize, ReadPreference readPreference)
- key:指定一個或多個文檔字段進行分組。和keyf兩者必須有一個
- keyf:可以接受一個javascript函數。用來動態的確定分組文檔的字段。和key兩者必須有一個
- initial:reduce中使用變量的初始化, 初始化聚合結果文檔。
- reduce:執行的reduce函數。函數需要返回值。
- cond:執行過濾的條件。
- finallize:在reduce執行完成,結果集返回之前對結果集最終執行的函數。可選的
DBCollection dbc=template.getCollection("collectionName");
String reduce = "function(doc,prev){\n" +
" prev.count+=1; \n" +
" }";
DBObject key=new BasicDBObject("state",1);
DBObject cond=query.getQueryObject();
DBObject initial=new BasicDBObject("count",0);
DBObject result = dbc.group(key, cond, initial, reduce);
Map map = result.toMap();
for (Map.Entry o : map.entrySet()) {
System.out.println(o.getKey() + " " + o.getValue());
}
方法二:aggregate聚合
方法:aggregate(Aggregation aggregation, String collectionName, Class<O> outputType);
- Aggregation aggregation:
- TypedAggregation<?> aggregation
- Class<O> outputType: 輸出類型,可以指定具體的實體類型。
- String inputCollectionName:。
- Class<?> inputType:一個輸入類型,也就是對哪個集合進行操作。
- String collectionName:
!注:Aggregation 提供了一系列mongoDB的操作方法,比如match,unwind,limit...等等。
Criteria criteria = where("...").....
AggregationOperation match = new MatchOperation(criteria);
UnwindOperation unwind = new UnwindOperation(Fields.field("values"));
SortOperation sort = new SortOperation(new Sort("..."));
AggregationOperation group = new GroupOperation(Fields.fields("deviceId")).first("deviceId").as("deviceId").count().as("value");
AggregationOperation projection = new ProjectionOperation(fields("events")).and("_id").as("deviceId").andExclude("_id");
Aggregation aggregation = Aggregation.newAggregation(match, unwind, sort, group, projection);
AggregationResults<User> aggRes = mongoTemplate.aggregate(aggregation, "collectionName", User.class);
List<User> listUser = aggRes.getMappedResults();
(一般可用 BasicDBObject 這個類接受,而不用User)