spring-data-mongo BaseDao的封装

3 篇文章 0 订阅
3 篇文章 0 订阅

引言

使用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 extends BaseEntity> {
    /**
     * 通过指定条件查找一个
     */
    T findOne(Query query);

    /**
     * 通过指定条件查找列表,不做分页
     * @param query
     * @return
     */
    List<T> find(Query query);
    /**
     * 通过指定条件查找列表,分页
     * @param query
     * @param pageable
     * @return
     */
    PageList<T> 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<T> 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<T extends BaseEntity> implements BaseDao<T> {

    protected MongoTemplate mongoTemplate;
    protected Class<T> entityClass = (Class<T>) ((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<T> find(Query query) {
        return mongoTemplate.find(query, entityClass, tabName);
    }

    @Override
    public PageList<T> find(Query query, Pageable pageable) {
        PageList<T> 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<T> 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<ResMenu> 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<ResMenu> resMenuList = resMenuDao.find(null);
        System.out.println();
    }
}

最后所有的代码都上传到git上了 源码
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值