Spring整合MongoDB增删改查及批量新增修改
Posted Lossdate
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring整合MongoDB增删改查及批量新增修改相关的知识,希望对你有一定的参考价值。
简单封装了下基础的增删改查以及批量操作,方便后续的拓展
一、配置
-
applicationContext.xml
#beans添加 xmlns:mongo="http://www.springframework.org/schema/data/mongo" http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd #配置 <mongo:mongo id="mongo" replica-set="$mongo.hostPort"> <!-- 一些连接属性的设置 --> <mongo:options connections-per-host="$mongo.connectionsPerHost" threads-allowed-to-block-for-connection-multiplier="$mongo.threadsAllowedToBlockForConnectionMultiplier" connect-timeout="$mongo.connectTimeout" max-wait-time="$mongo.maxWaitTime" auto-connect-retry="$mongo.autoConnectRetry" socket-keep-alive="$mongo.socketKeepAlive" socket-timeout="$mongo.socketTimeout" slave-ok="$mongo.slaveOk" write-number="1" write-timeout="0" write-fsync="true" /> </mongo:mongo> <mongo:db-factory dbname="database" mongo-ref="mongo" /> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongo" ref="mongo" /> <constructor-arg name="databaseName" value="test" /> </bean>
mongo.hostPort=127.0.0.1:27017 mongo.connectionsPerHost=8 mongo.threadsAllowedToBlockForConnectionMultiplier=4 #连接超时时间 mongo.connectTimeout=1000 #等待时间 mongo.maxWaitTime=1500 mongo.autoConnectRetry=true mongo.socketKeepAlive=true #Socket超时时间 mongo.socketTimeout=1500 mongo.slaveOk=true
二、代码整合
-
接口
/* * BaseEntity 为基础实体类,参数随意 */ public interface BaseMongoInterface<T extends BaseEntity> /** * 按 id 查询 * @param clazz Class * @param id 查询的id * @param collectionName collectionName * @return Entity */ T get(final Class<T> clazz, final String id, final String collectionName); /** * insert * @param entity new Entity * @param collectionName collectionName * @return 1 */ int insert(final T entity, final String collectionName); /** * update * @param clazz Class * @param id update 的 id * @param needUpdateParams 需要更新的字段和值 * @param collectionName collectionName * @return count */ int update(final Class<T> clazz, String id, Map<String, Object> needUpdateParams, final String collectionName); /** * find * @param clazz Class * @param whereParams 查询条件 * @param sortParam 排序字段 * @param sortWay 排序方式("ASC", "DESC") * @param collectionName collectionName * @return List<Entity> */ List<T> find(final Class<T> clazz, Map<String, Object> whereParams, String sortParam, String sortWay, final String collectionName); /** * find one * @param clazz Class * @param whereParams 查询条件 * @param sortParam 排序字段 * @param sortWay 排序方式("ASC", "DESC") * @param collectionName collectionName * @return Entity */ T findOne(final Class<T> clazz, Map<String, Object> whereParams, String sortParam, String sortWay, final String collectionName); /** * 根据实体 批量 insert * @param list 批量插入的实体 list * @param collectionName collectionName * @return count */ int insertBatch(final List<T> list, final String collectionName); /** * 根据查询条件 批量 update * @param clazz Class * @param whereParams 查询条件 * @param needUpdateParams 需要更新的字段 * @param collectionName collectionName * @return count */ int updateBatch(final Class<T> clazz, Map<String, Object> whereParams, Map<String, Object> needUpdateParams, final String collectionName); /** * 根据实体 批量 update * @param list 需要 update 的实体 list * @param collectionName collectionName * @param upsert 实体 id 不存在的情况是否需要插入 * @param needNullParam 是否更新实体内为null的字段 * @return count */ int updateBatch(final List<T> list, final String collectionName, boolean upsert, boolean needNullParam); /** * 分页查询 * @param clazz Class * @param whereParams 查询条件 * @param sortParam 排序字段 * @param sortWay 排序方式("ASC", "DESC") * @param collectionName collectionName * @param limitStart 起始 * @param pageSize 查询多少条 * @return List<Entity> */ List<T> page(final Class<T> clazz, Map<String, Object> whereParams, String sortParam, String sortWay, final String collectionName, int limitStart, int pageSize); /** * 查询数量 * @param clazz Class * @param whereParams 查询条件 * @param collectionName collectionName * @return count */ long count(final Class<T> clazz, Map<String, Object> whereParams, final String collectionName); /** * 删除 * @param clazz Class * @param whereParams 查询条件 * @param collectionName collectionName * @return count */ int remove(final Class<T> clazz, Map<String, Object> whereParams, final String collectionName);
-
批量更新工具类
public class BathUpdateOptions private Query query; private Update update; private boolean upsert = false; private boolean multi = false; public BathUpdateOptions() public BathUpdateOptions(Query query, Update update, boolean upsert, boolean multi) this.query = query; this.update = update; this.upsert = upsert; this.multi = multi; //getter and setter ...
public class BatchUpdateHelper public static <T> Map<String, Object> beanToMap(T bean, boolean needNullParam) Map<String, Object> map = Maps.newHashMap(); if (bean != null) BeanMap beanMap = BeanMap.create(bean); for (Object key : beanMap.keySet()) if(!needNullParam && beanMap.get(key) == null) continue; map.put(key + "", beanMap.get(key)); return map; public static int bathUpdate(MongoTemplate mongoTemplate, List<BathUpdateOptions> options, String collectionName) return doBathUpdate(mongoTemplate.getCollection(collectionName), collectionName, options, true); private static int doBathUpdate(DBCollection dbCollection, String collName, List<BathUpdateOptions> options, boolean ordered) DBObject command = new BasicDBObject(); command.put("update", collName); List<BasicDBObject> updateList = new ArrayList<>(); for (BathUpdateOptions option : options) BasicDBObject update = new BasicDBObject(); update.put("q", option.getQuery().getQueryObject()); update.put("u", option.getUpdate().getUpdateObject()); update.put("upsert", option.isUpsert()); update.put("multi", option.isMulti()); updateList.add(update); command.put("updates", updateList); command.put("ordered", ordered); CommandResult commandResult = dbCollection.getDB().command(command); return Integer.parseInt(commandResult.get("n").toString());
-
功能实现
@Component public abstract class BaseMongoInterfaceImpl<T extends BaseEntity> implements BaseMongoInterface<T> @Autowired private MongoTemplate mongoTemplate; @Override public T get(@NotNull Class<T> clazz, @NotNull String id, @NotNull String collectionName) return mongoTemplate.findById(id, clazz, collectionName); @Override public int insert(@NotNull T entity, @NotNull String collectionName) mongoTemplate.insert(entity, collectionName); return 1; @Override public int update(@NotNull Class<T> clazz, @NotNull String id, @NotNull Map<String, Object> needUpdateParams, @NotNull String collectionName) Query query = new Query(); query.addCriteria(Criteria.where("_id").is(id)); Update update = new Update(); needUpdateParams.forEach(update::set); WriteResult writeResult = mongoTemplate.updateFirst(query, update, clazz, collectionName); return writeResult.getN(); @Override public List<T> find(@NotNull Class<T> clazz, Map<String, Object> whereParams, String sortParam, String sortWay, @NotNull String collectionName) Query query = getFindQuery(whereParams, sortParam, sortWay); return mongoTemplate.find(query, clazz, collectionName); private Query getFindQuery(Map<String, Object> whereParams, String sortParam, String sortWay) Query query = new Query(); if (whereParams != null && whereParams.size() > 0) AtomicReference<Criteria> criteria = new AtomicReference<>(); AtomicInteger index = new AtomicInteger(); whereParams.forEach((k,v) -> if(k.equals("id")) k = "_id"; if(index.get() == 0) criteria.set(Criteria.where(k).is(v)); else criteria.get().and(k).is(v); index.getAndIncrement(); ); query.addCriteria(criteria.get()); if(StringUtils.isNotBlank(sortParam)) if(sortWay == null) sortWay = "ASC"; if("ASC".equals(sortWay)) query.with(new Sort(new Sort.Order(Sort.Direction.ASC, sortParam))); else query.with(new Sort(new Sort.Order(Sort.Direction.DESC, sortParam))); return query; @Override public T findOne(@NotNull Class<T> clazz, @NotNull Map<String, Object> whereParams, String sortParam, String sortWay, @NotNull String collectionName) Query query = getFindQuery(whereParams, sortParam, sortWay); query.skip(0); query.limit(1); List<T> dataList = mongoTemplate.find(query, clazz, collectionName); return dataList.isEmpty() ? null : dataList.get(0); /** * 批量操作批次最大数 */ public static final Integer BATCH_CEILING = 300; @Override public int insertBatch(@NotNull List<T> list, @NotNull String collectionName) List<List<T>> batchList = new ArrayList<>(); int len = BATCH_CEILING; if(!list.isEmpty()) if(list.size() > len) //优化insertBatch,切割处理 int size = list.size(); int count = (size + len - 1) / len; for (int i = 0; i < count; i++) List<T> subList = list.subList(i * len, (Math.min((i + 1) * len, size))); batchList.add(subList); if(batchList.size() > 0) for (List<T> subList : batchList) mongoTemplate.insert(subList, collectionName); else mongoTemplate.insert(list, collectionName); return list.size(); @Override public int updateBatch(@NotNull Class<T> clazz, @NotNull Map<String, Object> whereParams, @NotNull Map<String, Object> needUpdateParams, @NotNull String collectionName) Query query = new Query(); AtomicReference<Criteria> criteria = new AtomicReference<>(); AtomicInteger index = new AtomicInteger(); whereParams.forEach((k,v) -> if(index.get() == 0) criteria.set(Criteria.where(k).is(v)); else criteria.get().and(k).is(v); index.getAndIncrement(); ); query.addCriteria(criteria.get()); Update update = new Update(); needUpdateParams.forEach(update::set); WriteResult writeResult = mongoTemplate.updateMulti(query, update, clazz, collectionName); return writeResult.getN(); @Override public int updateBatch(@NotNull List<T> list, @NotNull String collectionName, @NotNull boolean upsert, @NotNull boolean needNullParam) int result = 0; List<BathUpdateOptions> optionsList = new ArrayList<>(); Map<String, Object> needUpdateParams; for (T entity : list) if(StringUtils.isBlank(entity.getId())) continue; Query query = new Query(); query.addCriteria(Criteria.where("_id").is(entity.getId())); entity.setId(null); needUpdateParams = BatchUpdateHelper.beanToMap(entity, needNullParam); Update update = new Update(); needUpdateParams.forEach(update::set); optionsList.add(new BathUpdateOptions(query, update, upsert, true)); List<List<BathUpdateOptions>> batchList = new ArrayList<>(); int len = BATCH_CEILING; if(!optionsList.isEmpty()) if(optionsList.size() > len) //优化insertBatch,切割处理 int size = optionsList.size(); int count = (size + len - 1) / len; for (int i = 0; i < count; i++) List<BathUpdateOptions> subList = optionsList.subList(i * len, (Math.min((i + 1) * len, size))); batchList.add(subList); if(batchList.size() > 0) for (List<BathUpdateOptions> subList : batchList) result += BatchUpdateHelper.bathUpdate(mongoTemplate, subList, collectionName); else result = BatchUpdateHelper.bathUpdate(mongoTemplate, optionsList, collectionName); return result; @Override public List<T> page(@NotNull Class<T> clazz, Map<String, Object> whereParams, String sortParam, String sortWay, @NotNull final String collectionName, @NotNull int limitStart, @NotNull int pageSize) Query query = getFindQuery(whereParams, sortParam, sortWay); query.skip(limitStart); query.limit(pageSize); return mongoTemplate.find(query, clazz, collectionName); @Override public long count(@NotNull Class<T> clazz, @NotNull Map<String, Object> whereParams, @NotNull final String collectionName) Query query = getFindQuery(whereParams, null, null); return mongoTemplate.count(query, clazz, collectionName); @Override public int remove(@NotNull Class<T> clazz, @NotNull Map<String, Object> whereParams, @NotNull final String collectionName) Query query = getFindQuery(whereParams, null, null); WriteResult remove = mongoTemplate.remove(query, clazz, collectionName); return remove.getN();
以上是关于Spring整合MongoDB增删改查及批量新增修改的主要内容,如果未能解决你的问题,请参考以下文章
04-springboot整合elasticsearch初识-简单增删改查及复杂排序,分页,聚合操作