1.sql对比
2.sql示例
文档内容
3.addToSet
采用追加的方式更新
public void updateWf603(WF603Bean wF603Bean){
AtomicBoolean needUpdate = new AtomicBoolean(wF603Bean.getTaskState().equals(TaskStateEnum.COMPLETED.getId()) || wF603Bean.getTaskState().equals(TaskStateEnum.REVOKED.getId()));
//与wf601的update需要整合
Query query = new Query();
query.addCriteria(Criteria.where("processInstanceId").is(wF603Bean.getProcessInstanceId()));
Update update = new Update();
//反射循环取实体
Field[] declaredFields = wF603Bean.getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
Object value = null;
try {
value = field.get(wF603Bean);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
String name = field.getName();
if(name.equals("wf603BeanList")){//如果是list 就采用追加的方式
List<WF601Bean> list = (List<WF601Bean>)value;
if(CollectionUtils.isNotEmpty(list)){
update.addToSet(name,list.get(0));
}
}else {
update.set(name,value);
}
}
mongoTemplate.findAndModify(query,update,WF603Bean.class);
}
db.tianyc03.update({'name':'xtt'},{$addToSet:{companies:'alibaba'}})
db.user.update({"name":"codingwhy.com"},{"$addToSet":{"hobby":{"$each":["singing","eating","dancing"]}}})
前提是被addToSet的数据是数组类型的
4.AtomicBoolean
上边的代码还有一个需要学习的点 ,原子操作AtomicBoolean
主要的原因就是因为if判断和set值是两个操作,这里面存在线程安全的问题;Atomic类型的变量就不存在这种问题
compareAndSet CAS原子操作
AtomicBoolean needUpdate = new AtomicBoolean(wF603Bean.getTaskState().equals(TaskStateEnum.COMPLETED.getId()) || wF603Bean.getTaskState().equals(TaskStateEnum.REVOKED.getId()));
public void init()
{
if( needUpdate.compareAndSet(false, true) )
{
//意思是如果needUpdate为false 就给needUpdate赋值为true
}
}
5.不在循环中操作数据库的方法insertAll
public void insert(PlatException platException) {
List<PlatException> list = new ArrayList<>();
list.add(platException);
mongoTemplate.insertAll(list);
}
6.Criteria的拼接
不管是 andOperator 还是 orOperator ,入参都是数组
所以就是or组成一堆(数组),and组成一堆(数组),整个拼成一个大的数组,往最后的Criteria里边放
7.mongodb开启事务
在配置类里(@Configuration)中配置bean-----MongoTransactionManager
https://blog.youkuaiyun.com/weixin_42322445/article/details/89358688
8.updateFirst(更新第一个匹配的), updateMulti(更新所有匹配的)
9.@slf4j注解和log4j配置文件的关系
slf4j仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已,所以单独的slf4j是不能工作的,必须搭配其他具体的日志实现方案,比如log4j或者log4j2
10.特殊类型:bigdecimal
需要配置读写类型转换(类型转换器)
https://blog.youkuaiyun.com/nrsc272420199/article/details/88833244
11.控制字段显示和不显示
不显示0,显示1
结果集只显示s和ss字段
db.getCollection("xytest").find({"s":1},{"s":1,"ss":1})
结果集不显示s和ss字段
db.getCollection("xytest").find({"s":1},{"s":0,"ss":0})
注意:0和1只能出现一个 否则报错
例外:排除Id时,可以
db.getCollection("xytest").find({"s":1},{"s":1,"_id":0})
12.in查询和or查询
in
db.getCollection('xytest').find(
{"ss":{"$in":[2,3]}}
)
or
db.getCollection('xytest').find(
{"$or":[{"ss":2},{"ss":3}]}
)
13.exitst
查询存在或者不存在某个字段的结果集
db.getCollection('xytest').find(
{ "aa":{"$exists":true} }
)
存在true 不存在false
14.not 取反
查询ss不大于7的结果集(这里的结果集不仅仅包括小于等于7的,还包括没有ss字段的结果集)
db.getCollection('xytest').find(
{"ss":{"$not":{"$gt":7}}}
)
15.排序
sort({}) -1倒序,1正序
db.getCollection('xytest').find(
{"ss":{"$not":{"$gt":7}}}
).sort({"sss":-1})
16.分页
skip() limit()
db.getCollection('xytest').find(
{"ss":{"$not":{"$gt":7}}}
).sort({"sss":1}).skip(3).limit(2)
17.查询数组类型的第几个数据
根据下标查询
如下为查询baohan数组第二个 为"包含2"
db.getCollection('xytest').find({"baohan.1":"包含2"})
18.给数组字段分页 silice
不是用skip和limit了 与查询条件同级 slice后边的数组分别代表skip几个 limit几个
19.模糊查询 regex
db.getCollection('xytest').find({"baohan":{"$regex":"含"}})
20.什么是对象数组
如下的wf603BeanList,数组中每一个json都是一个对象,都有自己的属性和属性值
{
"_id" : "14e9abfd-171d-11ea-89bb-00ffaabbccdd",
"wf603BeanList" : [
{
"_id" : "14f96392-171d-1-89bb-00ffaabbccdd",
"title" : "第一",
"reason" : "同意",
"withdraw" : false,
"taskDefinitionKey" : "diyi",
"isMultiInstance" : false
},
{
"_id" : "14f96392-171d-11ea-89bb-00ffaabbccdd",
"time" : "2019-12-05",
"assigneeOrgName" : "市中心",
"taskDefinitionKey" : "duoshili",
"isMultiInstance" : true
}
],
"_class" : "com.wish.plat.approval.api.bean.WF603Bean"
}
21.什么情况用mongo / mysql
关系型数据库适合存储结构化数据,如用户的帐号、地址:
1)这些数据通常需要做结构化查询,比如join,这时候,关系型数据库就要胜出一筹
2)这些数据的规模、增长的速度通常是可以预期的
3)事务性、一致性
NoSQL适合存储非结构化数据,如文章、评论:
1)这些数据通常用于模糊处理,如全文搜索、机器学习
2)这些数据是海量的,而且增长的速度是难以预期的,
3)根据数据的特点,NoSQL数据库通常具有无限(至少接近)伸缩性
4)按key获取数据效率很高,但是对join或其他结构化查询的支持就比较差
22.读写效率高得另一个原因
对于mysql来说,需要通过关联表存储得数据,可以在mongo存储一个数组型得字段,查询时不用查询关联表,效率高
可以以20.对象数组为例
23.group by
与aggregate一起使用,并且 aggregate后边跟的是一个数组
db.getCollection('xytest').aggregate([{"$group":{"_id":"$ss", "count":{"$sum":1}}}])
相当于mysql的
SELECT createUserId,count(createUserId) as num FROM pf1001 GROUP BY createUserId
mongo的 "count":{"$sum":1} 就是同级结果数量
分类统计的查询条件用match 在aggregate的数组中,查询条件 与 分类统计条件 与 排序条件 按顺序同级
处理顺序
db.getCollection('xytest').aggregate
([{"$match":{"ss":28}},
{"$group":{"_id":"$ss", "count":{"$sum":1}}},
{"$sort":{"ss":-1}}])
java代码中的写法与此sql类似
Aggregation aggregation4 =
Aggregation.newAggregation(
Aggregation.match(criteriaEnd),
Aggregation.group("processDefinKey").count().as("resultCount"),
Aggregation.sort(new Sort(Sort.Direction.DESC,"processDefinKey"))
);
24.insertOne和insertMany
insertOne跟着的是一个对象 insertMany跟着的是一个数组 数组中的多个对象用逗号,隔开
平时用的insert相当于insertOne
db.getCollection('xytest').insertMany(
[
{
"_id" : "cdab26709c7",
"ss" : 2.0,
"sss" : 3.0,
"s" : 7.0
},
{
"_id" : "111111111111",
"ss" : 2.0,
"sss" : 3.0,
"s" : 7.0
}
]
)
db.getCollection('xytest').insertOne(/* 1 */
{
"_id" : "c0e0dabb26709c7",
"ss" : 2.0,
"sss" : 3.0,
"s" : 7.0
}
)
25.mongo的sql中的deleteOne和deleteMany
deleteOne是删除符合条件的第一条 deleteMany是删除所有符合条件的数据
remove相当于deleteMany
可以这样删除,删除查询结果第一个
var ss = db.getCollection('xytest').find({"bbbbb" : "a"}).sort({"int":-1})[0]
db.getCollection('xytest').deleteOne(ss)
26.替换更新update和操作符更新$set
操作符更新更快
db.getCollection('xytest').update
({ "_id" : ObjectId("5e6ce130c0e03dabb26709cc")},{"baohan":"0"})
db.getCollection('xytest').update
({ "_id" : ObjectId("5e6ce130c0e03dabb26709cc")},{"$set":{"baohan":"0"}})
27.怎么更新多条 multi
默认false 只更新第一条 为true时 更新所有
update中的顺序是 查询条件 更新结果(把什么更新成什么) 操作限制 (更新一条还是多条,不存在时是否插入)
28.数据不存在时直接插入 upsert
如果查询条件中的数据不存在那么直接插入更新结果
如果有“baohan”为"1"的数据,就把这条数据的"baohan"字段更新为"0"
如果没有,就插入一条"baohan"为"0"的记录
结果中的new record说明新插入一条记录
29.mongo居然可以删除字段 unset 还可以改字段名 rename
db.getCollection('xytest').update({ "baohan":"0"},{"$unset":{ "baohan":""}})
删除之后可以通过$exists查询验证
改字段名 rename
db.getCollection('xytest').update({ "aa":"a"},{"$rename":{ "aa":"bbbbb"}})
同样可以用exist验证