前言: 你用Spring Boot不代表你真的在做微服务
>_<
事情的起因很简单,看到公司的项目里的代码 -_-更新MongoDB记录的方法采用的是:
1、根据条件查找出符合更新条件的某一条记录;
2、将需要更新的内容(jsonString参数传入)用Gson转成一个实体类,然后用MongoTemplate的Save(实体类对象)方法完成对数据的更新。
public boolean saveAssetConfiguration(String jsonProject) {
String projectName = getProjectName(jsonProject);
String assetConfigValue =getProjectAssets(jsonProject);
Query query=new Query(Criteria.where("projectName").is(projectName));
ProjectBasicInfo projectBasicInfo = mongoTemplate.findOne(query, ProjectBasicInfo.class);
ProjectConfig projectConfig = mongoTemplate.findOne(query , ProjectConfig.class);
if (projectBasicInfo == null){
return false;
}
if (projectConfig == null){
projectConfig = new ProjectConfig();
projectConfig.setProjectName(projectName);
}
List assets = new ArrayList();
try {
assets = gson.fromJson(assetConfigValue, assets.getClass());
} catch(JsonSyntaxException e) {
e.printStackTrace();
return false;
}
projectConfig.setAssets(assets);
mongoTemplate.save(projectConfig);
然后就在考虑,如果有多条记录符合条件,并且需要更新该肿么办?
于是上网搜索到MongoTemplate有更新方法:mongoTemplate.updateMulti(),于是决定用下这个方法,但是网上各种资料都是很简单的示例,例如:
mongoTemplate. updateMulti (newQuery(Criteria.where("cname").is("zcy ")), new Update().set("date", "2015-08-08"), collectionName);
这样的示例,看起来好像只能一个一个输入
最后研究出来,new update的set方法还可以这样复杂的用:
1、定义一个实体类对应MongoDB的一个Colllection。
testjia是mongodb collection的名字,@Field的注解是用来映射testjia表里设置的字段和代码里变量名不一致的情况,如果你能保证你表里字段名称和实体类定义的属性名称是一致的,那么你可以不用@Field这个注解。
//testjia是mongodb collection的名字
@Document(collection = "testjia")
public class Testjia {
//@Field的注解是用来
@Field("name")
String nm;
String data;
省略掉getter和setter
}
然后我们就可以用下面的方式来更新多条符合条件的记录,如下:
//Testjia是跟mongodb collection表名一致的实体类。
mongoTemplate.updateMulti(new Query(Criteria.where("nm").is(name)),new Update().set("data",new Gson().fromJson(value,type)),Testjia.class)
set("data",new Gson().fromJson(value,type)),可以直接插入复杂的json, 而不需要把json转成实体类对象通过insert或者save方式插入。
其中value表示json字符串或者是json数组
例如,简单json格式:
{"name":"jia","data":"test"}
data对应的json数组格式:
{"name":"jia","data":[{"test":"test"}]}
需要注意的是这里的type是什么意思?
Gson为我们提供了TypeToken来实现对泛型的支持,所以,如果我们遇到json数组的时候,就需要写成这样:
Type type = new TypeToken>(){}.getType();
如果是简单的json格式,就写成这样:
Type type = new TypeToken
这样就可以根据不同的json格式,对data这个字段进行数据更新。
更多测试代码如下,有些代码有点傻。。。
public int modifyMulti(String name){
//更新很多条记录
Type type = null;
int n = 0;
String inputString = "{\"projectName\":\"jiatest02\",\n" +
"\"assets\":[{\"basicInformation\":{\"name\":\"MC-Agent1\",\"MindSphereHostname\":\"https://mindconnectcom.apps.mindsphere.io\",\"MindConnectIPAddress\":\"192.168.0.100\",\"Port\":\"123\",\"AgentID\":\"123\",\"OBK\":\"123\",\"maxBufferPackets\":\"123\",\"uploadTimer\":\"123\",\"onboardStatus\":\"Not Onboard\"},\n" +
"\"aspects\":[{\"aspectName\":\"New Aspect 1\",\"readingCycle\":\"5s\",\"dataSource\":\"\",\"dataSourceIPAddress\":\"10.10.10.10\",\"dataSourceProtocol\":\"S999\",\"adaptorType\":\"adaptor\",\"configFileId\":\"88\",\n" +
"\"variables\":[{\"address\":\"I0.1\",\"dataType\":\"Bool\",\"key\":\"TV_2\",\"name\":\"左极限位\",\"type\":\"DataPoint\",\"unit\":\"One\",\"converter\":\"testnew\"}]}]\n" +
"}]\n" +
"}";
try{
HashMap hashMap = new Gson().fromJson(inputString,HashMap.class);
System.out.println("assets: " + hashMap.get("assets"));
String value = new Gson().toJson(hashMap.get("assets"));
if (value.indexOf("[")!=-1){
type = new TypeToken>(){}.getType();
}else{
type = new TypeToken
参考文献:
你真的知道Gson吗