第一次接触mongodb,在使用MongoTemplate的过程中,鉴于太多冗余代码以及开发效率,故自己做了一个简单的crud封装供公司项目中使用

目录

定义一个接口IMongoBaseService

接口实现MongoBaseServiceImpl

MongodbUtil工具类

具体使用


定义一个接口IMongoBaseService

public interface IMongoBaseService<T> {/*** 单个插入* TODO _id已存在会做覆盖,原本有值的字段可能会被置null* @param entity*/T insert(T entity);/*** 批量插入* TODO _id已存在会做覆盖,原本有值的字段可能会被置null* @param entityList*/List<T> insertBatch(Collection<T> entityList);/*** 单个更新* TODO 根据id进行更新* TODO 没有任何一个字段做更新不做处理, 否则会将除_id外的字段都置null* @param entity* @return*/boolean updateById(T entity);/*** 批量更新* TODO 根据id进行更新* TODO 没有任何一个字段做更新不做处理, 否则会将除_id外的字段都置null* @param entityList* @return*/long updateBatchById(Collection<T> entityList);/*** 按条件更新* TODO 自定义条件* @param query* @param update* @return*/long update(Query query, Update update);/*** 删除* TODO 根据id进行删除* @param id* @return*/boolean deleteById(Object id);/*** 批量删除* TODO 根据id进行删除* @param ids* @return*/long deleteByIds(Collection<? extends Serializable> ids);/*** 单个查询* TODO 根据id进行查询* @param id* @return*/T getById(Object id);/*** 批量查询* TODO 根据id进行查询* @param ids* @return*/List<T> listByIds(Collection<? extends Serializable> ids);/*** 按实体条件查询* TODO 非空字段会组装成条件进行查询* TODO 只支持(基本数据类型)字段=条件查询, 参考: MongodbUtil.isPrimitive* TODO 不支持排序* TODO 不支持分页* @param entity* @return*/List<T> query(T entity);/*** 条件查询* TODO 自定义条件* TODO 支持分页* TODO 支持排序* @param query* @return*/List<T> query(Query query);/*** 查询一条数据* TODO 自定义条件* @param query* @return*/T getOne(Query query);
}

接口实现MongoBaseServiceImpl

@Service
public class MongoBaseServiceImpl<T> implements IMongoBaseService<T> {public final MongoTemplate mongoTemplate = SpringUtil.getBean(MongoTemplate.class);/*** 获取需操作的实体类class* @return*/public Class<T> getEntityClass() {return ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);}@Overridepublic T insert(T entity) {// TODO mongodb中的_id统一自定义设置, 否则手动抛出异常Assert.isTrue(MongodbUtil.existDocumentId(entity), ResultCodeEnums.FAILED, "No document ID is set");return mongoTemplate.save(entity);}@Overridepublic List<T> insertBatch(Collection<T> entityList) {// TODO mongodb中的_id统一自定义设置, 否则手动抛出异常entityList.forEach(x-> Assert.isTrue(MongodbUtil.existDocumentId(x), ResultCodeEnums.FAILED, "No document ID is set"));return (List<T>) mongoTemplate.insert(entityList, getEntityClass());}@Overridepublic boolean updateById(T entity) {Query query = MongodbUtil.buildIdQuery(entity);Update update = MongodbUtil.buildUpdate(entity);// TODO 没有任何一个字段做更新不做处理, 否则会将除_id外的字段都置nullif (!update.isIsolated()) {UpdateResult upsert = mongoTemplate.updateFirst(query, update, getEntityClass());return upsert.getModifiedCount() > 0 ? true : false;}return true;}@Overridepublic long updateBatchById(Collection<T> entityList) {List<Pair<Query, Update>> pairList = MongodbUtil.getPairList(entityList);BulkWriteResult execute = mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, getEntityClass()).upsert(pairList).execute();return execute.getModifiedCount();}@Overridepublic long update(Query query, Update update) {return mongoTemplate.upsert(query, update, getEntityClass()).getModifiedCount();}@Overridepublic boolean deleteById(Object id) {Query query = MongodbUtil.buildIdQuery(id);return mongoTemplate.remove(query, getEntityClass()).getDeletedCount() > 0 ? true : false;}@Overridepublic long deleteByIds(Collection<? extends Serializable> ids) {Query query = Query.query(Criteria.where(MongodbConstant.ID).in(ids));return mongoTemplate.remove(query, getEntityClass()).getDeletedCount();}@Overridepublic T getById(Object id) {Query query = MongodbUtil.buildIdQuery(id);return mongoTemplate.findOne(query, getEntityClass());}@Overridepublic List<T> listByIds(Collection<? extends Serializable> ids) {Query query = Query.query(Criteria.where(MongodbConstant.ID).in(ids));return mongoTemplate.find(query, getEntityClass());}@Overridepublic List<T> query(T entity) {Query query = MongodbUtil.buildQuery(entity);return mongoTemplate.find(query, getEntityClass());}@Overridepublic List<T> query(Query query) {return mongoTemplate.find(query, getEntityClass());}@Overridepublic T getOne(Query query) {return mongoTemplate.findOne(query, getEntityClass());}
}

