虽然NoSql的优势之一就是不需要提前设计表结构,可以用JSON对象来接收MongoDB返回的结果,但实际开发中,大多数集合的结构不怎么会变,并且为了提高代码的可读性,通常还是会在程序中提供DO类来与数据库映射,并通过他来对数据库进行操作。
习惯了mybatis的通用mapper,在写mongoDB数据库相关的操作没有类似genterator的工具去生成,便想着封装一个BaseDao基类,让其他的dao通过继承,就能直接使用最基本的增删改查。
依赖
为了方便设置更新时的对象属性,引入了fastjson
库,虽然好像日常出bug。不放心的话可以自己替换成其他的实现方式,不依赖其他库的话也可以使用反射实现。
代码
BaseDao类:
import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
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 javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @Author: visionki
* @CreateDate: 2020/11/26 14:03
* @Description: dao基类
*/
public class BaseDao<T> {
@Resource
private MongoTemplate mongoTemplate;
/**
* 获取泛型Class
*/
private Class<T> clazz = (java.lang.Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
/**
* 根据条件查询记录
* @param query
* @return
*/
public List<T> find(Query query){
return mongoTemplate.find(query, clazz);
}
/**
* 查询集合全部记录
* @return
*/
public List<T> findAll(){
return mongoTemplate.findAll(clazz);
}
/**
* 根据ID获取记录
* @param id
* @return
*/
public T findById(String id){
return mongoTemplate.findById(id, clazz);
}
/**
* 根据条件查询一条记录
* @param query
* @return 即便多条记录也只会返回第一条
*/
public T findOne(Query query){
System.out.println(mongoTemplate);
return mongoTemplate.findOne(query, clazz);
}
/**
* 新增记录
* @param t
* @return
*/
public T insert(T t){
return mongoTemplate.insert(t);
}
/**
* 批量新增记录
* @param list
* @return
*/
public Collection<T> insertAll(Collection<? extends T> list){
return mongoTemplate.insertAll(list);
}
/**
* 根据ID更新记录,对象属性全部更新
* @return
*/
public UpdateResult updateById(T t){
Query query = new Query(Criteria.where("id").is(getIdByObject(t)));
Update update = getUpdateByObjectAllField(t);
return mongoTemplate.updateMulti(query, update, clazz);
}
/**
* 根据ID更新记录,仅更新不为null属性的对象
* @return
*/
public UpdateResult updateByIdSelective(T t){
Query query = new Query(Criteria.where("id").is(getIdByObject(t)));
Update update = getUpdateByObjectNotNullField(t);
return mongoTemplate.updateMulti(query, update, clazz);
}
/**
* 根据条件批量更新记录
* @return
*/
public UpdateResult update(Query query, Update update){
return mongoTemplate.updateMulti(query, update, clazz);
}
/**
* 根据条件删除记录
* @param query
* @return
*/
public DeleteResult delete(Query query){
return mongoTemplate.remove(query, clazz);
}
/**
* 根据ID删除记录
* @param id
* @return
*/
public DeleteResult deleteById(String id){
Query query = new Query(Criteria.where("id").is(id));
return mongoTemplate.remove(query, clazz);
}
/**
* 查询一条记录并删除这条记录
* @param query
* @return
*/
public T deleteOneAndReturn(Query query){
return mongoTemplate.findAndRemove(query, clazz);
}
/**
* 根据条件查询全部记录并删除
* @param query
* @return
*/
public List<T> deleteAllAndReturn(Query query){
return mongoTemplate.findAllAndRemove(query, clazz);
}
/**
* 根据ID,若数据库存在则更新数据,若数据库不存在则新增数据
* @param t
* @return
*/
public UpdateResult upsertById(T t) {
Query query = new Query(Criteria.where("id").is(getIdByObject(t)));
Update update = getUpdateByObjectAllField(t);
return mongoTemplate.upsert(query, update, clazz);
}
/**
* 从对象中获取ID属性值
* @return
*/
private Object getIdByObject(T t){
try {
return t.getClass().getDeclaredField("id");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(clazz.getName() + "类不存在id属性");
}
}
/**
* 将对象的所有属性设置进update
* @param t
* @return
*/
private Update getUpdateByObjectAllField(T t){
Document document = Document.parse(JSON.toJSONString(t));
Update update = new Update();
for (Map.Entry<String, Object> entry : document.entrySet()) {
update.set(entry.getKey(), entry.getValue());
}
return update;
}
/**
* 将对象内不为null的属性设置进update
* @param t
* @return
*/
private Update getUpdateByObjectNotNullField(T t){
Document document = Document.parse(JSON.toJSONString(t));
Update update = new Update();
for (Map.Entry<String, Object> entry : document.entrySet()) {
if (entry.getValue() != null){mongo
update.set(entry.getKey(), entry.getValue());
}
}
return update;
}
}
UserDao类:
/**
* @Author: visionki
* @CreateDate: 2020/11/26 14:28
* @Description:
*/
@Repository
public class UserDao extends BaseDao<User> {
}
就可以在service中快乐使用了~
注意
- 主键默认为id
- 数据库中集合的名字默认为泛型的类名(首字母小写,例如User类对应数据库user集合)。
- query中无论键名是
id
还是_id
,mongoTemplate都会把他映射到数据库的_id
字段。
本文由 visionki 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Mar 17, 2021 at 06:38 am