崛起於Springboot2.X+ MongoDB讀寫分離(25)

《SpringBoot2.X心法總綱》javascript

優化本篇博客最新時間:2019/08/17java

一、pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
    <groupId>org.mongodb.morphia</groupId>
    <artifactId>morphia</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.7</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.5.16</version>
</dependency>

二、application.properties

spring.data.mongodb.uri=mongodb://localhost:27017/xbl

#下面是主庫,讀庫,寫庫
mongoDBName=xbl
mongoDBIP=127.0.0.1
mongoDBPORT=27017
mongoDBCheck=(drop|remove|kill|shutdown|rename|update|insert|save|add|use)
mongodbConnectionsCount=1000

mongoDBWriteName=xbl
mongoDBWriteIP=127.0.0.1
mongoDBWritePORT=27017
mongoDBWriteCheck=(drop|remove|kill|shutdown|rename|update|insert|save|add|use)
mongodbWriteConnectionsCount=1000

mongoDBReadName=xbl
mongoDBReadIP=127.0.0.1
mongoDBReadPORT=27017
mongoDBReadCheck=(drop|remove|kill|shutdown|rename|update|insert|save|add|use)
mongodbReadConnectionsCount=1000

三、參數實體類

public class Constant {
    /**
     * 文件模型
     */
    public static final String model_files = "files";

    /**
     * 建立時間
     */
    public static final String CREATED_AT = "createdAt";

    /**
     * 更新時間
     */
    public static final String UPDATED_AT = "updatedAt";

    /**
     * 主鍵key
     */
    public static final String OBJECTID = "objectId";
}
import cn.hutool.setting.dialect.Props;

public class MongodbConstant {

    /**
     * mongodb主庫
     */
    public static String mongoDBHOSTS;
    public static String mongoDBPORTS;
    public static String mongoDBIP;
    public static String mongoDBPORT;
    public static String mongoDBName;
    public static String mongoDBCheck;
    public static String mongodbConnectionsCount;

    /**
     * mongodb寫
     */
    public static String mongoDBWriteHOSTS;
    public static String mongoDBWritePORTS;
    public static String mongoDBWriteIP;
    public static String mongoDBWritePORT;
    public static String mongoDBWriteName;
    public static String mongoDBWriteCheck;
    public static String mongodbWriteConnectionsCount;

    /**
     * mongodb讀
     */
    public static String mongoDBReadHOSTS;
    public static String mongoDBReadPORTS;
    public static String mongoDBReadIP;
    public static String mongoDBReadPORT;
    public static String mongoDBReadName;
    public static String mongoDBReadCheck;
    public static String mongodbReadConnectionsCount;

