SpringBoot:java实现Repository统一接口操作MongoDB

一. Spring如何操作MongoDB?

1.Spring data jpa for MongoDB
2.使用Google的Morphia框架操作MongoDB
3.使用MongoDB原生的驱动,类似JDBC的原生驱动

这里针对第一种方式.

二.如何实现Repository统一接口
1.使用SpringBoot快速创建项目,pom.xml中引入依赖:

 <dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-mongodbartifactId>
 dependency>

2.总配置文件bootstrap.properties中配置MongoDB驱动

spring.datasource.mongo.url=mongodb://diseasediscuss:diseasediscuss@{ip}:27017/diseasediscuss?authSource=diseasediscuss
spring.datasource.mongo.database=diseasediscuss

3.MongoDB配置类


package com.dachen.config;

import com.dachen.support.dao.BaseRepositoryImpl;
import com.dachen.util.IDGenerator;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * basePackages:设置Repository的扫描目录
 * mongoTemplateRef:mongo模板类引用,类似于JDBCTemplate
 * repositoryBaseClass:设置默认的Repository实现类为BaseRepositoryImpl,代替SimpleMongoRepository
 */
@Configuration
@EnableMongoRepositories(
    basePackages={"com.dachen.disease.model.po",
                                "com.dachen.disease.dao",
                                "com.dachen.question.dao"},
    mongoTemplateRef="diseaseMongoTemplate",
     repositoryBaseClass = BaseRepositoryImpl.class)
public class MongodbConfig {

    @Autowired
    private ConfigProperties configProperties;

    @Value("${spring.datasource.mongo.url}")
    private String mongoUri;

    @Value("${spring.datasource.mongo.database}")
    private String dbName;

    @Bean(name="diseaseMongoTemplate")
    public MongoTemplate diseaseMongoTemplate() throws Exception {
        MappingMongoConverter converter = new MappingMongoConverter(
                new DefaultDbRefResolver(mongodbFactory()), 
                new MongoMappingContext());

        converter.setTypeMapper(new DefaultMongoTypeMapper(null));

        return new MongoTemplate(mongodbFactory(), converter);
    }

    @Bean
    public MongoDbFactory mongodbFactory() throws Exception {
        MongoClientURI mongoClientUri = new MongoClientURI(mongoUri);
        return new SimpleMongoDbFactory(new MongoClient(mongoClientUri), dbName);
    }

    @Bean
    public IDGenerator idGenerator(){
        return  new IDGenerator(configProperties.getWorkerId(),0);
    }
}

3.Repository统一接口


package com.dachen.support.dao;

import com.dachen.util.PageVO;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Created by wanghong on 2017/9/21
 */
@NoRepositoryBean  //避免spring扫描BaseRepository
public interface BaseRepository<T, ID extends Serializable> extends MongoRepository<T,ID> {
    void batchSave(List<T> obj);
    void batchDelete(List<ID> pks);
    void update(ID id, Map<String, Object> updateFieldMap);
    void update(Map<String,Object> queryParamMap, Map<String, Object> updateFieldMap);
    PageVO<T> findPage(Integer pageIndex, Integer pageSize, Map<String, Integer> sortMap);
    T findByIdAndType(Long id,Integer type);
    PageVO<T> findPageWithParam(Map<String,Object> queryParamMap,String searchKey,Integer pageIndex, Integer pageSize, Map<String,Integer> sortMap);
}

4.Repository统一接口实现类


package com.dachen.support.dao;

import com.dachen.disease.model.enums.CommonEnum;
import com.dachen.util.PageVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoOperations;
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.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author wanghong
 * @desc
 * @date: 2017/9/21  10:40
 * @Copyright (c) 2017, DaChen All Rights Reserved.
 */
public class BaseRepositoryImpl extends SimpleMongoRepository implements BaseRepository {

    protected final MongoOperations mongoTemplate;

    protected final MongoEntityInformation entityInformation;

    private Class clazz;

    public BaseRepositoryImpl(MongoEntityInformation metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
        this.mongoTemplate=mongoOperations;
        this.entityInformation = metadata;
        clazz = entityInformation.getJavaType();
    }

    @Override
    public T findByIdAndType(Long id,Integer type){
        Criteria criatira = new Criteria();
        criatira.andOperator(Criteria.where("_id").is("id"), Criteria.where("type").is(type));
        T t = mongoTemplate.findOne(new Query(criatira), clazz);
        return t;
    }

    /**
     * @param id  更新主键
     * @param updateFieldMap  key:需要更新的属性  value:对应的属性值
     */
   @Override
    public void update(ID id, Map updateFieldMap) {
        if (updateFieldMap != null || !updateFieldMap.isEmpty()) {
            Criteria criteria = new Criteria("_id").is(id);
            Update update = new Update();
            updateFieldMap.entrySet().forEach(entry -> update.set(entry.getKey(),entry.getValue()));
            mongoTemplate.findAndModify(new Query(criteria), update, clazz);
        }
    }

