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能使用^以及$等正则表达式来识别数据库中使用 换行的每一行开始字符以及字符。 //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){
" +
" prev.count+=1;
" +
" }";
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)