MongodbUtil工具类

public class MongodbUtil {public static Query buildIdQuery(Object obj) {if (isPrimitive(obj)) {return Query.query(Criteria.where(MongodbConstant.ID).is(obj));}else {return Query.query(Criteria.where(MongodbConstant.ID).is(getDocumentId(obj)));}}public static Update buildUpdate(Object obj) {Update update = new Update();try {Class rClass = obj.getClass();// 得到类对象Field[] fs = rClass.getDeclaredFields();// 得到属性集合for (Field f : fs) {// 遍历属性f.setAccessible(true); // 设置属性是可以访问的String name = f.getName();// 得到此属性的nameObject val = f.get(obj);// 得到此属性的value// id不作为更新字段Id id = f.getAnnotation(Id.class);if (id != null || StrUtil.equals(name, "_id")) {continue;}//                // 字段值不为null的情况下进行更新
//                if (val != null) {org.springframework.data.mongodb.core.mapping.Field field = f.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);if (field != null) {update.set(field.value(), val);}else {update.set(name, val);}
//                }}} catch (IllegalAccessException e) {e.printStackTrace();}return update;}public static Query buildQuery(Object obj) {Query query = new Query();try {Class rClass = obj.getClass();// 得到类对象Field[] fs = rClass.getDeclaredFields();// 得到属性集合for (Field f : fs) {// 遍历属性f.setAccessible(true); // 设置属性是可以访问的String name = f.getName();// 得到此属性的nameObject val = f.get(obj);// 得到此属性的value// val不为null且是基本数据类型构组装成条件if (val != null && isPrimitive(val)) {org.springframework.data.mongodb.core.mapping.Field field = f.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);// 是否指定字段query.addCriteria(Criteria.where(field != null ? field.value() : name).is(val));}}} catch (IllegalAccessException e) {e.printStackTrace();}return query;}/*** 判断一个对象是否是: 基本类型/基本类型的封装类型/字符串/其他*/private static boolean isPrimitive(Object obj) {if (obj == null) return false;// 自定义放行对象类型 TODO 待完善 继续添加新的类型if (obj instanceof String)  return true;if (obj instanceof BigInteger)  return true;if (obj instanceof BigDecimal)  return true;// 基本数据类型或封装类型放行try {return ((Class<?>) obj.getClass().getField("TYPE").get(null)).isPrimitive();} catch (Exception e) {return false;}}@SneakyThrowspublic static <T> List<Pair<Query, Update>> getPairList(Collection<T> list) {List<Pair<Query, Update>> pairList = new LinkedList<>();for (T t : list) {// 循环获取Pair对象Pair<Query, Update> pair = getPair(t);pairList.add(pair);}return pairList.stream().filter(e -> e != null).collect(Collectors.toList());}@SneakyThrowsprivate static <T> Pair<Query, Update> getPair(T t) {Query query = buildIdQuery(t);Update update = buildUpdate(t);// TODO 没有任何一个字段做更新不做处理, 否则会将除_id外的字段都置nullif (update.isIsolated()) {return null;}// 返回Pair对象return Pair.of(query, buildUpdate(t));}/*** 判断@Id是否存在, 并且value不为null* @param obj* @return*/public static boolean existDocumentId(Object obj) {return getDocumentId(obj) == null ? false : true;// 空值返回false 非空返回true}/*** 获取@Id下的字段value* @param obj* @return*/@SneakyThrowspublic static Object getDocumentId(Object obj) {Class rClass = obj.getClass();// 得到类对象Field[] fs = rClass.getDeclaredFields();// 得到属性集合for (Field f : fs) {// 遍历属性Id id = f.getAnnotation(Id.class);if (id != null) {f.setAccessible(true); // 设置属性是可以访问的return f.get(obj);// 返回@Id注解下的字段值}}return null;}}

具体使用

MongoTemplate crud 封装相关推荐

