您的位置:首页 > 数据库 > Mongodb

SpringData实现Mongodb的CRUD:MongoTemplate框架

2017-02-20 14:44 591 查看
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方法

返回类型方法说明应用例子
QueryaddCriteria(Criteria criteria)向query里追加查询条件query.addCriteria(Criteria.where("name").is("jack"));
Queryskip(int skip)从第skip下标数据开始查询,跳过skip下标之前的数据,小标从0开始query.skip(skip);
Querylimit(int limit)限制返回数据的最大条数query.limit(limit);
QuerywithHint(String name)做强迫索引查询用
Querywith(Sort sort)可用于排序用query.with(new Sort(Sort.Direction.DESC,"time"));

query.with(new Sort(Sort.Direction.ASC,"time"));

Querywith(Pageable pageable)Pageable对象里有skip,limit,sort信息,所以做可以分页和排序
static Queryquery(Criteria criteria)Query.query(Criteria.where("name").is("jack"));
DBObject
getQueryObject()
Fieldfields()Field 可用于做指定字段查询query.fields().include("age").exclude("name");

还可用做返回指定字段时的工具(后面有例子)

query.fields()
Criteria类常用方法

static Criteriawhere(String key)创建一个key,即查询的key键query.addCriteria(Criteria.where("name").is("jack"));
static CriteriabyExample(Object example)

()
static CriteriabyExample(Example<?> example)

()
Criteriais(Object obj)等于(==) obj query.addCriteria(Criteria.where("name").is("obj"));
Criteriaand(String key)并且,用于多个字段同时查询 query(where("key1").is("value1").and("key2").is("value2"));
Criteriane(Object o)不为 (不等于)query(where("siteId").ne(null));//查询siteId不为空的数据

query(where("name").ne("不为该值"));//

Criterialt(Object o)小于(<) query.addCriteria(Criteria.where("insert_date").gte(Date1).lte(Date2));

query.addCriteria(Criteria.where("age").gte(20).lte(30));

Criterialte(Object o)小于等于(<=)
Criteriagt(Object o)大于(>)
Criteriagte(Object o)大于等于(>=)
Criteriain(Object... co)

在...里(key对应的数据被包含在 co 里)String[] strs=... ;

query.addCriteria(Criteria.where("name").in((Object[]) strs));

或query.addCriteria(Criteria.where("name").in(obj1,obj2,obj3,...));

Criteriain(Collection<?> co)

   List<Object> collec=...;

query.addCriteria(Criteria.where("key").in(collec));

Criterianin(Object... o)

不在...里(与in相反)(略)
Criterianin(Collection<?> o)

Criteriamod(Number value, Number remainder)取模(求余)运算 ,即:key对应的值%value==remainder(求余是否等于remainder)

// {key:15} {key2:15}

query.addCriteria(Criteria.where("key").mod(10,3));

//key条件不成立;key2条件成立

Criteriaall(Object... col)

key键对应的集合包含col(all是包含关系,in是被包含关系)query.addCriteria(Criteria.where("key").all("n1","n2"));//此时key对应的值应该是集合

query.addCriteria(Criteria.where("nameList").all((Object[]) names)));

Criteriaall(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));

Criteriaexists(boolean b)查询字段是否存在(true:存在,false:不存在) query.addCriteria(Criteria.where("confirmTime").exists(false));
Criteriatype(int t)
Criterianot()取反 //注意:not().is()这样是错误的,not()后面不用跟is()

query.addCriteria(Criteria.where("number").not().lte(2)); //number<=2取反,即number>2

Criteriaregex(String re)模糊查询用(例子见下)
Criteriaregex(String re, String options)options可选值:i/m/x/s

//i表示不区分大小写

//m能使用^以及$等正则表达式来识别数据库中使用\n换行的每一行开始字符以及字符。

//x

//s如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个修饰符,点号不匹配换行符。

Criteriaregex(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)
Criteriaalike(Example<?> sample)
CriteriawithinSphere(Circle circle)
Criteriawithin(Shape shape)
Criterianear(Point point)
CriterianearSphere(Point point)
Criteriaintersects(GeoJson geoJson)
CriteriamaxDistance(double maxDistance)
CriteriaminDistance(double minDistance)
booleanlastOperatorWasNot()
PatterntoPattern(String regex, String options)
StringgetKey()
DBObjectgetCriteriaObject()
DBObjectgetSingleCriteriaObject()
BasicDBListcreateCriteriaList(Criteria[] criteria)
voidsetValue(DBObject dbo, String key, Object value)
booleancreateNearCriteriaForCommand(String command, String operation, double maxDistance)
booleansimpleCriteriaEquals(Criteria left, Criteria right)
booleanisEqual(Object left, Object right)
inthashCode()
static booleanrequiresGeoJsonFormat(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:返回的数据被映射成的类型。

MongoTemplate提供的一些常用crud方法

返回类型方法名example说明
<T> TfindOne(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> TfindAndModify(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) 该张表全部数据会被删除
WriteResultremove(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)
查询是否存在
booleanexists(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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: