/** * */ package me.yumin.mongo.client; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import me.yumin.mongo.client.domain.valueobject.MongoDsnVO; import me.yumin.mongo.client.domain.valueobject.MongoSortVO; import me.yumin.mongo.client.etc.MongoConnector; import me.yumin.mongo.client.etc.MongoUtil; import me.yumin.mongo.client.exception.MongoException; import me.yumin.mongo.client.query.MongoAdvancedQuery; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.Mongo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; /** * @author yumin * */ public class MongoDAO<T> implements InitializingBean, IMongoDAO<T> { /** * */ private MongoDsnVO dsn; private String database, collection; private T pojo; private Mongo mongo; private DB db; private DBCollection coll; /** * */ private static final Log LOG = LogFactory.getLog(MongoDAO.class); // ==================== // public and protected // ==================== /** * 初始化本抽像类 同时支持Spring注入和子类的手工初始化 * 子类手工初始化: * 1.先设定属性:dsn,database,collection,pojo; * 2.再调用本方法即可. * 若使用Spring注入,则配置bean时注入以上三个属性也可. * * @throws UnknownHostException */ protected void initializingBean() throws UnknownHostException { if (null == dsn) { throw new MongoException("koubei-mongo: check the datasource file!"); } if (null == database || null == collection || null == pojo) { throw new MongoException("koubei-mongo: property 'database', 'collection', 'pojo' required!"); } mongo = MongoConnector.getMongo(dsn); if (null == mongo) { throw new MongoException("koubei-mongo: connection failed!"); } db = mongo.getDB(database); coll = db.getCollection(collection); if (null == db || null == collection) { throw new MongoException("koubei-mongo: property 'db', 'coll' initializing failed!"); } } /** * Spring注入口 */ public void afterPropertiesSet() throws Exception { initializingBean(); } @Override public boolean insert(T object) { // 返回结果 boolean result = false; try { // 写入对象 DBObject dbObject = MongoUtil.getDBObjectByObject(object); // 调试信息 LOG.debug("insert - " + dbObject.toString()); // 执行写入 coll.insert(dbObject); result = getResult(); } catch (Exception e) { LOG.debug("insert", e); } return result; } @Override public boolean insertList(List<T> args) { // 返回结果 boolean result = false; try { // 写入对象 List<DBObject> dbObjects = new ArrayList<DBObject>(); // 批量转换 if (null != args && 0 < args.size()) { for (T object : args) { dbObjects.add(MongoUtil.getDBObjectByObject(object)); } } // 调试信息 LOG.debug("insertList - " + dbObjects.toString()); // 执行写入 coll.insert(dbObjects); result = getResult(); } catch (Exception e) { LOG.debug("insertList", e); } return result; } @Override public boolean save(T object) { // 返回结果 boolean result = false; try { // 保存对象 DBObject dbObject = MongoUtil.getDBObjectByObject(object); // 调试信息 LOG.debug("save - " + dbObject.toString()); // 执行保存 coll.save(dbObject); result = getResult(); } catch (Exception e) { LOG.debug("save", e); } return result; } @Override public boolean updateMapByCondition(Map<String, Object> condition, Map<String, Object> target) { // 返回结果 boolean result = false; try { // 修改条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 新改对象 DBObject dbObject = MongoUtil.getDBObjectByObject(target); dbObject.removeField("_id"); // 经实际测试,不允许改_id // 支持批量 DBObject objNew = new BasicDBObject("$set", dbObject); // 调试信息 LOG.debug("updateMapByCondition - query:" + query.toString() + " | objNew:" + objNew.toString()); // 执行修改 coll.update(query, objNew, false, true); result = getResult(); } catch (Exception e) { LOG.debug("updateMapByCondition", e); } return result; } @Override public boolean updateMapByKV(String field, String value, Map<String, Object> target) { Map<String, Object> condition = new HashMap<String, Object>(); condition.put(field, value); return updateMapByCondition(condition, target); } @Override public boolean updateMapByPrimaryId(String value, Map<String, Object> target) { return updateMapByKV("_id", value, target); } @Override public boolean updateObjectByCondition(Map<String, Object> condition, T target) { // 返回结果 boolean result = false; try { // 修改条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 修改对象 DBObject dbObject = MongoUtil.getDBObjectByObject(target); dbObject.removeField("_id"); // 经实际测试,不允许改_id // 支持批量 DBObject objNew = new BasicDBObject("$set", dbObject); // 调试信息 LOG.debug("updateObjectByCondition - query:" + query.toString() + " | objNew:" + objNew.toString()); // 执行修改 coll.update(query, objNew, false, true); result = getResult(); } catch (Exception e) { LOG.debug("updateObjectByCondition", e); } return result; } @Override public boolean updateObjectByKV(String field, String value, T target) { Map<String, Object> condition = new HashMap<String, Object>(); condition.put(field, value); return updateObjectByCondition(condition, target); } @Override public boolean updateObjectByPrimaryId(String value, T target) { return updateObjectByKV("_id", value, target); } @Override public boolean incrByPrimaryId(String value, String column, int step) { // 参数判断 if (0 > step) { return false; } // 执行累加 return incOperateByKV("_id", value, column, step); } @Override public boolean decrByPrimaryId(String value, String column, int step) { // 参数判断 if (0 < step) { return false; } // 执行累减 return incOperateByKV("_id", value, column, step); } @Override public boolean removeByCondition(Map<String, Object> condition) { // 返回结果 boolean result = false; try { // 删除条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 调试信息 LOG.debug("removeByCondition - " + query.toString()); // 执行删除 coll.remove(query); result = getResult(); } catch (Exception e) { LOG.debug("removeByCondition", e); } return result; } @Override public boolean removeByKV(String field, String value) { Map<String, Object> condition = new HashMap<String, Object>(); condition.put(field, value); return removeByCondition(condition); } @Override public boolean removeByPrimaryId(String value) { return removeByKV("_id", value); } @Deprecated @Override public boolean removeAll() { // 返回结果 boolean result = false; try { // 执行删除 coll.remove(new BasicDBObject()); result = getResult(); } catch (Exception e) { LOG.debug("removeAll", e); } return result; } @SuppressWarnings("unchecked") @Override public T findOneByCondition(Map<String, Object> condition) { // 返回结果 T object = null; try { // 查询条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 调试信息 LOG.debug("findOneByCondition - " + query.toString()); // 执行查询 DBObject dbObject = coll.findOne(query); if (null != dbObject) { // 转为原型 object = (T) MongoUtil.getObjectByDBObject(dbObject, pojo); } } catch (Exception e) { LOG.debug("findOneByCondition", e); } return object; } @Override public T findOneByKV(String field, String value) { Map<String, Object> condition = new HashMap<String, Object>(); condition.put(field, value); return findOneByCondition(condition); } @Override public T findOneByPrimaryId(String value) { return findOneByKV("_id", value); } @SuppressWarnings("unchecked") @Deprecated @Override public List<T> findAllByCondition(Map<String, Object> condition, MongoSortVO sort) { // 返回结果 List<T> resultList = new ArrayList<T>(); try { // 查询条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 排序条件 DBObject order = MongoUtil.getDBObjectByMongoSort(sort); // 调试信息 LOG.debug("findAllByCondition - query:" + query.toString() + " | order:" + order); // 执行查询 DBCursor cursor = coll.find(query).sort(order); if (null != cursor && 0 < cursor.count()) { for (DBObject dbObject : cursor) { T object = (T) MongoUtil.getObjectByDBObject(dbObject, pojo); if (null != object) { resultList.add(object); } } } } catch (Exception e) { LOG.debug("findAllByCondition", e); } return resultList; } @SuppressWarnings("unchecked") @Override public List<T> findByCondition(Map<String, Object> condition, MongoSortVO sort, int page, int size) { // 返回结果 List<T> resultList = new ArrayList<T>(); try { // 查询条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 分页参数 page = (0 < page ? page : 1); size = (0 < size ? size : 1); int skip = (page - 1) * size; // 排序条件 DBObject order = MongoUtil.getDBObjectByMongoSort(sort); // 调试信息 LOG.debug("findByCondition - query:" + query.toString() + " | order:" + order); // 执行查询 DBCursor cursor = coll.find(query).skip(skip).limit(size).sort(order); if (null != cursor && 0 < cursor.count()) { for (DBObject dbObject : cursor) { T object = (T) MongoUtil.getObjectByDBObject(dbObject, pojo); if (null != object) { resultList.add(object); } } } } catch (Exception e) { LOG.debug("findByCondition", e); } return resultList; } @Override public long countByCondition(Map<String, Object> condition) { // 返回结果 long count = -1; try { // 统计条件 DBObject query = MongoUtil.getDBObjectByObject(condition); // 调试信息 LOG.debug("countByCondition - " + query.toString()); // 执行统计 count = coll.count(query); } catch (Exception e) { LOG.debug("countByCondition", e); } return count; } @SuppressWarnings("unchecked") @Override public List<T> advancedFindByCondition(Map<String, MongoAdvancedQuery> condition, MongoSortVO sort, int page, int size) { // 返回结果 List<T> resultList = new ArrayList<T>(); if (null == condition) { return resultList; } try { // 查询条件 DBObject query = MongoUtil.getDBObjectByAdvancedQuery(condition); // 分页参数 page = (0 < page ? page : 1); size = (0 < size ? size : 1); int skip = (page - 1) * size; // 排序条件 DBObject order = MongoUtil.getDBObjectByMongoSort(sort); // 调试信息 LOG.debug("advancedFindByCondition - query:" + query.toString() + " | order:" + order); // 执行查询 DBCursor cursor = coll.find(query).skip(skip).limit(size).sort(order); if (null != cursor && 0 < cursor.count()) { for (DBObject dbObject : cursor) { T object = (T) MongoUtil.getObjectByDBObject(dbObject, pojo); if (null != object) { resultList.add(object); } } } } catch (Exception e) { LOG.debug("advancedFindByCondition", e); } return resultList; } @Override public long advancedCountByCondition(Map<String, MongoAdvancedQuery> condition) { // 返回结果 long count = -1; if (null == condition) { return count; } try { // 统计条件 DBObject query = MongoUtil.getDBObjectByAdvancedQuery(condition); // 调试信息 LOG.debug("advancedCountByCondition - " + query.toString()); // 执行统计 count = coll.count(query); } catch (Exception e) { LOG.debug("advancedCountByCondition", e); } return count; } @Override public void close() { mongo.close(); } // ==================== // private methods // ==================== /** * 获取操作返回值 适用增删改操作 * * @return true|false */ private boolean getResult() { // 返回结果 boolean result = false; DBObject msg = db.getLastError(); if (null != msg) { String err = (String) msg.get("err"); if (null == err || 0 == err.length()) { result = true; } else { } } return result; } /** * $inc操作,累加或累减(单条件版) * * @param field 查询字段名 * @param value 查询字段值 * @param column 被更改字段名 * @param step 被更改步长值(若为正数则累加反之累减) * @return true|false */ private boolean incOperateByKV(String field, String value, String column, int step) { // 返回结果 boolean result = false; try { // 修改条件 DBObject query = new BasicDBObject(); query.put(field, value); // 修改对象 DBObject dbObject = new BasicDBObject(); dbObject.put(column, step); DBObject objNew = new BasicDBObject("$inc", dbObject); // 调试信息 LOG.debug("incOperateByKV - query:" + query.toString() + " | objNew:" + objNew.toString()); // 执行修改 coll.update(query, objNew, false, true); result = getResult(); } catch (Exception e) { LOG.debug("incOperateByKV", e); } return result; } // ==================== // getters and setters // ==================== /** * */ public void setDsn(MongoDsnVO dsn) { this.dsn = dsn; } public void setDatabase(String database) { this.database = database; } public void setCollection(String collection) { this.collection = collection; } public void setPojo(T pojo) { this.pojo = pojo; } }