使用spring-data-mongo操作mongo数据库时,按常规的写法dao中会有很多重复且冗余的代码,所以将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);
}
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();
}
}