//mongoDB ,创建一个自动增长的ID
public 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);
}
@Override
public <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();
}
@Override
public <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);
}
@Override
public <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();
}
@Override
public <T, V> T queryForObjectById(Class<T> clazz, V id) {
return this.ds.get(clazz, id);
}
@Override
public <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;
}
@Override
public <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;
}
@Override
public <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;
}
@Override
public <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;
}
@Override
public <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;
}
@Override
public <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;
}
@Override
public <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);
}
}
}
//业务层具体实现增,删,改,查,
/**
* 评分
*/
@Service
public class BookScoreMongoManager{
@Autowired
private OriginalBookManager originalBookManager;
@Autowired
private 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;
@Autowired
private BookScoreMongoManager bookScoreMongoManager;
@Autowired
private PaperBookManager paperBookManager;
@Autowired
private 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;
}
}
MongoDb应用
最新推荐文章于 2025-04-04 17:20:36 发布