123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- package com.fdkankan.mongodb.service.impl;
- import cn.hutool.core.lang.UUID;
- import cn.hutool.core.util.ObjectUtil;
- import com.fdkankan.mongodb.base.BaseRequestMongo;
- import com.fdkankan.mongodb.base.MongoPageResult;
- import com.fdkankan.mongodb.service.MongodbBaseService;
- import com.mongodb.client.result.DeleteResult;
- import org.apache.commons.lang3.StringUtils;
- import org.bson.Document;
- import org.bson.types.ObjectId;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.Sort;
- import org.springframework.data.geo.GeoResults;
- import org.springframework.data.mapping.MappingException;
- import org.springframework.data.mongodb.core.MongoTemplate;
- import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
- import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
- import org.springframework.data.mongodb.core.query.Criteria;
- import org.springframework.data.mongodb.core.query.NearQuery;
- import org.springframework.data.mongodb.core.query.Query;
- import org.springframework.data.util.Pair;
- import org.springframework.stereotype.Component;
- import org.springframework.util.Assert;
- import javax.annotation.PostConstruct;
- import java.lang.reflect.ParameterizedType;
- import java.util.Collections;
- import java.util.List;
- import java.util.Locale;
- import java.util.stream.Collectors;
- /**
- * @author Xiewj
- * @date 2021/11/15
- * Mongodb工具类
- */
- @Component
- public class MongodbBaseServiceImpl<T> implements MongodbBaseService<T> {
- public static MongodbBaseServiceImpl mongodbBaseService;
- @PostConstruct
- public void init() {
- mongodbBaseService = this;
- mongodbBaseService.mongoTemplate = this.mongoTemplate;
- }
- @Autowired
- private MongoTemplate mongoTemplate;
- private static final int FIRST_PAGE_NUM = 1;
- private static final String ID = "_id";
- /**
- * 分页查询.
- *
- * @param query Mongo Query对象,构造你自己的查询条件.
- * @param page#mapper 映射器,你从db查出来的list的元素类型是entityClass, 如果你想要转换成另一个对象,比如去掉敏感字段等,可以使用mapper来决定如何转换.
- * @param page#pageSize 分页的大小.
- * @param page#pageNum 当前页.
- * @param page#lastId 条件分页参数, 区别于skip-limit,采用find(_id>lastId).limit分页.
- * 如果不跳页,像朋友圈,微博这样下拉刷新的分页需求,需要传递上一页的最后一条记录的ObjectId。 如果是null,则返回pageNum那一页.
- * @return PageResult,一个封装page信息的对象.
- */
- @Override
- public MongoPageResult<T> pageQuery(BaseRequestMongo page, Query query) {
- //分页逻辑
- long total = mongoTemplate.count(query, getTClass());
- final Integer pages = (int) Math.ceil(total / (double) page.getPageSize());
- if (page.getPageNum() <= 0 || page.getPageNum() > pages) {
- page.setPageNum(FIRST_PAGE_NUM);
- }
- if (StringUtils.isNotBlank(page.getLastId())) {
- final Criteria criteria = new Criteria(UUID.randomUUID().toString());
- if (page.getPageNum() != FIRST_PAGE_NUM) {
- criteria.and(ID).gt(new ObjectId(page.getLastId()));
- }
- query.limit(page.getPageSize());
- query.addCriteria(criteria);
- } else {
- int skip = page.getPageSize() * (page.getPageNum() - 1);
- query.skip(skip).limit(page.getPageSize());
- }
- List<T> entityList=null;
- if (page.getSortBy().toUpperCase(Locale.ROOT).equals(Sort.Direction.DESC.name())){
- query.with(Sort.by(Collections.singletonList(new Sort.Order(Sort.Direction.DESC, page.getOrderBy()))));
- }else {
- query.with(Sort.by(Collections.singletonList(new Sort.Order(Sort.Direction.ASC, page.getOrderBy()))));
- }
- entityList=mongoTemplate.find(query, getTClass());
- MongoPageResult<T> mongoPageResult = new MongoPageResult<>();
- mongoPageResult.setTotal(total);
- mongoPageResult.setPages(pages);
- mongoPageResult.setPageSize(page.getPageSize());
- mongoPageResult.setPageNum(page.getPageNum());
- mongoPageResult.setList(entityList);
- return mongoPageResult;
- }
- @Override
- public long getCount(Query query) {
- return mongoTemplate.count(query, getTClass());
- }
- @Override
- public T save(T t) {
- return mongoTemplate.save(t);
- }
- @Override
- public T insert(T t) {
- return mongoTemplate.insert(t);
- }
- @Override
- public DeleteResult delete(T t) {
- return mongoTemplate.remove(t);
- }
- @Override
- public DeleteResult deleteById(Object id) {
- T t = mongoTemplate.findById(id, getTClass());
- if (ObjectUtil.isNotNull(t)){
- return delete(t);
- }
- return null;
- }
- @Override
- public DeleteResult delete(Query query) {
- return mongoTemplate.remove(query, getTClass());
- }
- @Override
- public T update(T t) {
- return mongoTemplate.save(t);
- }
- @Override
- public T findById(Object id) {
- return mongoTemplate.findById(id, getTClass());
- }
- @Override
- public List<T> findAll() {
- return mongoTemplate.findAll(getTClass());
- }
- @Override
- public List<T> find(Query query) {
- return mongoTemplate.find(query, getTClass());
- }
- @Override
- public GeoResults<T> geoNear(NearQuery query) {
- GeoResults<T> geoResults = mongoTemplate.geoNear(query, getTClass());
- return geoResults;
- }
- @Override
- public T findOne(Query query) {
- return mongoTemplate.findOne(query,getTClass());
- }
- @Override
- public boolean exists(Query query) {
- return mongoTemplate.exists(query, getTClass());
- }
- @Override
- public boolean exists(T t) {
- return exists(getIdQueryFor(t));
- }
- @Override
- public boolean exitsById(Object id) {
- return exists(findById(id));
- }
- @Override
- public long count(Query query) {
- return mongoTemplate.count(query, getTClass());
- }
- @Override
- public Class<T> getTClass() {
- Class<T> tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
- return tClass;
- }
- @Override
- public Pair<String, Object> extractIdPropertyAndValue(Object object) {
- Assert.notNull(object, "Id cannot be extracted from 'null'.");
- Class<?> objectType = object.getClass();
- if (object instanceof Document) {
- return Pair.of("_id", ((Document) object).get("_id"));
- } else {
- MongoPersistentEntity<?> entity = (MongoPersistentEntity) mongoTemplate.getConverter().getMappingContext().getPersistentEntity(objectType);
- if (entity != null && entity.hasIdProperty()) {
- MongoPersistentProperty idProperty = (MongoPersistentProperty) entity.getIdProperty();
- return Pair.of(idProperty.getFieldName(), entity.getPropertyAccessor(object).getProperty(idProperty));
- } else {
- throw new MappingException("No id property found for object of type " + objectType);
- }
- }
- }
- @Override
- public Query getIdQueryFor(Object object) {
- Pair<String, Object> id = this.extractIdPropertyAndValue(object);
- return new Query(Criteria.where((String) id.getFirst()).is(id.getSecond()));
- }
- }
|