    /**
     * @param queryParamMap 查询参数
     * @param updateFieldMap  更新参数
     */
    @Override
    public void update(Map queryParamMap, Map updateFieldMap) {
        if (queryParamMap != null || !queryParamMap.isEmpty()){
            List criteriaList = new ArrayList<>();
            for (Map.Entry entry:queryParamMap.entrySet()){
                criteriaList.add(Criteria.where(entry.getKey()).is(entry.getValue()));
            }

            int size = criteriaList.size();
            Criteria[] criterias = new Criteria[size];
            for (int i=0;i
                criterias[i] = criteriaList.get(i);
            }
            Criteria criteria = new Criteria( ).andOperator(criterias);

            if (updateFieldMap != null || !updateFieldMap.isEmpty()) {
                Update update = new Update();
                updateFieldMap.entrySet().forEach(entry -> update.set(entry.getKey(),entry.getValue()));
                mongoTemplate.findAndModify(new Query(criteria), update, clazz);
            }

        }
    }

    @Override
    public void batchSave(List obj) {
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(obj)) {
            //过滤掉集合中的空对象
            obj = obj.stream().filter(o -> Objects.nonNull(o)).collect(Collectors.toList());
             save(obj);
        }
    }

    @Override
    public void batchDelete(List pks) {
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(pks)) {
            Query query = new Query(Criteria.where("_id").in(pks));
            mongoTemplate.findAllAndRemove(query,clazz);
        }
    }

    /**
     * 分页查询列表
     * @param pageIndex
     * @param pageSize
     * @param sortMap 排序 key:排序字段 value:升序0或降序1
     * @return
     */
   public PageVO findPage(Integer pageIndex, Integer pageSize, Map sortMap) {
        List.Order> orders = new ArrayList<>();
        Pageable pageable = null;
        if (sortMap != null && !sortMap.isEmpty()){
            sortMap.entrySet().forEach(entry -> orders.add(new Sort.Order(entry.getValue() == 0 ? Sort.Direction.ASC:Sort.Direction.DESC, entry.getKey())));
            pageable = new PageRequest(pageIndex, pageSize, new Sort(orders));
        }else {
            pageable = new PageRequest(pageIndex, pageSize);
        }
        Page page = findAll(pageable);
        PageVO pageVO = new PageVO<>(pageIndex, pageSize);
        pageVO.setPageData(page.getContent());
        pageVO.setTotal(page.getTotalElements());
        return pageVO;
    }

    /**
     * 带关键字和条件的查询分页,只针对病例搜索
     * @param queryParamMap
     * @param searchKey
     * @param pageIndex
     * @param pageSize
     * @param sortMap
     * @return
     */
    public PageVO findPageWithParam(Map queryParamMap,String searchKey,Integer pageIndex, Integer pageSize, Map sortMap) {
        if (queryParamMap == null || queryParamMap.isEmpty()) {
            return  findPage(pageIndex, pageSize, sortMap);
        }

        List criteriaList = new ArrayList<>();
        for (Map.Entry entry:queryParamMap.entrySet()){
            criteriaList.add(Criteria.where(entry.getKey()).is(entry.getValue()));
        }
        Criteria criteria1 = Criteria.where("status").is(CommonEnum.Status.NORMAL.getIndex());
        criteriaList.add(criteria1);
        if(StringUtils.isNotBlank(searchKey)){
            Criteria criteriaPattern = new Criteria();
            Pattern p1 = Pattern.compile(String.format(".*%1$s.*", searchKey), Pattern.CASE_INSENSITIVE);
            criteriaPattern.orOperator( Criteria.where("userName").regex(p1), Criteria.where("title").regex(p1));
            criteriaList.add(criteriaPattern);
        }

        Criteria[] criterias = new Criteria[criteriaList.size()];
        criterias = criteriaList.toArray(criterias);
        Criteria criteria = new Criteria( ).andOperator(criterias);

        Query query = new Query(criteria);

        if (sortMap != null && !sortMap.isEmpty()) {
            List.Order> orders = new ArrayList<>();
            sortMap.entrySet().forEach(entry -> orders.add(new Sort.Order(entry.getValue() == 0 ? Sort.Direction.ASC:Sort.Direction.DESC, entry.getKey())));
            Sort sort = new Sort(orders);
            query.with(sort);
        }
        long total = this.mongoTemplate.count(query,  clazz);
        query.skip(pageIndex*pageSize);
        query.limit(pageSize);

        List data = this.mongoTemplate.find(query, clazz);

        PageVO pageVO = new PageVO<>();
        pageVO.setPageIndex(pageIndex);
        pageVO.setPageSize(pageSize);
        pageVO.setTotal(total);
        pageVO.setPageData(data);
        return pageVO;
    }

}

然后具体的业务DAO就可以继承BaseRepository


package com.dachen.disease.dao;

import com.dachen.disease.model.po.Disease;
import com.dachen.support.dao.BaseRepository;

/**
 * @author wanghong
 * @desc
 * @date: 2017/9/25  17:19
 * @Copyright (c) 2017, DaChen All Rights Reserved.
 */
public interface DiseaseRepository extends BaseRepository {

    /**
     * 根据病例id查询病例信息
     * @param id
     *      病例id
     * @param status
     *      病例帖子状态
     */
    Disease findByIdAndStatus(Long id, Integer status);

}

参考:http://blog.csdn.net/ssrc0604hx/article/details/51155368
关于Spring data jpa参考: http://www.ityouknow.com/springboot/2016/08/20/springboot%28%E4%BA%94%29-spring-data-jpa%E7%9A%84%E4%BD%BF%E7%94%A8.html

你可能感兴趣的:(JavaWeb)