- 前言
- springboot整合MongoDB
- pom版本依赖信息
- properties文件配置
- mongodb与springboot整合config配置
- 对mongoTemplate做进一步封装
- 创建模板接口
- 增加MongoDbTemplate对IDbTemplate实现类
- 查询转换核心
- 后续
业务需要使用到MongoDB,因此将整合过程一一记录。由于原生template操作并不直观,以及操作方式与传统sql数据库有差别。这里将template做进一步封装,使其操作风格尽可能与传统数据DAO一致,对上层屏蔽数据库操作的差异。
springboot整合MongoDB pom版本依赖信息org.springframework.boot spring-boot-starter-parent 2.2.5.RELEASE
properties文件配置org.springframework.data spring-data-mongodb 2.1.1.RELEASE
spring.data.mongo.uri=mongodb://localhost:27017/test 若有密码认证则配置如下 spring.data.mongo.uri=mongodb://username:password@localhost:27017/datasourcemongodb与springboot整合config配置
@Configuration
public class MongoDBConfig {
@Value("${spring.data.mongo.uri}")
private String uri;
@Bean
public MappingMongoConverter mappingMongoConverter(MongoMappingContext mongoMappingContext) {
DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(dbFactory());
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
// 去除写入mongodb时的_class字段
return converter;
}
@Bean
public MongoDbFactory dbFactory() {
return new SimpleMongoClientDbFactory(uri);
}
}
对mongoTemplate做进一步封装
目的对上层使用者屏蔽不同的数据的操作差异。
创建模板接口package com.onecloud.wm.core.db;
import com.onecloud.wm.core.db.mongo.MongoFilter;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import java.util.List;
import java.util.Map;
public interface IDbTemplate {
boolean batchSave(List list, String collectionName);
boolean save(Object obj);
boolean remove(Object obj);
boolean update(Class objClazz, Map valueMap, Map updateMap);
Object findUniqueBy(Class objClazz, Map valueMap);
long count(Class objClazz, Map valueMap);
List find(Class objClazz, Map valueMap);
PageImpl findPage(Class objClazz, PageRequest pageRequest, Map valueMap);
List find(Class objClazz, List filters);
}
增加MongoDbTemplate对IDbTemplate实现类
@Primary注解用于如果有多个实现类,告知spring优先使用此实现
@Component将该实现类交给sping容器管理
以obj对象形式保存数据。将对象的属性为key,以需要属性数据位value组装成map,对数据进行改查操作。
将map以及将自定义MongoFilter转成MongoDB规范查询语言。具体核心代码如下文 查询转换核心
package com.onecloud.wm.core.db.mongo;
import com.onecloud.wm.core.db.IDbTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.List;
import java.util.Map;
@Component
@Primary
public class MongoDbTemplate implements IDbTemplate {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public boolean batchSave(List list, String collectionName) {
mongoTemplate.insert(list, collectionName);
return true;
}
@Override
public boolean save(Object obj) {
mongoTemplate.save(obj);
return true;
}
@Override
public boolean remove(Object obj) {
return mongoTemplate.remove(obj).getDeletedCount() > 0;
}
@Override
public boolean update(Class objClazz, Map valueMap, Map updateMap) {
Criteria criteria = MongoQueryTool.buildCriteria(valueMap);
Assert.notNull(criteria, "Criteria must not be null!");
Query query = Query.query(criteria);
Update update = MongoQueryTool.buildUpdate(updateMap);
return mongoTemplate.updateFirst(query, update, objClazz).getModifiedCount() > 0;
}
@Override
@SuppressWarnings("unchecked")
public Object findUniqueBy(Class objClazz, Map valueMap) {
Criteria criteria = MongoQueryTool.buildCriteria(valueMap);
Assert.notNull(criteria, "Criteria must not be null!");
Query query = Query.query(criteria);
return mongoTemplate.findOne(query, objClazz);
}
@Override
public long count(Class objClazz, Map valueMap) {
Criteria criteria = MongoQueryTool.buildCriteria(valueMap);
Assert.notNull(criteria, "Criteria must not be null!");
Query query = Query.query(criteria);
return mongoTemplate.count(query, objClazz);
}
@Override
@SuppressWarnings("unchecked")
public List find(Class objClazz, Map valueMap) {
Criteria criteria = MongoQueryTool.buildCriteria(valueMap);
Assert.notNull(criteria, "Criteria must not be null!");
Query query = Query.query(criteria);
return mongoTemplate.find(query, objClazz);
}
@Override
@SuppressWarnings("unchecked")
public PageImpl findPage(Class objClazz, PageRequest pageRequest, Map valueMap) {
Criteria criteria = MongoQueryTool.buildCriteria(valueMap);
Assert.notNull(criteria, "Criteria must not be null!");
long count = count(objClazz, valueMap);
Query query = Query.query(criteria);
query.with(pageRequest);
List list = mongoTemplate.find(query, objClazz);
return new PageImpl(list, pageRequest, count);
}
@Override
@SuppressWarnings("unchecked")
public List find(Class objClazz, List filters) {
Criteria criteria = MongoQueryTool.buildCriteria(filters);
Assert.notNull(criteria, "Criteria must not be null!");
Query query = Query.query(criteria);
return mongoTemplate.find(query, objClazz);
}
}
查询转换核心
MongoFilter具体类
package com.onecloud.wm.core.db.mongo;
public class MongoFilter {
private Object matchValue = null;
private MatchType matchType = null;
private String propertyName = null;
public MongoFilter() {}
public MongoFilter(String propName, MatchType matchType, Object value) {
this.matchType = matchType;
this.propertyName = propName;
this.matchValue = value;
}
public MatchType getMatchType() {
return matchType;
}
public Object getMatchValue() {
return matchValue;
}
public String getPropertyName() {
return propertyName;
}
public enum MatchType {
EQ, LIKE, LT, GT, LE, GE, IN, NE
}
}
查询转换工具类
package com.onecloud.wm.core.db.mongo;
import com.onecloud.model.util.CommonTool;
import com.onecloud.wm.core.db.mongo.MongoFilter.MatchType;
import com.onecloud.utils.AssertUtils;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Update;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class MongoQueryTool {
public static Criteria buildCriteria(Map paramMap) {
if (paramMap == null) {
return null;
}
Criteria criteria = null;
int i = 0;
for (String key : paramMap.keySet()) {
Object value = paramMap.get(key);
if (i == 0) {
if (value instanceof Collection) {
criteria = Criteria.where(key).in(value);
} else {
criteria = Criteria.where(key).is(value);
}
} else {
if (value instanceof Collection) {
criteria.and(key).in(value);
} else {
criteria.and(key).is(value);
}
}
}
return criteria;
}
public static Criteria buildCriteria(List filters) {
if (CommonTool.isNullOrEmpty(filters)) {
return null;
}
Criteria criteria = new Criteria();
for (MongoFilter filter : filters) {
criteria
.andOperator(buildCriterion(filter.getPropertyName(), filter.getMatchValue(), filter.getMatchType()));
}
return criteria;
}
public static Update buildUpdate(Map paramMap) {
if (paramMap == null) {
return null;
}
Update update = new Update();
for (String key : paramMap.keySet()) {
Object value = paramMap.get(key);
update.set(key, value);
}
return update;
}
public static Criteria buildCriterion(String propertyName, Object propertyValue, MatchType matchType) {
AssertUtils.hasText(propertyName, "propertyName不能为空");
Criteria criteria = new Criteria(propertyName);
// 根据MatchType构造criterion
switch (matchType) {
case EQ:
criteria = criteria.is(propertyValue);
break;
case NE:
criteria = criteria.ne(propertyValue);
break;
case LIKE:
String pattern = ".*" + propertyValue + ".*";
criteria = criteria.regex(pattern);
break;
case LE:
criteria = criteria.lte(propertyValue);
break;
case LT:
criteria = criteria.lt(propertyValue);
break;
case GE:
criteria = criteria.gte(propertyValue);
break;
case GT:
criteria = criteria.gt(propertyValue);
break;
case IN:
criteria = criteria.in(propertyValue);
break;
default:
break;
}
return criteria;
}
}
后续
可进一步封装MongoDBDao层,以及MongoDBService,完成基础的实现。后续扩展新的表,可直接实继承MongoDBService实现类,使用默认操作
见:像传统数据库DAO一样操作MongoDB