  1. 自己的mongodb的CRUD封装

    工具类:package Utils;import com.google.common.collect.Lists; import com.mongodb.MongoClient; import com ...

  2. MyBatisPlus——CRUD

    一.BaseMapper--通用CRUD接口 通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 My ...

  3. DDD中Diff的应用(JAVERS)的封装

    文章目录 背景 说明 官网 Github 构造diff 测试 测试修改 测试新增 集合比较 封装CRUD 自定义比较器 使用 注解 类级别 @Entity @ValueObject @Value @D ...

  4. 02_MybatisPlus—CRUD 接口

    1 Service CRUD 接口 通用 Service CRUD 封装IService (opens new window)接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 l ...

  5. 双刃剑MongoDB的学习和避坑

    双刃剑MongoDB的学习和避坑 MongoDB 是一把双刃剑,它对数据结构的要求并不高.数据通过key-value的形式存储,而value的值可以是字符串,也可以是文档.所以我们在使用的过程中非常方 ...

  6. SpringBoot高级篇MongoDB之修改基本使用姿势

    原文: 190218-SpringBoot高级篇MongoDB之修改基本使用姿势 本篇依然是MongoDB curd中的一篇,主要介绍document的更新,主要内容如下 常见类型成员的修改 数组类型 ...

  7. mybatis-plus入坑指南

    简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 特性 无侵入:只做增强不做改变,引入它不会对现 ...

  8. java面试必背知识点

    JAVA必背面试题和项目面试通关要点 一 数据库 1.常问数据库查询.修改(SQL查询包含筛选查询.聚合查询和链接查询和优化问题,手写SQL语句,例如四个球队比赛,用SQL显示所有比赛组合:举例2:选 ...

  9. struts、hibernate、spring、 mybatis、 spring boot 等面试题汇总

    1.谈谈你对Struts的理解. 答: 1. struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是ActionS ...

最新文章

  1. (五)磁盘存储空间的管理
  2. intellij idea 配置远程访问本地的tomcat项目
  3. SP1043 GSS1 - Can you answer these queries I(线段树,区间最大子段和(静态))
  4. BeanFactory作为 IoC 容器示例
  5. Shell命令-Sort,Join
  6. ReentrantReadWriteLock可重入读写锁分析
  7. virtualbox中安装ubuntu
  8. mysql binlog oplog_mongodb 学习之oplog
  9. Spring MVC-集成(Integration)-集成LOG4J示例(转载实践)
  10. 使用Sencha cmd安装extjs6
  11. c语言 音符符号大全,音符符号大全
  12. 宝塔面板windows建站教程_宝塔面板建站教程
  13. 在VMware Workstation中创建一个虚拟软盘,并在Windows XP上使用
  14. python查询12306余票_「python」12306余票查询GUI
  15. 外贸企业邮箱格式怎么写?外贸域名邮箱格式
  16. ubuntu下如何打开root文件夹,如何用root权限管理员权限打开文件夹,以及如何获取root权限
  17. windows下mysql免安装配置
  18. Neural Networks Basics
  19. SQL Server之SQL Trace选项
  20. 实验7-4 身份证号码最后一位

热门文章

  1. 多边形内角和c语言编程,029.多边形及其内角和(C).doc
  2. 多边形内角和c语言编程,初二年级奥数多边形的内角和试题及答案
  3. 知识图谱与文献计量你一定做错了! citespace
  4. 遗传图谱 genetic map
  5. 在线视频播放App的实现
  6. 2021年全国行政区划代码
  7. python中set转换为list_python-str,list,set间的转换实例
  8. 小程序免300认证教程,可以用于公众号引流,全程免费认证,系统带认证链接,公众号可直接挂链接。
  9. 代码雨的实现 linux or html
  10. 第七章 面向对象核心