六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 265|回复: 0

MongoDb应用

[复制链接]

升级  11.33%

15

主题

15

主题

15

主题

秀才

Rank: 2

积分
67
 楼主| 发表于 2013-1-30 01:54:51 | 显示全部楼层 |阅读模式
//mongoDB ,创建一个自动增长的IDpublic abstract class AbstractIdEntity{@Id Long _id;@Transient protected Datastore ds;public AbstractIdEntity(){}public void setDs(Datastore ds) {this.ds = ds;}@PrePersist void prePersist(){if (_id == null) {String collName = ds.getCollection(getClass()).getName();    Query<StoredSeqence> q = ds.find(StoredSeqence.class, "_id", collName);    UpdateOperations<StoredSeqence> uOps = ds.createUpdateOperations(StoredSeqence.class).inc("value");    StoredSeqence newId = ds.findAndModify(q, uOps);    if (newId == null) {       newId = new StoredSeqence(collName);       ds.save(newId);    }        _id = newId.value;}}public Long geId() {return _id;}}@Entity(value="book_score_mongo", noClassnameStored=true)public class BookScoreMongo extends AbstractIdEntity {/**书的ID*/private Long bookId;/**书的类型(1为原创,2为藏书)*/private Integer bookType;/**用户的userId*/private Integer userId;/**评分的分数*/private Long score;public Long getBookId() {return bookId;}public void setBookId(Long bookId) {this.bookId = bookId;}public Integer getBookType() {return bookType;}public void setBookType(Integer bookType) {this.bookType = bookType;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public Long getScore() {return score;}public void setScore(Long score) {this.score = score;}}public interface IDAO {/** * 查询mongo数据库集合中的所有记录数 *  * @param clazz 通过cls配置的MongoCollect注解找到集合名 * @return 返回集合的所有记录数 */public <T> long count(Class<T> clazz);public <T> long count(Class<T> clazz, Map<String, Object> conditions);/** * 保存对象,返回主键值 *  * @param entity 需要保存的对象 * @return 主键值 */<T> Object saveRtnKey(T entity);<T> void delete(Class<T> clazz, Map<String, Object> conditions);/** * 根据主键值,将指定的字段更新为相应的值 *  * @param clazz  * @param id 主键id * @param updateFieldsMap updateFieldsMap中的key为字段名,value为字段值 * @return 返回更新的行数 */<T, V> int update(Class<T> clazz, V id, Map<String, Object> updateFieldsMap);/** * 根据主键值,查询数据库,查询结果转换为指定类的实例对象,没有结果,返回null。 *  * @param clazz 查询结果转换为该类 * @param id 主键值,作为查询条件 * @return 返回指定类cls的实例对象 */<T,V> T queryForObjectById(Class<T> clazz, V id);/** * 查询所有记录,查询结果转换为指定类的实例对象列表,没有结果,返回空的List对象。 *  * @param cls 查询结果转换为该类 * @return    返回指定类的实例对象列表 */<T> List<T> queryForList(Class<T> clazz);/** * 查询所有记录,并根据字段进行排序,查询结果转换为指定类的实例对象列表,没有结果,返回空的List对象。 * 排序字段示例: * ("age")  * ("-age") age字段降序排序 * ("age,date")  * ("age,-date") age字段升序,date字段降序排序 *  * @param cls 查询结果转换为该类 * @param orderFields 排序字段列表  * @return  返回指定类的实例对象列表 */<T> List<T> queryForListWithOrder(Class<T> clazz, String orderFields);/** * 查询所有符合条件的记录,查询结果转换为指定类的实例对象列表,没有结果,返回空的List对象。 * 属性名必须是"属性名 操作符"("age >") * 属性中,可以使用的有效操作符 ["=", "==","!=", "<>", ">", "<", ">=", "<=", "in", "nin", "all", "size", "exists"]  * 例如: *  * ("yearsOfOperation >", 5)   * ("rooms.maxBeds >=", 2) * ("rooms.bathrooms exists", 1) * ("stars in", new Long[]{3,4}) //3 and 4 stars (midrange?)} * ("age >=", age) * ("age =", age) * ("age", age)如果不写操作符,默认为=号 * ("age !=", age) * ("age in", ageList) * ("customers.loyaltyYears in", yearsList) *  * @param clazz 查询结果转换为该类 * @param property * @param value * @return 返回指定类的实例对象列表 */<T, V> List<T> queryForListByConExpr(Class<T> clazz, String property, V value);/** * 查询所有符合条件的记录,查询结果转换为指定类的实例对象列表,没有结果,返回空的List对象, * 多个查询条件之间的关系是与关系 *  * @param cls 查询结果转换为该类 * @param conditions key为property,可参考queryForListByConExpr方法说明 * @return 返回指定类的实例对象列表 */<T> List<T> queryForListByConExprMap(Class<T> cls, Map<String, Object> conditions);<T> List<T> queryForListByConExprMapWithOrder(Class<T> cls, Map<String, Object> conditions, String orderFields);<T> List<T> queryForListByConExprMapWithOrderLimit(Class<T> clazz, Map<String, Object> conditions, String orderFields, int rtnNum);<T> List<T> queryForListByConExprMapWithOrderSkipLimit(Class<T> cls, Map<String, Object> conditions,String orderFields, int skipNum, int rtnNum);}public class MongoServiceDAO implements IDAO{public static final String MONGO_ID_KEY="_id";private Datastore ds;private static MongoServiceDAO instance = new MongoServiceDAO();static{init();}private MongoServiceDAO(){}public static MongoServiceDAO getInstance(){return instance;}private static void init(){InputStream in=null;try {in = MongoServiceDAO.class.getClassLoader().getResourceAsStream("mongodb.properties");Properties prop = new Properties(); prop.load(in);String host = prop.getProperty("host").trim();int port = Integer.valueOf(prop.getProperty("port").trim());String dbName = prop.getProperty("dbName").trim();String userName = prop.getProperty("userName").trim();String password = prop.getProperty("password").trim();Morphia morphia = new Morphia();Mongo mongo = new Mongo(host, port);instance.ds = morphia.createDatastore(mongo,dbName);if (isMongoSecure(userName, password)){boolean bauth = instance.ds.getDB().authenticate(userName, password.toCharArray());if (!bauth) {throw new Exception("auth fail.");}}} catch(Exception e){SysLogger.error(e.getMessage());throw new RuntimeException(e.getMessage());}finally{if (in!=null){try {in.close();} catch (IOException e) {SysLogger.error(e.getMessage());}}}}    private static boolean isMongoSecure(String mongoUsername, String mongoPassword) {        if (mongoUsername == null            || "".equals(mongoUsername)            || mongoPassword == null            || "".equals(mongoPassword))            return false;        return true;    }        @Override    public <T> long count(Class<T> clazz){    return this.ds.getCount(clazz);    }        @Override    public <T> long count(Class<T> clazz, Map<String, Object> conditions){    if (conditions==null) return this.count(clazz);    Set<Entry<String, Object>> set = conditions.entrySet();Query<T> q = this.ds.createQuery(clazz);//加入过滤条件for(Entry<String,Object> entry : set){q.filter(entry.getKey(), entry.getValue());}return this.ds.getCount(q);    }    @Overridepublic <T> Object saveRtnKey(T entity) {if (AbstractIdEntity.class.isAssignableFrom(entity.getClass())){((AbstractIdEntity)entity).setDs(this.ds);}Key<T> key = this.ds.save(entity);return key.getId();}@Overridepublic <T> void delete(Class<T> clazz, Map<String, Object> conditions){Query<T> q = this.ds.createQuery(clazz);if (conditions != null){Set<Entry<String, Object>> set = conditions.entrySet();//加入过滤条件for(Entry<String,Object> entry : set){q.filter(entry.getKey(), entry.getValue());}}this.ds.delete(q);}@Overridepublic <T, V> int update(Class<T> clazz, V id, Map<String, Object> updateFieldsMap){Query<T> q = this.ds.find(clazz, "_id =", id);UpdateOperations<T> ops = this.ds.createUpdateOperations(clazz);for (Map.Entry<String, Object> entry : updateFieldsMap.entrySet()){ops.set(entry.getKey(), entry.getValue());}UpdateResults<T> updateResult = this.ds.update(q, ops);return updateResult.getUpdatedCount();}@Overridepublic <T, V> T queryForObjectById(Class<T> clazz, V id) {return this.ds.get(clazz, id);}@Overridepublic <T> List<T> queryForList(Class<T> clazz) {List<T> rtnList = new ArrayList<T>();Query<T> q = this.ds.find(clazz);Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}@Overridepublic <T> List<T> queryForListWithOrder(Class<T> clazz, String orderFields) {List<T> rtnList = new ArrayList<T>();Query<T> q = this.ds.find(clazz);//排序q.order(orderFields);//返回结果Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}@Overridepublic <T, V> List<T> queryForListByConExpr(Class<T> clazz, String property, V value) {List<T> rtnList = new ArrayList<T>();Query<T> q = this.ds.find(clazz, property, value);Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}@Overridepublic <T> List<T> queryForListByConExprMap(Class<T> clazz, Map<String, Object> conditions) {List<T> rtnList = new ArrayList<T>();Set<Entry<String, Object>> set = conditions.entrySet();Query<T> q = this.ds.createQuery(clazz);//过滤for(Entry<String,Object> entry : set){q.filter(entry.getKey(), entry.getValue());}//返回结果Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}@Overridepublic <T> List<T> queryForListByConExprMapWithOrder(Class<T> clazz, Map<String, Object> conditions,String orderFields) {List<T> rtnList = new ArrayList<T>();Set<Entry<String, Object>> set = conditions.entrySet();Query<T> q = this.ds.createQuery(clazz);//过滤for(Entry<String,Object> entry : set){q.filter(entry.getKey(), entry.getValue());}//排序q.order(orderFields);//返回结果Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}@Overridepublic <T> List<T> queryForListByConExprMapWithOrderLimit(Class<T> clazz, Map<String, Object> conditions, String orderFields, int rtnNum) {List<T> rtnList = new ArrayList<T>();Set<Entry<String, Object>> set = conditions.entrySet();Query<T> q = this.ds.createQuery(clazz);//过滤for(Entry<String,Object> entry : set){q.filter(entry.getKey(), entry.getValue());}//排序q.order(orderFields);//取查询结果顶部rtnNum条记录q.limit(rtnNum);//返回结果Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}@Overridepublic <T> List<T> queryForListByConExprMapWithOrderSkipLimit(Class<T> clazz, Map<String, Object> conditions,String orderFields, int skipNum, int rtnNum) {List<T> rtnList = new ArrayList<T>();Set<Entry<String, Object>> set = conditions.entrySet();Query<T> q = this.ds.createQuery(clazz);//过滤for(Entry<String,Object> entry : set){q.filter(entry.getKey(), entry.getValue());}//排序q.order(orderFields);//查询结果指针偏移数q.offset(skipNum);//取查询结果指针位置后的rtnNum记录q.limit(rtnNum);//返回结果Iterator<T> itor = q.fetch().iterator();while (itor.hasNext()){rtnList.add(itor.next());}return rtnList;}/** * 对传入的key通过分割符/进行层次分解, * 例如key为a/b/c/d,分解之后的层次为a, a/b, a/b/c, a/b/c/d四层, * 对每层中的给定的所有字段值加1 * 例如:addFieldsValueFromLeafkey2Rootkey("a/b/c","field1","field2") * 将执行: * _id     field1            field2 * ------------------------------------------ * a/b/c   field1.value+1    field2.value+1 * a/b     field1.value+1    field2.value+1 * a       field1.value+1    field2.value+1 *  * @param leafkey 叶层次的key值 * @param fieldNames 需要字段值加1的字段 */public void incFieldsValueFromLeafkey2Rootkey(Class clazz,String leafkey, String...fieldNames){this.addFieldsValueFromLeafkey2Rootkey(clazz, leafkey, 1, fieldNames);}public void addFieldsValueFromLeafkey2Rootkey(Class clazz, String leafkey, int value, String...fieldNames){DBCollection coll = this.ds.getCollection(clazz);for (String fieldName:fieldNames){recurseAddVisitCount(coll, leafkey, value, fieldName);}}public void incFieldsValue(Class clazz, Object primaryKeyValue, String...fieldNames){this.addFieldsValue(clazz, primaryKeyValue, 1, fieldNames);}public void addFieldsValue(Class clazz, Object primaryKeyValue, int value, String...fieldNames){DBCollection coll = this.ds.getCollection(clazz);for (String fieldName:fieldNames){addFieldValue(coll, primaryKeyValue, value, fieldName);}}private void addFieldValue(DBCollection coll, Object primaryKeyValue, int value, String fieldName){if (primaryKeyValue==null) return;BasicDBObject conditionDBObject = new BasicDBObject();conditionDBObject.put(MONGO_ID_KEY, primaryKeyValue);BasicDBObject valDBObject = new BasicDBObject();valDBObject.put(fieldName, value);BasicDBObject updateDBObject = new BasicDBObject();updateDBObject.put("$inc", valDBObject);coll.update(conditionDBObject, updateDBObject, true, false);}private static final String KEY_SEPERATOR = "/"; //db.c.update({_id:10},{$inc:{count:value}})private void recurseAddVisitCount(DBCollection coll, String key, int value, String fieldName){if (key==null || key.trim().equals("")) return;if(key.startsWith(KEY_SEPERATOR) || key.endsWith(KEY_SEPERATOR))throw new RuntimeException("key can't start or end with "+KEY_SEPERATOR+",because it is key seperator.");BasicDBObject conditionDBObject = new BasicDBObject();conditionDBObject.put(MONGO_ID_KEY, key);BasicDBObject valDBObject = new BasicDBObject();valDBObject.put(fieldName, value);BasicDBObject updateDBObject = new BasicDBObject();updateDBObject.put("$inc", valDBObject);coll.update(conditionDBObject, updateDBObject, true, false);int pos = key.lastIndexOf(KEY_SEPERATOR);if (pos>0){String newKey = key.substring(0,pos);recurseAddVisitCount(coll, newKey, value, fieldName);}}}//业务层具体实现增,删,改,查,/** * 评分 */@Servicepublic class BookScoreMongoManager{@Autowiredprivate OriginalBookManager originalBookManager;@Autowiredprivate PaperBookManager paperBookManager;/** * 插入评分mongo表 * @param bookScoreMongo * @return */public Long insertBookScoreMongo(BookScoreMongo bookScoreMongo){return (Long)MongoServiceDAO.getInstance().saveRtnKey(bookScoreMongo);}/** * 通过ID获取评分mongo数据 * @param id * @return */public BookScoreMongo getBookScoreMongoById(Long id){return MongoServiceDAO.getInstance().queryForObjectById(BookScoreMongo.class, id);}/** * 修改个人对书的评分分数 * @param bookScoreMongo * @param score */private void updateBookScoreMongoById(BookScoreMongo bookScoreMongo ,Long score){if(score!=null && score>0 ){Map<String, Object> updateFieldsMap = new HashMap<String, Object>();updateFieldsMap.put("score", score);MongoServiceDAO.getInstance().update(BookScoreMongo.class,bookScoreMongo.geId(),updateFieldsMap);}}/** * 通过书籍ID,书籍类型和用户ID取评分mongo * @param bookid * @param userid * @param booktype  * @return */    public BookScoreMongo getScoreById(Long bookId,Integer userid,Integer booktype){     Map<String,Object>  maps = new HashMap<String,Object>();        maps.put("bookId",bookId);        maps.put("userId",userid);        maps.put("bookType",booktype);        List<BookScoreMongo> list = MongoServiceDAO.getInstance().queryForListByConExprMapWithOrderLimit(BookScoreMongo.class,maps,"",1);        if(list != null && list.size() > 0){        return list.get(0);        }else{        return null;        }    }public BookScoreMongo getScoreByBookidUserId(Long bookid,Integer userid,Integer booktype){Map<String, Object> conditions = new HashMap<String, Object>();conditions.put("bookId", bookid);conditions.put("userId", userid);conditions.put("bookType", booktype);List<BookScoreMongo> list = MongoServiceDAO.getInstance().queryForListByConExprMapWithOrderLimit(BookScoreMongo.class,conditions,"",1);if(list != null && list.size() >0){return list.get(0);}else{return null;}}   public void updateByBookUserId(Long bookId,Integer userid,Long score,Integer booktype){   if(score != null && score > 0){      }   }/** * 插入或者修改个人评分分数 * @param bookid * @param userid * @param score * @param booktype(1为原创,2为藏书) */public void updateByBookidUserId(Long bookid,Integer userid,Long score,Integer booktype){if(score != null && score >0){BookScoreMongo bookScoreMongo = getScoreByBookidUserId(bookid,userid,booktype);if(bookScoreMongo != null){if(score != bookScoreMongo.getScore()){updateBookScoreMongoById(bookScoreMongo,score);//修改总分数if(booktype.equals(1)){originalBookManager.changScore(bookid,score,bookScoreMongo.getScore());}else if(booktype.equals(2)){paperBookManager.changScore(bookid,score,bookScoreMongo.getScore());}}}else{bookScoreMongo = new BookScoreMongo();bookScoreMongo.setBookId(bookid);bookScoreMongo.setUserId(userid);bookScoreMongo.setScore(score);bookScoreMongo.setBookType(booktype);insertBookScoreMongo(bookScoreMongo);//修改总分数和评分总人数if(booktype.equals(1)){originalBookManager.addScoreSun(bookid,score);}else if(booktype.equals(2)){paperBookManager.addScoreSun(bookid,score);}}}}}@SuppressWarnings("serial")public class BookScoreAction extends ActionSupport{/**书籍ID*/private int bookId;/**分数*/private int score;/**类型 (如1是原创,2是藏书)*/private int type;private int userId;/** * ids */private String ids;@Autowiredprivate BookScoreMongoManager bookScoreMongoManager;@Autowiredprivate PaperBookManager paperBookManager;@Autowiredprivate OriginalBookManager originalBookManager;public String getIds() {return ids;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public void setIds(String ids) {this.ids = ids;}protected final ObjectMapper mapper = new ObjectMapper();/** * 对书进行评分Action */public void insertScore() throws Exception{if(userId != 0){BookUserUtil.scored(userId,bookId,type,score);}else{BookUserUtil.scored(RequestContext.getCurrUser().getId().intValue(),bookId,type,score);}Map<String, Object> scoreMap = new HashMap<String, Object>();bookScoreMongoManager.updateByBookidUserId((long) bookId,RequestContext.getCurrUser().getId().intValue(), (long) score,type);BookScoreMongo bookScoreMongo = bookScoreMongoManager.getScoreByBookidUserId((long)bookId, RequestContext.getCurrUser().getId().intValue(), type);scoreMap.put("bookScoreMongo", bookScoreMongo);// 藏书if (type == 2) {PaperBookMongo paperBookMongo = paperBookManager.getMongoBookById((long) bookId);scoreMap.put("paperBookMongo", paperBookMongo);} else if (type == 1) {OriginalBookMongo originalBookMongo = originalBookManager.getMongoBookById((long) bookId);scoreMap.put("originalBookMongo", originalBookMongo);}String result =mapper.writeValueAsString(scoreMap);Struts2Utils.renderJson(result);}/** * 根据登入userId获取用户对 原创/藏书的评分 */public void getScoreByUser(){Struts2Utils.renderJson(bookScoreMongoManager.getScoreByBookidUserId((long)bookId,RequestContext.getCurrUser().getId().intValue(),type));}/** * 根据传入userId获取用户对 原创/藏书的评分 */public void getScoreByOtherUser(){Struts2Utils.renderJson(bookScoreMongoManager.getScoreByBookidUserId((long)bookId,userId,type));}/** * 批量获取评分统计 *///public void getStatisticList(){////List<Integer> params=null;////if (ids != null && !"".equals(ids)) {//params = new ArrayList<Integer>();//String[] idArr = ids.split(",");//for (int i = 0; i < idArr.length; i++) {//params.add(Integer.parseInt(idArr[i]));//}//}////evaluationManager.get//Struts2Utils.renderJson(scoreManager.getScoreStatisticals(params, type));//}public int getBookId() {return bookId;}public void setBookId(int bookId) {this.bookId = bookId;}public int getType() {return type;}public void setType(int type) {this.type = type;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}}
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表