MongodbBaseServiceImpl.java 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package com.fdkankan.mongodb.service.impl;
  2. import cn.hutool.core.lang.UUID;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import com.fdkankan.mongodb.base.BaseRequestMongo;
  5. import com.fdkankan.mongodb.base.MongoPageResult;
  6. import com.fdkankan.mongodb.service.MongodbBaseService;
  7. import com.mongodb.client.result.DeleteResult;
  8. import org.apache.commons.lang3.StringUtils;
  9. import org.bson.Document;
  10. import org.bson.types.ObjectId;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.data.domain.Sort;
  13. import org.springframework.data.geo.GeoResults;
  14. import org.springframework.data.mapping.MappingException;
  15. import org.springframework.data.mongodb.core.MongoTemplate;
  16. import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
  17. import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
  18. import org.springframework.data.mongodb.core.query.Criteria;
  19. import org.springframework.data.mongodb.core.query.NearQuery;
  20. import org.springframework.data.mongodb.core.query.Query;
  21. import org.springframework.data.util.Pair;
  22. import org.springframework.stereotype.Component;
  23. import org.springframework.util.Assert;
  24. import javax.annotation.PostConstruct;
  25. import java.lang.reflect.ParameterizedType;
  26. import java.util.Collections;
  27. import java.util.List;
  28. import java.util.Locale;
  29. import java.util.stream.Collectors;
  30. /**
  31. * @author Xiewj
  32. * @date 2021/11/15
  33. * Mongodb工具类
  34. */
  35. @Component
  36. public class MongodbBaseServiceImpl<T> implements MongodbBaseService<T> {
  37. public static MongodbBaseServiceImpl mongodbBaseService;
  38. @PostConstruct
  39. public void init() {
  40. mongodbBaseService = this;
  41. mongodbBaseService.mongoTemplate = this.mongoTemplate;
  42. }
  43. @Autowired
  44. private MongoTemplate mongoTemplate;
  45. private static final int FIRST_PAGE_NUM = 1;
  46. private static final String ID = "_id";
  47. /**
  48. * 分页查询.
  49. *
  50. * @param query Mongo Query对象,构造你自己的查询条件.
  51. * @param page#mapper 映射器,你从db查出来的list的元素类型是entityClass, 如果你想要转换成另一个对象,比如去掉敏感字段等,可以使用mapper来决定如何转换.
  52. * @param page#pageSize 分页的大小.
  53. * @param page#pageNum 当前页.
  54. * @param page#lastId 条件分页参数, 区别于skip-limit,采用find(_id>lastId).limit分页.
  55. * 如果不跳页,像朋友圈,微博这样下拉刷新的分页需求,需要传递上一页的最后一条记录的ObjectId。 如果是null,则返回pageNum那一页.
  56. * @return PageResult,一个封装page信息的对象.
  57. */
  58. @Override
  59. public MongoPageResult<T> pageQuery(BaseRequestMongo page, Query query) {
  60. //分页逻辑
  61. long total = mongoTemplate.count(query, getTClass());
  62. final Integer pages = (int) Math.ceil(total / (double) page.getPageSize());
  63. if (page.getPageNum() <= 0 || page.getPageNum() > pages) {
  64. page.setPageNum(FIRST_PAGE_NUM);
  65. }
  66. if (StringUtils.isNotBlank(page.getLastId())) {
  67. final Criteria criteria = new Criteria(UUID.randomUUID().toString());
  68. if (page.getPageNum() != FIRST_PAGE_NUM) {
  69. criteria.and(ID).gt(new ObjectId(page.getLastId()));
  70. }
  71. query.limit(page.getPageSize());
  72. query.addCriteria(criteria);
  73. } else {
  74. int skip = page.getPageSize() * (page.getPageNum() - 1);
  75. query.skip(skip).limit(page.getPageSize());
  76. }
  77. List<T> entityList=null;
  78. if (page.getSortBy().toUpperCase(Locale.ROOT).equals(Sort.Direction.DESC.name())){
  79. query.with(Sort.by(Collections.singletonList(new Sort.Order(Sort.Direction.DESC, page.getOrderBy()))));
  80. }else {
  81. query.with(Sort.by(Collections.singletonList(new Sort.Order(Sort.Direction.ASC, page.getOrderBy()))));
  82. }
  83. entityList=mongoTemplate.find(query, getTClass());
  84. MongoPageResult<T> mongoPageResult = new MongoPageResult<>();
  85. mongoPageResult.setTotal(total);
  86. mongoPageResult.setPages(pages);
  87. mongoPageResult.setPageSize(page.getPageSize());
  88. mongoPageResult.setPageNum(page.getPageNum());
  89. mongoPageResult.setList(entityList);
  90. return mongoPageResult;
  91. }
  92. @Override
  93. public long getCount(Query query) {
  94. return mongoTemplate.count(query, getTClass());
  95. }
  96. @Override
  97. public T save(T t) {
  98. return mongoTemplate.save(t);
  99. }
  100. @Override
  101. public T insert(T t) {
  102. return mongoTemplate.insert(t);
  103. }
  104. @Override
  105. public DeleteResult delete(T t) {
  106. return mongoTemplate.remove(t);
  107. }
  108. @Override
  109. public DeleteResult deleteById(Object id) {
  110. T t = mongoTemplate.findById(id, getTClass());
  111. if (ObjectUtil.isNotNull(t)){
  112. return delete(t);
  113. }
  114. return null;
  115. }
  116. @Override
  117. public DeleteResult delete(Query query) {
  118. return mongoTemplate.remove(query, getTClass());
  119. }
  120. @Override
  121. public T update(T t) {
  122. return mongoTemplate.save(t);
  123. }
  124. @Override
  125. public T findById(Object id) {
  126. return mongoTemplate.findById(id, getTClass());
  127. }
  128. @Override
  129. public List<T> findAll() {
  130. return mongoTemplate.findAll(getTClass());
  131. }
  132. @Override
  133. public List<T> find(Query query) {
  134. return mongoTemplate.find(query, getTClass());
  135. }
  136. @Override
  137. public GeoResults<T> geoNear(NearQuery query) {
  138. GeoResults<T> geoResults = mongoTemplate.geoNear(query, getTClass());
  139. return geoResults;
  140. }
  141. @Override
  142. public T findOne(Query query) {
  143. return mongoTemplate.findOne(query,getTClass());
  144. }
  145. @Override
  146. public boolean exists(Query query) {
  147. return mongoTemplate.exists(query, getTClass());
  148. }
  149. @Override
  150. public boolean exists(T t) {
  151. return exists(getIdQueryFor(t));
  152. }
  153. @Override
  154. public boolean exitsById(Object id) {
  155. return exists(findById(id));
  156. }
  157. @Override
  158. public long count(Query query) {
  159. return mongoTemplate.count(query, getTClass());
  160. }
  161. @Override
  162. public Class<T> getTClass() {
  163. Class<T> tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
  164. return tClass;
  165. }
  166. @Override
  167. public Pair<String, Object> extractIdPropertyAndValue(Object object) {
  168. Assert.notNull(object, "Id cannot be extracted from 'null'.");
  169. Class<?> objectType = object.getClass();
  170. if (object instanceof Document) {
  171. return Pair.of("_id", ((Document) object).get("_id"));
  172. } else {
  173. MongoPersistentEntity<?> entity = (MongoPersistentEntity) mongoTemplate.getConverter().getMappingContext().getPersistentEntity(objectType);
  174. if (entity != null && entity.hasIdProperty()) {
  175. MongoPersistentProperty idProperty = (MongoPersistentProperty) entity.getIdProperty();
  176. return Pair.of(idProperty.getFieldName(), entity.getPropertyAccessor(object).getProperty(idProperty));
  177. } else {
  178. throw new MappingException("No id property found for object of type " + objectType);
  179. }
  180. }
  181. }
  182. @Override
  183. public Query getIdQueryFor(Object object) {
  184. Pair<String, Object> id = this.extractIdPropertyAndValue(object);
  185. return new Query(Criteria.where((String) id.getFirst()).is(id.getSecond()));
  186. }
  187. }