Hutool的mongoDB工具类封装了链接的多源于连接接池的,并没有细节的增删改查等操作,所以根据自己的当前项目特征封装了一套自己用的。
api
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import cn.hutool.db.nosql.mongo.MongoDS;
import cn.hutool.db.nosql.mongo.MongoFactory;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.setting.GroupedMap;
import cn.hutool.setting.Setting;
/**
* mongo CRUB 基类
* @author lijiayu
* @date 2019-05-29
*/
public class MongoApi {
protected static Log LOG = LogFactory.get();
// MongoDB实例连接列表
public static MongoDS ds;
// 初始化mongoDs
static {
try {
Setting setting = new Setting(MongoDS.MONGO_CONFIG_PATH);
GroupedMap gMap = setting.getGroupedMap();
List<String> groups = new ArrayList<String>();
Set<Entry<String, LinkedHashMap<String, String>>> set = gMap.entrySet();
for (Entry<String, LinkedHashMap<String, String>> entry : set) {
if (entry.getKey() == null || entry.getKey().equals("")) {
continue;
}
String host = entry.getValue().get("host");
if (host == null || host.equals("null") || host.equals("")) {
continue;
}
LOG.info("Mongo,初始化数据源[{}]信息", entry.getKey());
LOG.info("Mongo,初始化数据源host[{}]信息", host);
groups.add(entry.getKey());
}
if (groups.size() > 0) {
ds = MongoFactory.getDS(groups);
} else {
ds = MongoFactory.getDS("master");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static MongoDS getDS() {
return ds;
}
}
base
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.eims.cto.framework.common.base.exception.BusinessException;
import com.eims.cto.framework.project.ylm.mongodb.entity.MongoBaseEntity;
import com.mongodb.Block;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
/**
* mongo CRUB 基类
* @author lijiayu
* @date 2019-05-29
*/
public abstract class MongoBaseService<T extends MongoBaseEntity> {
protected Logger log = LoggerFactory.getLogger(this.getClass());
public abstract String getDbName();
public abstract String getTableName();
public abstract Class<T> getClaz();
protected MongoCollection<Document> getCollection() {
return MongoApi.getDS().getCollection(getDbName(), getTableName());
}
/**
* 根据 mongoId查询
* @param _id
* @return
*/
public T selectByMgId(String _id) {
try {
MongoCollection<Document> table = getCollection();
Document query = getIdQuery(_id);
Document doc = table.find(query).first();
if (doc == null) {
return null;
}
return documentToEntity(doc);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 根据 mongoId查询
* @param _id
* @return
*/
public T selectByMgId(ObjectId _id) {
return selectByMgId(_id.toHexString());
}
/**
* 根据实体对象获取单条记录
* @param entity
* @return
*/
public T selectOne(T entity) {
List<T> list = listByEntity(entity);
if (list.size() > 0) {
return list.get(0);
} else {
return null;
}
}
/**
* 根据实体对象字段查询
* @param entity 为null 查询所有
* @return
*/
public List<T> listByEntity(T entity) {
try {
return listByEntity(entity, null);
} catch (Exception e) {
log.error("listByEntity error:{}", e.getMessage());
}
return new ArrayList<>();
}
/**
* 根据实体对象字段查询并排序
* @param entity 为null 查询所有
* @param sort 为null不排序,字段值 1 升序, -1 降序
* @return
*/
public List<T> listByEntity(T entity, T sort) {
try {
MongoCollection<Document> table = getCollection();
Document query = getDocumentByEntity(entity);
log.debug("=================== listByEntity get query document is:{}", query.toJson().toString());
List<T> ret = new ArrayList<>();
Block<Document> processBlock = new Block<Document>() {
@Override
public void apply(final Document document) {
ret.add(documentToEntity(document));
}
};
if (sort == null) {
table.find(query).forEach(processBlock);
} else {
Document docsort = getDocumentByEntity(sort);
table.find(query).sort(docsort).forEach(processBlock);
}
return ret;
} catch (Exception e) {
log.error("listByEntity error:{}", e.getMessage());
}
return new ArrayList<>();
}
/**
* 查询所有
* @param entity
* @param sort
* @return
*/
public List<T> listAll() {
return listAll(null);
}
/**
* 查询所有并排序
* @param entity
* @param sort
* @return
*/
public List<T> listAll(T sort) {
return listByEntity(null, sort);
}
/***
* 插入单条记录
* @param table 表连接
* @param obj 单条数据 obj double 处理不规范
* @return
*/
public String insertOne(T obj) {
if (obj == null) {
return null;
}
MongoCollection<Document> table = getCollection();
Document docine = Document.parse(JSON.toJSONString(obj));
docine.remove("_id");
docine.put("_id", new ObjectId());
table.insertOne(docine);
return docine.get("_id").toString();
}
/**
* 更新数据 注意 多余字段 会在库表记录追加
* @param obj
* @return
*/
public long updateOne(T obj) {
long num = 0;
try {
MongoCollection<Document> table = getCollection();
Document updateset = getUpdateSet(obj);
log.debug("=================== updateOne _id is {},get update set document is:{}",
obj.get_id().toHexString(), updateset.toJson().toString());
// UpdateResult result = table.updateOne(getIdQuery(obj.get_id()), updateset);
UpdateResult result = table.updateMany(getIdQuery(obj.get_id()), updateset);
num = result.getModifiedCount();
log.debug("updateOne:{}", num);
} catch (Exception e) {
log.error("updateOne error {}", e.getMessage());
throw new BusinessException(e.getMessage());
}
return num;
}
/**
* 批量更新
* @param query 用于查询条件的实体对象
* @param upset 用于更新的实体对象
* @return
*/
public long updateBatch(T query, T upset) {
long num = 0;
try {
Document qfilter = getDocumentByEntity(query);
log.debug("=================== updateBatch get query document is:{}", qfilter.toJson().toString());
Document updateset = getUpdateSet(upset);
log.debug("=================== updateBatch get update set document is:{}", updateset.toJson().toString());
UpdateResult result = getCollection().updateMany(qfilter, updateset);
num = result.getModifiedCount();
log.debug("updateBatch ModifiedCount:{}", num);
} catch (Exception e) {
log.error("updateBatch error {}", e.getMessage());
throw new BusinessException(e.getMessage());
}
return num;
}
/**
* 删除,根据ID
* @param id
* @return
*/
public long deleteOne(ObjectId id) {
return deleteOne(id.toHexString());
}
/**
* 删除,根据ID
* @param id
* @return
*/
public long deleteOne(String id) {
Document query = getIdQuery(id);
MongoCollection<Document> table = getCollection();
DeleteResult re = table.deleteOne(query);
return re.getDeletedCount();
}
/**
* 批量删除,根据实体类设置的属性值
* @param entity
* @return
*/
public long deleteByEntity(T entity) {
if (entity == null) {
log.error("deleteByEntity error: update entity is null");
return 0;
}
try {
Document query = getDocumentByEntity(entity);
log.debug("=================== deleteByEntity get query document is:{}", query.toJson().toString());
if (query.size() <= 0) {
log.error("deleteByEntity error: entity doesn't have any properties");
throw new BusinessException("deleteByEntity error: entity doesn't have any properties");
}
DeleteResult re = getCollection().deleteMany(query);
return re.getDeletedCount();
} catch (Exception e) {
log.error("deleteByEntity error {} class:{}", e.getMessage(), entity.getClass().getName());
throw new BusinessException(e.getMessage());
}
}
private Document getDocumentByEntity(T entity) throws IllegalAccessException, InvocationTargetException {
Document query = new Document();
if (entity == null) {
return query;
}
Field[] fields = MongoUtil.getFields(getClaz());
for (Field f : fields) {
if (f.getName().equals("serialVersionUID")) {
continue;
}
f.setAccessible(true);
Object obj = f.get(entity);
if (null == obj) {
continue;
}
query.append(f.getName(), obj);
}
return query;
}
private T documentToEntity(Document doc) {
try {
T t = getClaz().newInstance();
Field[] fields = MongoUtil.getFields(getClaz());
for (Field f : fields) {
if (doc.get(f.getName()) == null) {
continue;
}
Object value = doc.get(f.getName());
if (null == value) {
continue;
}
if (f.getName().equals("_id")) {
value = new ObjectId(String.valueOf(value));
}
setFieldValue(t, f, value);
}
return t;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
private void setFieldValue(T t, Field field, Object value) {
try {
field.setAccessible(true);
field.set(t, value);
} catch (Exception e) {
log.error("IllegalAccess for {}.{}", t.getClass(), field.getName());
throw new BusinessException(e.getMessage());
}
}
private Document getUpdateSet(T entity) throws IllegalAccessException, InvocationTargetException {
Document set = getDocumentByEntity(entity);
set.remove("_id");
set = new Document("$set", set);
return set;
}
private Document getIdQuery(ObjectId id) {
Document query = new Document();
query.append("_id", id);
return query;
}
private Document getIdQuery(String id) {
return getIdQuery(new ObjectId(id));
}
protected BusinessException handleBusinessException(Exception e) {
if (e instanceof BusinessException) {
return (BusinessException) e;
} else {
e.printStackTrace();
return new BusinessException(-500, "未知异常Mongdo Server Error:" + e.getMessage());
}
}
}
import java.io.Serializable;
import org.bson.types.ObjectId;
/**
* mongo实体的基类
* @author lijiayu
* @date 2019-05-28
*/
public class MongoBaseEntity implements Serializable {
private static final long serialVersionUID = -5786688718211843023L;
/**
* 在MongoDB中,存储于集合中的每一个文档都需要一个唯一的 _id 字段作为 primary_key。如果一个插入文档操作遗漏了``_id``
* 字段,MongoDB驱动会自动为``_id``字段生成一个 ObjectId
*/
private ObjectId _id;
public ObjectId get_id() {
return _id;
}
public void set_id(ObjectId _id) {
this._id = _id;
}
}
util 主要用于反射实体等操作的工具类
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 用于mongoBase的专用工具
* @author lijiayu
* @date 2019-05-30
*/
public class MongoUtil {
private static final Map<String, Field[]> FIELDS_CACHE = new ConcurrentHashMap<String, Field[]>();
public static Field[] getFields(Class<?> claz) throws SecurityException {
Field[] allFields = FIELDS_CACHE.get(claz.toString());
if (null != allFields) {
return allFields;
}
allFields = getFieldsDirectly(true, claz);
FIELDS_CACHE.put(claz.toString(), allFields);
return allFields;
}
public static Field[] getFieldsDirectly(boolean withSuperClassFieds, Class<?> claz) throws SecurityException {
Field[] allFields = null;
Class<?> searchType = claz;
Field[] declaredFields;
while (searchType != null) {
declaredFields = searchType.getDeclaredFields();
if (null == allFields) {
allFields = declaredFields;
} else {
allFields = append(allFields, declaredFields);
}
searchType = withSuperClassFieds ? searchType.getSuperclass() : null;
}
return allFields;
}
private static Field[] append(Field[] buffer, Field... newElements) {
if (isEmpty(buffer)) {
return newElements;
}
return insert(buffer, buffer.length, newElements);
}
private static Field[] insert(Field[] array, int index, Field... newFieldlements) {
if (isEmpty(newFieldlements)) {
return array;
}
if (isEmpty(array)) {
return newFieldlements;
}
final int len = length(array);
if (index < 0) {
index = (index % len) + len;
}
Field[] result = newArray(array.getClass().getComponentType(), Math.max(len, index) + newFieldlements.length);
System.arraycopy(array, 0, result, 0, Math.min(len, index));
System.arraycopy(newFieldlements, 0, result, index, newFieldlements.length);
if (index < len) {
System.arraycopy(array, index, result, index + newFieldlements.length, len - index);
}
return result;
}
private static Field[] newArray(Class<?> componentType, int newSize) {
return (Field[]) Array.newInstance(componentType, newSize);
}
private static boolean isEmpty(Field... array) {
return array == null || array.length == 0;
}
private static int length(Object array) throws IllegalArgumentException {
if (null == array) {
return 0;
}
return Array.getLength(array);
}
}
使用的具体业务类
@Service
public class MgCustImageService extends MongoBaseService<CustImage> {
@Override
public String getDbName() {
return MongoConstants.Dbs.customerInfo;
}
@Override
public String getTableName() {
return MongoConstants.customerInfo.custImage;
}
@Override
public Class<CustImage> getClaz() {
return CustImage.class;
}
}
CustImage 就是普通的javabean 但是需要继承 MongoBaseEntity