    static{
        try {
            Props p = new Props("application.properties");

            mongoDBName= p.getProperty("mongoDBName");
            mongodbConnectionsCount= p.getProperty("mongodbConnectionsCount");
            mongoDBHOSTS = p.getProperty("mongoDBHOSTS");
            mongoDBPORTS = p.getProperty("mongoDBPORTS");
            mongoDBIP= p.getProperty("mongoDBIP");
            mongoDBPORT= p.getProperty("mongoDBPORT");
            mongoDBCheck= p.getProperty("mongoDBCheck");

            mongoDBWriteName= p.getProperty("mongoDBWriteName");
            mongodbWriteConnectionsCount= p.getProperty("mongodbWriteConnectionsCount");
            mongoDBWriteHOSTS = p.getProperty("mongoDBWriteHOSTS");
            mongoDBWritePORTS = p.getProperty("mongoDBWritePORTS");
            mongoDBWriteIP= p.getProperty("mongoDBWriteIP");
            mongoDBWritePORT= p.getProperty("mongoDBWritePORT");
            mongoDBWriteCheck= p.getProperty("mongoDBWriteCheck");

            mongoDBReadName= p.getProperty("mongoDBReadName");
            mongodbReadConnectionsCount= p.getProperty("mongodbReadConnectionsCount");
            mongoDBReadHOSTS = p.getProperty("mongoDBReadHOSTS");
            mongoDBReadPORTS = p.getProperty("mongoDBReadPORTS");
            mongoDBReadIP= p.getProperty("mongoDBReadIP");
            mongoDBReadPORT= p.getProperty("mongoDBReadPORT");
            mongoDBReadCheck= p.getProperty("mongoDBReadCheck");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、抽象配置類

import com.mongodb.DB;
import com.mongodb.MongoClient;
import lombok.extern.slf4j.Slf4j;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;

@Slf4j
public abstract class AbstarctMongoDBConnection {

    protected MongoClient instance = null;

    protected boolean isRenew = false;

    protected volatile boolean isShard = true;

    public abstract MongoClient getMongoClient();

    public DB getDB(String dbname) {
        return getMongoClient().getDB(dbname);
    }

    public Datastore getDataStore(String dbname) {
        Morphia morphia = new Morphia();
        return morphia.createDatastore(getMongoClient(), dbname);
    }

    public boolean isShard() {
        return isShard;
    }
}

五、繼承抽象

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.tssd.school.entity.comm.MongodbConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class MongoDBConnection extends AbstarctMongoDBConnection{

    /**
     * Mongodb鏈接實例
     * @return
     */
    @Override
    public MongoClient getMongoClient() {
        if(super.instance==null){
            try {
                MongoClientOptions.Builder build = new MongoClientOptions.Builder();
                build.connectionsPerHost(Integer.valueOf(MongodbConstant.mongodbConnectionsCount));//鏈接數
                build.connectTimeout(5000);//鏈接超時時間
                build.maxWaitTime(10000);//最大等待時間
                build.socketKeepAlive(true);//保持鏈接
                build.socketTimeout(0);//0,不限時間
                build.threadsAllowedToBlockForConnectionMultiplier(50);
                MongoClientOptions options = build.build();
                List<ServerAddress> addresses = new ArrayList<ServerAddress>();
                if (StringUtils.isNotEmpty(MongodbConstant.mongoDBHOSTS)) {
                    String[] hosts = MongodbConstant.mongoDBHOSTS.split(",");
                    String[] ports = MongodbConstant.mongoDBPORTS.split(",");
                    for (int i = 0; i < hosts.length; i++) {
                        ServerAddress address = new ServerAddress(hosts[i], Integer.valueOf(ports[i]));
                        addresses.add(address);
                    }
                    super.instance = new MongoClient(addresses, options);
                    super.isShard = true;
                }else{
                    ServerAddress addr = new ServerAddress(MongodbConstant.mongoDBIP, Integer.valueOf(MongodbConstant.mongoDBPORT));
                    super.instance = new MongoClient(addr, options);
                    super.isShard = false;
                }
            } catch (NumberFormatException e) {
                log.error("Mongon數據庫服務器鏈接失敗!", e);
            }
        }
        return super.instance;
    }
}
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.tssd.school.entity.comm.MongodbConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class MongoDBReadConnection extends AbstarctMongoDBConnection {

    @Override
    public MongoClient getMongoClient() {
        if(super.instance==null){
            try {
                MongoClientOptions.Builder build = new MongoClientOptions.Builder();
                //build.autoConnectRetry(true);//是否鏈接自動重試

                build.connectionsPerHost(Integer.valueOf(MongodbConstant.mongodbConnectionsCount));//鏈接數
                build.connectTimeout(5000);//鏈接超時時間
                build.maxWaitTime(10000);//最大等待時間
                build.socketKeepAlive(true);//保持鏈接
                build.socketTimeout(0);//0,不限時間
                //build.maxAutoConnectRetryTime(1);//最大重試時間,單位秒
                build.threadsAllowedToBlockForConnectionMultiplier(50);
                MongoClientOptions options = build.build();

                List<ServerAddress> addresses = new ArrayList<ServerAddress>();
                if (StringUtils.isNotEmpty(MongodbConstant.mongoDBReadHOSTS)) {
                    String[] hosts = MongodbConstant.mongoDBReadHOSTS.split(",");
                    String[] ports = MongodbConstant.mongoDBReadHOSTS.split(",");
                    for (int i = 0; i < hosts.length; i++) {
                        ServerAddress address = new ServerAddress(hosts[i], Integer.valueOf(ports[i]));
                        addresses.add(address);
                    }
                    super.instance = new MongoClient(addresses, options);
                    super.isShard = true;
                }else{
                    ServerAddress addr = new ServerAddress(MongodbConstant.mongoDBReadIP, Integer.valueOf(MongodbConstant.mongoDBReadPORT));
                    super.instance = new MongoClient(addr, options);
                    super.isShard = false;
                }
            } catch (NumberFormatException e) {
                log.error("Mongon數據庫服務器鏈接失敗!", e);
            }
        }
        return super.instance;
    }
}
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.tssd.school.entity.comm.MongodbConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class MongoDBWriteConnection extends AbstarctMongoDBConnection {

    @Override
    public MongoClient getMongoClient() {
        if(super.instance==null){
            try {
                MongoClientOptions.Builder build = new MongoClientOptions.Builder();
               //build.autoConnectRetry(true);//是否鏈接自動重試
                build.connectionsPerHost(Integer.valueOf(MongodbConstant.mongodbWriteConnectionsCount));//鏈接數
                build.connectTimeout(5000);//鏈接超時時間
                build.maxWaitTime(10000);//最大等待時間
                build.socketKeepAlive(true);//保持鏈接
                build.socketTimeout(0);//0,不限時間
                //build.maxAutoConnectRetryTime(1);//最大重試時間,單位秒
                build.threadsAllowedToBlockForConnectionMultiplier(50);
                MongoClientOptions options = build.build();

                List<ServerAddress> addresses = new ArrayList<ServerAddress>();
                if (StringUtils.isNotEmpty(MongodbConstant.mongoDBWriteHOSTS)) {
                    String[] hosts = MongodbConstant.mongoDBWriteHOSTS.split(",");
                    String[] ports = MongodbConstant.mongoDBWritePORTS.split(",");
                    for (int i = 0; i < hosts.length; i++) {
                        ServerAddress address = new ServerAddress(hosts[i], Integer.valueOf(ports[i]));
                        addresses.add(address);
                    }
                    super.instance = new MongoClient(addresses, options);
                    super.isShard = true;
                }else{
                    ServerAddress addr = new ServerAddress(MongodbConstant.mongoDBWriteIP, Integer.valueOf(MongodbConstant.mongoDBWritePORT));
                    super.instance = new MongoClient(addr, options);
                    super.isShard = false;
                }
            } catch (NumberFormatException e) {
                log.error("Mongon數據庫服務器鏈接失敗!", e);
            }
        }
        return super.instance;
    }
}

六、接口類

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.WriteResult;

import java.util.List;

/**
 * @Author:MuJiuTian
 * @Date:2019/8/17 下午4:07
 * @Description:model:集合名
 */

public interface IMongoDAO {
    
    JSONObject save(String model, String json);

    JSONObject save(String model, JSONArray list);

    JSONObject delete(String model, String id);
    
    void delete(String model, DBObject where);

    JSONObject update(String model, String json, String id);

    JSONObject updateUnset(String model, String json, String id) ;

    /**
     * inc(自增加)
     */
    JSONObject inc(String model, String json, String id);

    /**
     * 批量自增加
     */
    JSONObject batchInc(String model, String json, JSONObject condition);

    JSONArray aggregate(String model, String query, String sort, int skip, int limit);
    /**
     * 聚合函數 aggregate
     * 經過管道操做:具體可用管道以下:
     * $project:修改輸入文檔的結構。能夠用來重命名、增長或刪除域,也能夠用於建立計算結果以及嵌套文檔。
     * $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做。
     * $limit:用來限制MongoDB聚合管道返回的文檔數。
     * $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
     * $unwind:將文檔中的某一個數組類型字段拆分紅多條,每條包含數組中的一個值。
     * $group:將集合中的文檔分組,可用於統計結果。
     * $sort:將輸入文檔排序後輸出。
     * $geoNear:輸出接近某一地理位置的有序文檔。
     * 下面是表達式內的能夠函數
     * $sum、$avg、$min、$max、$push、$addToSet、$first、$last
     */
    JSONArray aggregate(String model, List<String> conditions);
    
    JSONArray aggregate(String model, List<String> conditions,String type);
    /**
     * 聚合函數
     */
    JSONArray aggregate(String model, String pipeline) throws Exception;
    
    String get(String model, String id);
    
    DBObject find(String where, String fields, String orderBy, String model, int skip, int size) ;

    DBObject find(String where, String fields, String orderBy, String model) ;

    /**
     * distinct(高級查詢)
     * @param query 查詢條件
     * @param fieldName 指定字段
     * @param model 查詢模型
     * @return List<DBObject>
     */
    List<?> distinct(String query,String fieldName, String model) ;

    /**
     * eval(在mongo Server上執行js函數)
     */
    String eval(String function, String json) ;

    /**
     * 原子修改操做
     * @param returnNew true返回修改後數據,false 返回修改前的數據
     * @param upsert true 修改的記錄不存在則新增一條
     * @return
     */
    JSONObject findAndModify(String model, String where, String update, boolean returnNew, boolean upsert);

    /**
     * 插入
     * @param model 集合名
     * @param obj 新文檔
     */

    WriteResult insert(String model, DBObject obj) ;

    /**
     * 查詢 
     * @param obj 條件文檔
     * @return DBCursor 遊標
     */
    DBCursor find(String model, DBObject obj) ;

    /**
     * 查詢unique
     * @param obj 條件文檔
     * @return DBObject 文檔對象
     */
    DBObject findOne(String model, DBObject obj) ;

    /**
     * 查詢
     * @param key  查詢條件鍵
     * @param value 查詢條件值
     * @return DBCursor 遊標
     */
    DBCursor find(String model, String key, String value) ;

    DBCursor find(String model, String key, Object value) ;

    /**
     * 查詢unique
     * @param key 查詢條件鍵
     * @param value 查詢條件值
     */
    DBObject findOne(String model, String key, String value) ;

    JSONObject updateByCondition(String model, String json, String condition);

}
public class MongoDAO extends AbstractMongoDAO{
   
   private static MongoDAO instance = new MongoDAO();
   
   private MongoDAO(){
      super.dbConnection = new MongoDBConnection();
      super.db = super.dbConnection.getDB(KeegooConfig.mongoDBName);
      super.db.setReadPreference(ReadPreference.nearest());
   }
   
   public static MongoDAO getInstance(){
      return instance;
   }
   
}
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.*;
import com.mongodb.util.JSON;
import com.tssd.school.config.AbstarctMongoDBConnection;
import com.tssd.school.entity.comm.Constant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

@SuppressWarnings("deprecation")
@Slf4j
public abstract class AbstractMongoDAO implements IMongoDAO {

    protected DB db;
    protected AbstarctMongoDBConnection dbConnection;

    /**
     * save(新增)
     * @param model
     * @param json
     * @return
     * @throws Exception
     *             String
     * @exception
     * @since 1.0.0
     */
    public JSONObject save(String model, String json) {
//    if(!db.collectionExists(model)){
//       shardCollection(KeegooConfig.mongoDBName, model, "_id");
//    }
        String date = DateUtil.format(new Date(),DateFormat.getDateTimeInstance());
        DBObject dbObject = (DBObject) JSON.parse(json);

        ObjectId id = null;
        String objectId = dbObject.get(Constant.OBJECTID)==null?null:(String)dbObject.get(Constant.OBJECTID);
        if(StringUtils.isEmpty(objectId)){
            id = ObjectId.get();
            objectId = id.toString();
        }else{
            id = new ObjectId(objectId);
        }

        dbObject.put("_id", id);// 系統主鍵
        dbObject.put(Constant.OBJECTID, objectId);// 業務主鍵
        dbObject.put(Constant.CREATED_AT, date);
        dbObject.put(Constant.UPDATED_AT, date);
        DBCollection dbCollection = db.getCollection(model);
        dbCollection.insert(dbObject, WriteConcern.SAFE);
        JSONObject returnValue = new JSONObject();
        returnValue.put(Constant.OBJECTID, objectId);// 業務主鍵
        returnValue.put(Constant.CREATED_AT, date);
        returnValue.put(Constant.UPDATED_AT, date);
        return returnValue;
    }

    public JSONObject save(String model, JSONArray list){

        String date = DateUtil.format(new Date(),DateFormat.getDateTimeInstance());
        List<DBObject> insert_list = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            DBObject db = (DBObject)JSON.parse(list.getString(i));
            ObjectId id = null;
            String objectId = db.get(Constant.OBJECTID)==null?null:(String)db.get(Constant.OBJECTID);
            if(StringUtils.isEmpty(objectId)){
                id = ObjectId.get();
                objectId = id.toString();
            }else{
                id = new ObjectId(objectId);
            }
            db.put("_id", id);// 系統主鍵
            db.put(Constant.OBJECTID, objectId);// 業務主鍵
            db.put(Constant.CREATED_AT, date);
            db.put(Constant.UPDATED_AT, date);
            insert_list.add(db);
        }

        DBCollection dbCollection = db.getCollection(model);
        WriteResult insert = dbCollection.insert(insert_list, WriteConcern.SAFE);
        JSONObject returnValue = new JSONObject();
        returnValue.put("save_count", insert.getN());// 業務主鍵
        returnValue.put(Constant.CREATED_AT, date);
        returnValue.put(Constant.UPDATED_AT, date);
        return returnValue;
    }


    public JSONObject delete(String model, String id) {

        DBCollection dbCollection = db.getCollection(model);
        String date = DateUtil.format(new Date(),DateFormat.getDateTimeInstance());
        DBObject dbObject = new BasicDBObject(Constant.OBJECTID, id);
        WriteResult wr = dbCollection.remove(dbObject,WriteConcern.SAFE);
        if(wr.getN()<=0) {
            return null;
        }

        JSONObject returnValue = new JSONObject();
        returnValue.put(Constant.OBJECTID, id);// 業務主鍵
        returnValue.put(Constant.UPDATED_AT, date);
        return returnValue;
    }

    /**
     * 刪除
     * @param collection
     *            集合名
     * @param delObj
     *            刪除目標條件
     */
    public void delete(String collection, DBObject delObj) {
        DBCollection dbCollection = db.getCollection(collection);
        dbCollection.remove(delObj);
    }

    /**
     * update(更新)
     * @param model
     * @param json
     * @param id
     * @return String
     * @exception
     * @since 1.0.0
     */
    public JSONObject update(String model, String json, String id) {
        if(StringUtils.isEmpty(id)){
            return null;
        }
        DBCollection dbCollection = db.getCollection(model);
        DBObject updateDBObject = (DBObject) JSON.parse(json);
        String date = DateUtil.format(new Date(),DateFormat.getDateTimeInstance());
        updateDBObject.put(Constant.UPDATED_AT, date);
        WriteResult wr = dbCollection.update(new BasicDBObject(Constant.OBJECTID, id), new BasicDBObject("$set", updateDBObject),false,true,WriteConcern.SAFE);
        if(wr.getN()<=0 || !wr.isUpdateOfExisting()) {
            return null;
        }

        JSONObject returnValue = new JSONObject();
        returnValue.put(Constant.OBJECTID, id);// 業務主鍵
        returnValue.put(Constant.UPDATED_AT, date);
        return returnValue;
    }

    public JSONObject updateUnset(String model, String json, String id) {
        if(StringUtils.isEmpty(id)){
            return null;
        }
        DBCollection dbCollection = db.getCollection(model);
        DBObject updateDBObject = (DBObject) JSON.parse(json);
        String date = DateUtil.format(new Date(),DateFormat.getDateTimeInstance());
        updateDBObject.put(Constant.UPDATED_AT, date);
        WriteResult wr = dbCollection.update(new BasicDBObject(Constant.OBJECTID, id), new BasicDBObject("$unset", updateDBObject),false,true,WriteConcern.SAFE);
        if(wr.getN()<=0 || !wr.isUpdateOfExisting()) {
            return null;
        }
        JSONObject returnValue = new JSONObject();
        returnValue.put(Constant.OBJECTID, id);// 業務主鍵
        returnValue.put(Constant.UPDATED_AT, date);
        return returnValue;
    }

    /**
     *
     * inc(自增加)
     *
     * @param model
     * @param json
     * @param id
     * @return String
     * @exception
     * @since 1.0.0
     */
    public JSONObject inc(String model, String json, String id) {
        if(StringUtils.isEmpty(id)){
            return null;
        }
        DBCollection dbCollection = db.getCollection(model);
        DBObject updateDBObject = (DBObject) JSON.parse(json);
        BasicDBObject query = new BasicDBObject(Constant.OBJECTID, id);
        query.put("objectId", id);
        DBObject findAndModify = dbCollection.findAndModify(query, new BasicDBObject("$inc", updateDBObject));
        if (findAndModify==null) {
            return null;
        }
        return JSONObject.parseObject(findAndModify.toString());
    }

    /**
     * 批量自增加
     * @param model
     * @param json
     * @param condition
     * @return
     * @throws ServiceException
     */
    public JSONObject batchInc(String model, String json, JSONObject condition) {
        DBCollection dbCollection = db.getCollection(model);
        DBObject updateDBObject = (DBObject) JSON.parse(json);
        BasicDBObject query = new BasicDBObject(condition);
        WriteResult wr = dbCollection.update(query, new BasicDBObject("$inc", updateDBObject),false,true,WriteConcern.SAFE);
        if(wr.getN()<=0 || !wr.isUpdateOfExisting()) {
            return null;
        }
        JSONObject returnValue = new JSONObject();
        returnValue.put(Constant.UPDATED_AT, DateUtil.format(new Date(),DateFormat.getDateInstance()));
        return returnValue;
    }

    /**
     * 聚合函數
     * @param model 表
     * @param query 查詢條件
     * @param sort 排序
     * @param skip 分頁
     * @param limit 分頁
     * @return
     * @throws Exception
     */
    public JSONArray aggregate(String model, String query, String sort, int skip, int limit) {
        if(StringUtils.isBlank(model)||StringUtils.isBlank(query)){
            return null;
        }
        DBCollection dbCollection = db.getCollection(model);
        BasicDBObject $query = (BasicDBObject)JSON.parse(query);
        BasicDBObject $skip = new BasicDBObject("$skip", skip);
        BasicDBObject $limit = new BasicDBObject("$limit", limit);
        List<BasicDBObject> list = new ArrayList<BasicDBObject>();
        list.add($query);
        if(StringUtils.isNotBlank(sort)){
            list.add((new BasicDBObject("$sort", (BasicDBObject)JSON.parse(sort))));
        }
        list.add($skip);
        list.add($limit);
        AggregationOutput out = dbCollection.aggregate(list);
        Iterator<DBObject> itor = out.results().iterator();
        JSONArray results = new JSONArray();
        while(itor.hasNext()){
            results.add(JSONObject.parseObject(itor.next().toString()));
        }
        return results;
    }
    /**
     * 聚合函數
     * aggregate:
     * @author sid
     * @param model
     * @param conditions
     * 經過管道操做;具體可用管道以下:
     * $project:修改輸入文檔的結構。能夠用來重命名、增長或刪除域,也能夠用於建立計算結果以及嵌套文檔。
     * $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做。
     * $limit:用來限制MongoDB聚合管道返回的文檔數。
     * $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
     * $unwind:將文檔中的某一個數組類型字段拆分紅多條,每條包含數組中的一個值。
     * $group:將集合中的文檔分組,可用於統計結果。
     * $sort:將輸入文檔排序後輸出。
     * $geoNear:輸出接近某一地理位置的有序文檔。
     * 下面是表達式內的能夠函數
     * $sum、$avg、$min、$max、$push、$addToSet、$first、$last
     * @return
     * @throws Exception
     */
    public JSONArray aggregate(String model, List<String> conditions) {
        DBCollection dbCollection = db.getCollection(model);
        List<BasicDBObject> list = new ArrayList<BasicDBObject>();
        for (String str : conditions) {
            list.add((BasicDBObject)JSON.parse(str));
        }
        AggregationOutput out = dbCollection.aggregate(list);
        Iterator<DBObject> itor = out.results().iterator();
        JSONArray results = new JSONArray();
        while(itor.hasNext()){
            results.add(JSONObject.parseObject(itor.next().toString()));
        }
        return results;
    }
    public JSONArray aggregate(String model, List<String> conditions,String type) {
        DBCollection dbCollection = db.getCollection(model);
        List<BasicDBObject> list = new ArrayList<BasicDBObject>();
        for (String str : conditions) {
            list.add((BasicDBObject)JSON.parse(str));
        }
        AggregationOutput out = dbCollection.aggregate(list);
        Iterator<DBObject> itor = out.results().iterator();
        JSONArray results = new JSONArray();
        while(itor.hasNext()){
            JSONObject jsonObject =JSONObject.parseObject(itor.next().toString());
            jsonObject.put("type",type);
            jsonObject.put(type+"Count",jsonObject.getString("count"));
            results.add(jsonObject);
        }
        return results;
    }
    /**
     * 聚合函數
     * @param model
     * @param pipeline
     * @return
     * @throws Exception
     */
    public JSONArray aggregate(String model, String pipeline) {
        DBCollection table = db.getCollection(model);
        @SuppressWarnings("unchecked")
        List<BasicDBObject> list = (ArrayList<BasicDBObject>) JSON.parse(pipeline);
        AggregationOutput output = table.aggregate(list);
        Iterator<DBObject> itor = output.results().iterator();
        JSONArray results = new JSONArray();
        while(itor.hasNext()){
            //DBObject o = itor.next();
            results.add(JSONObject.parseObject(itor.next().toString()));
        }
        return results;
    }

    /**
     *
     * get(按id查找)
     *
     * @param model
     * @param id
     * @return String
     * @exception
     * @since 1.0.0
     */
    public String get(String model, String id) {
        if(StringUtils.isEmpty(id)){
            return null;
        }
        String cacheString = null;//cacheService.get(model+":"+id);
        if(StringUtils.isBlank(cacheString)){
            DBCollection dbCollection = db.getCollection(model);
            DBObject dbObject = dbCollection.findOne(new BasicDBObject(Constant.OBJECTID, id));
            if(dbObject!=null){
                cacheString = dbObject.toString();
            }
        }
        if(StringUtils.isBlank(cacheString)){
            return null;
        }
        return cacheString;
    }

    /**
     *
     * find(高級查詢)
     * @param query
     *            查詢條件
     * @param fields
     *            返回字段
     * @param orderBy
     *            排序條件
     * @param model
     *            查詢模型
     * @param numToSkip
     *            跳過條數
     * @param batchSize
     *            返回條數
     * @return List<DBObject>
     * @exception
     * @since 1.0.0
     */
    public DBObject find(String where, String fields, String orderBy, String model, int skip, int size) {
        DBCollection dbCollection = db.getCollection(model);
        DBObject ref = (DBObject) JSON.parse(where);
        DBObject keys = (DBObject) JSON.parse(fields);
        keys.put("_id", 0);//不返回系統主鍵
        DBObject order = (DBObject) JSON.parse(orderBy);
        DBCursor dbCursor = dbCollection.find(ref, keys).sort(order).skip(skip).limit(size);
        BasicDBList list = new BasicDBList();
        DBObject result = new BasicDBObject();
        while (dbCursor.hasNext()) {
            list.add(dbCursor.next());
        }
        result.put("count", dbCursor.count());
        result.put(Constant.RESULTS, list);
        return result;
    }

    /**
     *
     * find(高級查詢)
     *
     * @param query
     *            查詢條件
     * @param fields
     *            返回字段
     * @param orderBy
     *            排序條件
     * @param model
     *            查詢模型
     * @return List<DBObject>
     * @exception
     * @since 1.0.0
     */
    @Override
    public DBObject find(String where, String fields, String orderBy, String model) {
        DBCollection dbCollection = db.getCollection(model);
        DBObject ref = (DBObject) JSON.parse(where);
        DBObject keys = (DBObject) JSON.parse(fields);
        keys.put("_id", 0);//不返回系統主鍵
        DBObject order = (DBObject) JSON.parse(orderBy);
        DBCursor dbCursor = dbCollection.find(ref, keys).sort(order);
        BasicDBList list = new BasicDBList();
        DBObject result = new BasicDBObject();
        while (dbCursor.hasNext()) {
            list.add(dbCursor.next());
        }
        result.put("count", dbCursor.count());
        result.put(Constant.RESULTS, list);
        return result;
    }

    /**
     *
     * distinct(高級查詢)
     *
     * @param query
     *            查詢條件
     * @param fieldName
     *            指定字段
     * @param model
     *            查詢模型
     * @return List<DBObject>
     * @exception
     * @since 1.0.0
     */
    @Override
    public List<?> distinct(String query,String fieldName, String model) {
        DBCollection dbCollection = db.getCollection(model);
        DBObject q = (DBObject) JSON.parse(query);
        List<?> distincts = dbCollection.distinct(fieldName, q);
        return distincts;
    }

    /**
     *
     * eval(在mongo Server上執行js函數)
     *
     * @param function
     * @param args
     * @return String
     * @exception
     * @since 1.0.0
     */
    @Override
    public String eval(String function, String json) {
        // 使用javascript最好是預先定義好註冊到數據庫服務端,客戶端傳入函數名及參數便可
        String code = "function(obj){return "+function+"(obj);}";
        DBObject obj = (DBObject) JSON.parse(json);
        Object o = db.eval(code, obj);
        String value = null;
        if(o instanceof Boolean){
            value = String.valueOf(((Boolean)o).booleanValue());
        }else if(o instanceof Number){
            value = String.valueOf((Number)o);
        }else if(o instanceof String){
            value = String.valueOf(o);
        }else if(o instanceof BasicDBObject){
            value = ((BasicDBObject)o).toString();
        }else if(o instanceof BasicDBList){
            value = ((BasicDBList)o).toString();
        }
        return value;
    }

    /**
     * 原子修改操做
     * @param model
     * @param where
     * @param update
     * @param returnNew true返回修改後數據,false 返回修改前的數據
     * @param upsert true 修改的記錄不存在則新增一條
     * @return
     */
    @Override
    public JSONObject findAndModify(String model, String where, String update, boolean returnNew, boolean upsert){
        DBCollection dbCollection = db.getCollection(model);
        DBObject query = (DBObject) JSON.parse(where);
        if(query.containsField(Constant.OBJECTID)){
            query.put("_id", new ObjectId(String.valueOf(query.get(Constant.OBJECTID))));
        }
        DBObject updateObject = (DBObject) JSON.parse(update);
        DBObject result = dbCollection.findAndModify(query, null, null, false, updateObject, returnNew, upsert);
        if (result == null) {
            return null;
        }
        return JSONObject.parseObject(result.toString());
    }

    @Override
    public WriteResult insert(String model, DBObject obj) {
        DBCollection dbCollection = db.getCollection(model);
        return dbCollection.insert(obj);
    }

    /**
     * 查詢
     * @param model
     *            集合名
     * @param obj
     *            條件文檔
     * @return DBCursor 遊標
     */
    @Override
    public DBCursor find(String model, DBObject obj) {
        DBCollection dbCollection = db.getCollection(model);
        return dbCollection.find(obj);
    }

    /**
     * 查詢unique
     *
     * @param collection
     *            集合名
     * @param obj
     *            條件文檔
     * @return DBObject 文檔對象
     */
    @Override
    public DBObject findOne(String model, DBObject obj) {
        DBCollection dbCollection = db.getCollection(model);
        return dbCollection.findOne(obj);
    }

    /**
     * 查詢
     *
     * @param model
     *            集合名
     * @param key
     *            查詢條件鍵
     * @param value
     *            查詢條件值
     * @return DBCursor 遊標
     */
    @Override
    public DBCursor find(String model, String key, String value) {
        DBObject query = new BasicDBObject();
        query.put(key, value);
        DBCollection dbCollection = db.getCollection(model);
        return dbCollection.find(query);
    }

    @Override
    public DBCursor find(String model, String key, Object value) {
        DBObject query = new BasicDBObject();
        query.put(key, value);
        DBCollection dbCollection = db.getCollection(model);
        return dbCollection.find(query);
    }

    /**
     * 查詢unique
     *
     * @param model
     *            集合名
     * @param key
     *            查詢條件鍵
     * @param value
     *            查詢條件值
     * @return DBObject 文檔對象
     */
    @Override
    public DBObject findOne(String model, String key, String value) {
        DBObject query = new BasicDBObject();
        query.put(key, value);
        DBCollection dbCollection = db.getCollection(model);
        return dbCollection.findOne(query);
    }

    @Override
    public JSONObject updateByCondition(String model, String json, String condition) {
        DBCollection dbCollection = db.getCollection(model);
        DBObject conditionDBObject = (DBObject) JSON.parse(condition);
        DBObject updateDBObject = (DBObject) JSON.parse(json);
        String date = DateUtil.format(new Date(),DateFormat.getDateTimeInstance());
        updateDBObject.put(Constant.UPDATED_AT, date);
        WriteResult wr = dbCollection.update(conditionDBObject, new BasicDBObject("$set", updateDBObject),false,true,WriteConcern.SAFE);
        if(wr.getN()<=0 || !wr.isUpdateOfExisting()) {
            return null;
        }
        JSONObject returnValue = new JSONObject();
        returnValue.put(Constant.UPDATED_AT, date);
        return returnValue;
    }
}
public class MongoDAOFactory {
    /**
     * 獲取讀寫
     * @return
     */
    public static IMongoDAO getMongoDAO(){
        return MongoDAO.getInstance();
    }
    /**
     * 獲取只讀
     * @return
     */
    public static IMongoDAO getMongoReadDAO(){
        return MongoReadDAO.getInstance();
    }
    /**
     * 獲取只寫
     * @return
     */
    public static IMongoDAO getMongoWriteDAO(){
        return MongoWriterDAO.getInstance();
    }
}
import com.mongodb.ReadPreference;
import com.tssd.school.config.MongoDBConnection;
import com.tssd.school.entity.comm.MongodbConstant;

@Component
public class MongoDAO extends AbstractMongoDAO {

    private static MongoDAO instance = new MongoDAO();

    private MongoDAO(){
        super.dbConnection = new MongoDBConnection();
        super.db = super.dbConnection.getDB(MongodbConstant.mongoDBName);
        /**
         * primary 主節點,默認模式,讀操做只在主節點,若是主節點不可用,報錯或者拋出異常。
         primaryPreferred 首選主節點,大多狀況下讀操做在主節點,若是主節點不可用,如故障轉移,讀操做在從節點。
         secondary 從節點,讀操做只在從節點, 若是從節點不可用,報錯或者拋出異常。
         secondaryPreferred 首選從節點,大多狀況下讀操做在從節點,特殊狀況(如單主節點架構)讀操做在主節點。
         nearest   最鄰近節點,讀操做在最鄰近的成員,多是主節點或者從節點
         */
        super.db.setReadPreference(ReadPreference.nearest());
    }

    public static MongoDAO getInstance(){
        return instance;
    }
}
import com.mongodb.ReadPreference;
import com.tssd.school.config.MongoDBReadConnection;
import com.tssd.school.entity.comm.MongodbConstant;

@Component
public class MongoReadDAO extends AbstractMongoDAO {

    private static MongoReadDAO instance = new MongoReadDAO();

    private MongoReadDAO(){
        super.dbConnection = new MongoDBReadConnection();
        super.db = super.dbConnection.getDB(MongodbConstant.mongoDBName);
        /**
         * primary 主節點,默認模式,讀操做只在主節點,若是主節點不可用,報錯或者拋出異常。
         primaryPreferred 首選主節點,大多狀況下讀操做在主節點,若是主節點不可用,如故障轉移,讀操做在從節點。
         secondary 從節點,讀操做只在從節點, 若是從節點不可用,報錯或者拋出異常。
         secondaryPreferred 首選從節點,大多狀況下讀操做在從節點,特殊狀況(如單主節點架構)讀操做在主節點。
         nearest   最鄰近節點,讀操做在最鄰近的成員,多是主節點或者從節點
         */
        super.db.setReadPreference(ReadPreference.nearest());
    }

    public static MongoReadDAO getInstance(){
        return instance;
    }
}
import com.mongodb.ReadPreference;
import com.tssd.school.config.MongoDBWriteConnection;
import com.tssd.school.entity.comm.MongodbConstant;
import org.springframework.stereotype.Component;

@Component
public class MongoWriterDAO extends AbstractMongoDAO {

    private static MongoWriterDAO instance = new MongoWriterDAO();

    private MongoWriterDAO(){
        super.dbConnection = new MongoDBWriteConnection();
        super.db = super.dbConnection.getDB(MongodbConstant.mongoDBName);
        /**
         * primary 主節點,默認模式,讀操做只在主節點,若是主節點不可用,報錯或者拋出異常。
         primaryPreferred 首選主節點,大多狀況下讀操做在主節點,若是主節點不可用,如故障轉移,讀操做在從節點。
         secondary 從節點,讀操做只在從節點, 若是從節點不可用,報錯或者拋出異常。
         secondaryPreferred 首選從節點,大多狀況下讀操做在從節點,特殊狀況(如單主節點架構)讀操做在主節點。
         nearest   最鄰近節點,讀操做在最鄰近的成員,多是主節點或者從節點
         */
        super.db.setReadPreference(ReadPreference.nearest());
    }

    public static MongoWriterDAO getInstance(){
        return instance;
    }
}

七、編寫controller,測試

@Controller
@RequestMapping(value = "/first")
public class FirstController {

   private Logger logger =Logger.getLogger(String.valueOf(getClass()));
   private static final int pageSize =10;
   
   @Autowired
   MongoWriterDAO mongoWriterDAO;

   @Autowired
   MongoReadDAO mongoReadDAO;

   @RequestMapping(value = "/get",method = RequestMethod.GET)
   @ResponseBody
   public String get(HttpServletRequest request){
       //接下來這些參數相似於京東淘寶購物頁面,有多個篩選條件,交個區間,價格等等。。

       int page = ServletRequestUtils.getIntParameter(request,"page",0);
       String roleName =ServletRequestUtils.getStringParameter(request,"roleName",null);
       //solrName 在一個搜索框中同時能夠搜索暱稱、手機、郵箱、帳號,因此這個代碼用到JSONArray
       String solrName =ServletRequestUtils.getStringParameter(request,"roleName",null);
       String startTime =ServletRequestUtils.getStringParameter(request,"startTime",null);
       String endTime =ServletRequestUtils.getStringParameter(request,"endTime",null);
       logger.debug("roleName"+roleName);
       logger.debug("solrName"+solrName);
       logger.debug("startTime"+startTime);
       logger.debug("endTime"+endTime);
       //query爲查詢條件
       DBObject query =new BasicDBObject();

       JSONObject jsonObject = new JSONObject();
       jsonObject.put("$ne","超級管理員");
       query.put("name",jsonObject);

       //搜索文本中能夠搜索的四個字段的查詢代碼
       if (solrName !=null && !solrName.isEmpty()){
           //搜索框中搜索暱稱
           JSONObject nickJson = new JSONObject();
           DBObject nickDB =new BasicDBObject();
           nickJson.put("$regex",solrName.trim());
           nickDB.put("nickName",nickJson);
           //搜索框中爲手機,這個利用克隆
           DBObject mobileDB =new BasicDBObject();
           mobileDB.put("mobile",nickJson.clone());
           //搜索框中爲郵箱
           DBObject emailDB =new BasicDBObject("email",nickJson.clone());
           //搜索框中爲帳號
           DBObject accountDB =new BasicDBObject("account",nickJson.clone());
           JSONArray $or =new JSONArray();
           $or.add(nickDB);
           $or.add(mobileDB);
           $or.add(accountDB);
           $or.add(emailDB);
           query.put("$or",$or);
       }
        //時間區域內的查詢代碼,若是是價格區間代碼相似
       if (!StringUtils.isEmpty(startTime) || !StringUtils.isEmpty(endTime)){
            JSONObject timeJson =new JSONObject();
            timeJson.put("$gte",startTime);
            timeJson.put("$lte",endTime);
            query.put("createAt",timeJson);
       }
       //查詢返回的字段,{} == 意思是返回集合中全部字段
       String fields ="{}";

       JSONObject orderby =new JSONObject();
       orderby.put("createdAt",-1);//在monggodb中,-1降序,1升序

       //t_role 爲mongodb 的一個集合 至關於MySQL中的一個表
       DBObject dbObject1 = mongoReadDao.find(query.toString(), fields, orderby.toJSONString(), "t_role",page*pageSize,pageSize);

       List<JSONObject> lists = null;
       if (dbObject1 != null && (int)dbObject1.get("count")>0){
           lists = new ArrayList<JSONObject>();
           BasicDBList results =(BasicDBList) dbObject1.get("results");
           JSONObject obj = null;
           for (Object item : results){
               obj = JSONObject.parseObject(item.toString());
               lists.add(obj);
           }
       }
       //下面是分頁
       int counts =Integer.parseInt(dbObject1.get("count").toString());
       int totalPage = 0;
       if(counts<=pageSize){
           totalPage = 1;
       }else{
           totalPage = counts/pageSize;
           if(totalPage*pageSize<counts){
               totalPage+=1;
           }
       }

       JSONObject resultObj = new JSONObject();
       resultObj.put("list", lists);
       resultObj.put("currentPage", page);
       resultObj.put("counts", counts);
       resultObj.put("totalPage", totalPage);

       return resultObj.toJSONString();
   }

   @RequestMapping(value = "/insert",method = RequestMethod.POST)
   @ResponseBody
    public String add(HttpServletRequest request) throws Exception{
       String account =ServletRequestUtils.getStringParameter(request,"account",null);
       String email =ServletRequestUtils.getStringParameter(request,"email",null);
       String mobile =ServletRequestUtils.getStringParameter(request,"mobile",null);
       Date date =new Date();
       SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
       String createAt =simpleDateFormat.format(date);

       logger.debug("account==>"+account);
       logger.debug("email==>"+email);
       logger.debug("mobile==>"+mobile);

       JSONObject jsonObject =new JSONObject();
       jsonObject.put("account",account);
       jsonObject.put("email",email);
       jsonObject.put("mobile",mobile);
       JSONObject result =mongoWriteDao.save("t_admin",jsonObject.toJSONString());
       return result.toJSONString();
   }

    @RequestMapping(value = "/update",method = RequestMethod.POST)
    @ResponseBody
    public String update(HttpServletRequest request)throws Exception{
       String email =ServletRequestUtils.getStringParameter(request,"email","152@qq.com");
       String id = ServletRequestUtils.getStringParameter(request,"id","5a24b0bae6ebae2a742eeacb");
       logger.debug("email==>"+email);
       JSONObject jsonObject =new JSONObject();
       jsonObject.put("email",email);
       JSONObject result =mongoWriteDao.update("t_admin",jsonObject.toJSONString(),id);
       return result.toJSONString();
    }
}

成功!spring

相關文章
相關標籤/搜索