spring-data-mongo BaseDao的封装

引言

使用spring-data-mongo操作mongo数据库时,按常规的写法dao中会有很多重复且冗余的代码,所以将BaseDao通用的代码抽取出来一个基类是很有必要的,不过这个抽取的方式有多种每个人可能都不一样,在这里我讲我抽取的基类贴出来希望大家共同进步。

具体实现

BaseDao代码如下:
package com.mn.dao;

import com.mn.comm.PageList;
import com.mn.domain.BaseEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

/**
 * Created by mn on 2017/7/22 0022.
 */
public interface BaseDao {
    /**
     * 通过指定条件查找一个
     */
    T findOne(Query query);

    /**
     * 通过指定条件查找列表,不做分页
     * @param query
     * @return
     */
    List find(Query query);
    /**
     * 通过指定条件查找列表,分页
     * @param query
     * @param pageable
     * @return
     */
    PageList find(Query query, Pageable pageable);
    /**
     * 更新所有的字段,除了指定字段
     * @param t
     */
    int updateAll(T t);

    /**
     * 更新制定字段
     * @param query 查询条件
     * @param update 更新字段集合
     * @return 是否成功
     */
    int update(Query query, Update update);


    /**
     * 更新制定字段
     * @param query 查询条件
     * @param update 更新字段集合
     * @return 是否成功
     */
    int updateMulti(Query query, Update update);
    /**
     * 查找更新
     * @param query 查询条件
     * @param update 更新字段集合
     * @param isNew 是否返回更新后的记录
     * @return
     */
    T findAndModify(Query query, Update update, boolean isNew);
    /**
     * 插入
     * @param t 要插入的记录
     */
    void insert(T t);
    /**
     * 删除
     * @param query 查询条件
     */
    int delete(Query query);
    /**
     * 批量插入
     * @param tList
     */
    void insert(List tList);

    /**
     * 查询数量
     * @param query 查询条件
     * @return
     */
    long count(Query query);

    /**
     *  是否存在
     * @param query 查询条件
     * @return
     */
    boolean isExist(Query query);
}

BaseDao适配器
package com.mn.dao;

import com.mn.comm.Fixed;
import com.mn.comm.PageList;
import com.mn.domain.BaseEntity;
import com.mongodb.WriteResult;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
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 java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * Created by mn on 2017/7/22 0022.
 */
public class BaseDaoAdapter implements BaseDao {

    protected MongoTemplate mongoTemplate;
    protected Class entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    protected String tabName = entityClass.getSimpleName();

    public BaseDaoAdapter(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public void setTabName(String tabName) {
        this.tabName = tabName;
    }

    @Override
    public T findOne(Query query) {
        return mongoTemplate.findOne(query, entityClass, tabName);
    }

    @Override
    public List find(Query query) {
        return mongoTemplate.find(query, entityClass, tabName);
    }

    @Override
    public PageList find(Query query, Pageable pageable) {
        PageList pageList = new PageList<>();
        if (pageable != null) {
            long totalCount = count(query);
            int pageCount = (int) (totalCount / pageable.getPageSize());
            if (totalCount % pageable.getPageSize() != 0) {
                pageCount += 1;
            }
            query.with(pageable);
            pageList.makePageList(null, pageable.getPageSize(), totalCount, pageable.getPageNumber(), pageCount);
        }
        pageList.setPage(mongoTemplate.find(query, entityClass, tabName));
        return pageList;
    }

    /**
     * 通过反射将对象的值设置到update中
     * @param obj
     * @param cur_class
     * @param update
     */
    private void setClassFieldToUpdate(Object obj, Class cur_class, Update update) {
        Field[] obj_fields = cur_class.getDeclaredFields();
        try {
            for (Field field : obj_fields) {
                if (Modifier.isFinal(field.getModifiers()) || Modifier.isPublic(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
                    continue;
                }
                field.setAccessible(true);
                boolean isFixed = false;
                Annotation annotations[] = field.getAnnotations();
                for (Annotation annotation:annotations){
                    if(annotation.getClass()== Fixed.class){
                        isFixed = true;
                    }
                }
                if(isFixed){//如果字段是不变的则不添加在update中
                    continue;
                }
                update.set(field.getName(), field.get(obj));
            }
            if (cur_class.getSuperclass() != null) {
                setClassFieldToUpdate(obj, cur_class.getSuperclass(), update);//递归获取父类的字段值
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int updateAll(T t) {
        Update update = new Update();
        setClassFieldToUpdate(t,entityClass,update);
        return mongoTemplate.updateFirst(Query.query(Criteria.where(BaseEntity._ID).is(t.get_id())),update,entityClass,tabName).getN();
    }

    @Override
    public int update(Query query, Update update) {
        return mongoTemplate.updateFirst(query,update,entityClass,tabName).getN();
    }

    @Override
    public int updateMulti(Query query, Update update) {
        return mongoTemplate.updateMulti(query,update,entityClass,tabName).getN();
    }

    @Override
    public T findAndModify(Query query, Update update, boolean isNew) {
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(isNew);
        findAndModifyOptions.upsert(true);
        return mongoTemplate.findAndModify(query,update,findAndModifyOptions,entityClass,tabName);
    }

    @Override
    public void insert(T t) {
        mongoTemplate.insert(t,tabName);
    }

    @Override
    public int delete(Query query) {
       return mongoTemplate.remove(query,entityClass,tabName).getN();
    }

    @Override
    public void insert(List tList) {
        mongoTemplate.insertAll(tList);
    }

    @Override
    public long count(Query query) {
        return mongoTemplate.count(query,entityClass,tabName);
    }

    @Override
    public boolean isExist(Query query) {
        return mongoTemplate.exists(query,entityClass,tabName);
    }
}

使用方式
package com.mn.dao.impl;

import com.mn.dao.BaseDaoAdapter;
import com.mn.dao.IResMenuDao;
import com.mn.domain.ResMenu;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;

/**
 * Created by Administrator on 2017/7/22 0022.
 */

@Repository
public class ResMenuDaoImpl extends BaseDaoAdapter implements IResMenuDao {

    @Autowired
    public ResMenuDaoImpl(MongoTemplate mongoTemplate) {
        super(mongoTemplate);
    }
}

测试
import com.mn.dao.IResMenuDao;
import com.mn.domain.ResMenu;
import com.mn.utils.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * Created by Administrator on 2017/7/22 0022.
 */
public class ResMenuTest extends AbstractSpringWithJunitTestRunner {

    @Autowired
    IResMenuDao resMenuDao;

    @Test
    public void update() {
        ResMenu resMenu = new ResMenu();
        resMenu.setName("测试");
        resMenu.setPid("");
        resMenu.setUrl("www.baidu.com");
        resMenu.set_id(StringUtils.getId());
        resMenuDao.insert(resMenu);
        List resMenuList = resMenuDao.find(null);
        System.out.println();
    }
}

最后所有的代码都上传到git上了 源码

你可能感兴趣的:(sping,后台,java,数据库)