package com.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.bson.Document;
import org.bson.conversions.Bson;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBObject;
import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientOptions.Builder;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
/**
* mongodb工具类
*
* MongoDB工具类 Mongo实例代表了一个数据库连接池,即使在多线程的环境中,一个Mongo实例对我们来说已经足够了<BR>
* 注意Mongo已经实现了连接池,并且是线程安全的。 <BR>
* 设计为单例模式, 因 MongoDB的Java驱动是线程安全的,对于一般的应用,只要一个Mongo实例即可,<BR>
* Mongo有个内置的连接池(默认为10个) 对于有大量写和读的环境中,为了确保在一个Session中使用同一个DB时,<BR>
* DB和DBCollection是绝对线程安全的<BR>
*
* @author lvgb
*
*/
public class MongoDBUtils {
private static Logger log = Logger.getLogger(MongoDBUtils.class);
private static MongoClient mongoClient;
/**
* 目前工具类只支持连接一个数据库
*/
private static MongoDatabase defaultDb;
/**
* 饿汉式单例
*/
private static MongoDBUtils instance = new MongoDBUtils();
private MongoDBUtils() {
}
public static MongoDBUtils getInstance() {
if (mongoClient == null) {
initMongo();
}
return instance;
}
/**
* 初始化mongodb
*/
private static void initMongo() {
log.info("==========mongodb初始化开始==========");
try {
Properties properties = PropertisLoadUtil.getProperties("mongodb.properties");
// 从配置文件中获取属性值
String hostPort = "127.0.0.01:20000;127.0.0.02:20000;127.0.0.03:20000;";//格式:ip:端口号
String dbName = "modb";//mongodb名称
String dbUser = "shanshan";//用户名
String dbPwd = "123";//密码
// 线程队列数
Builder builder = new MongoClientOptions.Builder();
// 连接池设置为300个连接,默认为100
builder.connectionsPerHost(Integer.parseInt(properties.getProperty("mongodb.connectionsPerHost")));
// 连接超时,推荐>3000毫秒
builder.connectTimeout(Integer.parseInt(properties.getProperty("mongodb.connectTimeout")));
//最大等待时间
builder.maxWaitTime(Integer.parseInt(properties.getProperty("mongodb.maxWaitTime")));
// 套接字超时时间,0无限制
builder.socketTimeout(Integer.parseInt(properties.getProperty("mongodb.socketTimeout")));
// 线程队列数
builder.threadsAllowedToBlockForConnectionMultiplier(
Integer.parseInt(properties.getProperty("mongodb.queueCount")));
MongoClientOptions myOptions = builder.build();
MongoCredential credential = MongoCredential.createScramSha1Credential(dbUser, dbName, dbPwd.toCharArray());
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(credential);
//mongoClient = new MongoClient(new ServerAddress(host, port), credentials, myOptions);
//mongs连接方法一
//mongoClient = new MongoClient(new MongoClientURI("mongodb://127.0.0.01:20000;127.0.0.02:20000;127.0.0.03:20000"));
List<ServerAddress> list = new ArrayList<ServerAddress>();
String[] hostPortArray = hostPort.split(";");
for (String hostPorts : hostPortArray) {
String[] arr = hostPorts.split(":");
list.add(new ServerAddress(arr[0].toString(), Integer.parseInt(arr[1])));
}
//mongs连接方法二
mongoClient = new MongoClient(list, credentials, myOptions);
log.info("==========开始连接默认DB库[" + dbName + "]==========");
defaultDb = mongoClient.getDatabase(dbName);
log.info("==========成功连接默认DB库[" + dbName + "]==========");
} catch (Exception e) {
e.printStackTrace();
log.error("初始化mongodb失败", e);
}
log.info("==========mongodb初始化结束==========");
}
/**
* 获取collection对象(如果没有,会自动创建) - 指定Collection
*
* @param collName
* @return
*/
public MongoCollection<Document> getCollection(String collName) {
if (StringUtils.isEmpty(collName)) {
return null;
}
return defaultDb.getCollection(collName);
}
/**
* 单笔插入
*
* @param collName
* @param json
*/
public void insertOne(String collName, String json) {
getCollection(collName).insertOne(Document.parse(json));
}
/**
* 多笔插入
*
* @param collName
* @param json
*/
public void insertMany(String collName, String json) {
List<Document> list = JSON.parseArray(json, Document.class);
getCollection(collName).insertMany(list);
}
/**
* 精确条件查询(多条件AND查询)
*
* @param collName
* @param json:{"name":"tx",
* "age":"99"} JSON数组字符串
* @return
*/
public String findExact(String collName, String json) {
BasicDBObject query = BasicDBObject.parse(json);
final List<Document> resultList = new ArrayList<Document>();
FindIterable<Document> docs = getCollection(collName).find(query);
docs.forEach(new Block<Document>() {
public void apply(Document document) {
resultList.add(document);
}
});
return JSON.toJSONString(resultList);
}
/**
* 文档查询(具体条件使用可以参考MongoTest)
*
* @param collName
* @param bson JSON数组字符串
* @return
*/
public String findExact(String collName, Bson bson) {
final List<Document> resultList = new ArrayList<Document>();
FindIterable<Document> docs = getCollection(collName).find(bson);
docs.forEach(new Block<Document>() {
public void apply(Document document) {
resultList.add(document);
}
});
return JSON.toJSONString(resultList);
}
/**
* 获取集合中总文档数
*
* @param collName
* @return
*/
public int getCount(String collName) {
int count = (int) getCollection(collName).count();
return count;
}
/**
* 获取集合中满足条件的文档数
*
* @param collName
* @param json
* @return
*/
public int getCount(String collName, String json) {
BasicDBObject query = BasicDBObject.parse(json);
int count = (int) getCollection(collName).count(query);
return count;
}
/**
* 创建普通索引
*
* @param collName
* 集合名称
* @param idxFields
* 需要创建普通索引的字段名称列表
*/
public void createNormalIndex(String collName, String... idxFields) {
MongoCollection<Document> coll = getCollection(collName);
for (String idxField : idxFields) {
coll.createIndex(new Document(idxField, 1));
}
}
/**
* 创建唯一索引
*
* @param collName
* 集合名称
* @param ukFields
* 需要创建唯一索引的字段名称列表
*/
public void createUKIndex(String collName, String... ukFields) {
MongoCollection<Document> coll = getCollection(collName);
for (String ukField : ukFields) {
coll.createIndex(new Document(ukField, 1), new IndexOptions().unique(true));
}
}
/**
* 精确条件查询,只返回一条数据
* map 选择性的显示字段 0:不显示 ,1:显示 例:{"a":"a","b":"b"} 要显示b 则传入参数 key:b value:1
* json 查询条件
* @param collName 集合名称
* @param map key为要查询的参数,value为要查询的参数值
* @return
*/
public String findOneExact(String collName, Map<String,Object> map ,JSONObject json) {
if(map == null){
return "";
}
BasicDBObject query = new BasicDBObject();
for (Map.Entry<String,Object> entry : map.entrySet()) {
query.append(entry.getKey(), entry.getValue());
}
FindIterable<Document> projection = getCollection(collName).find(BasicDBObject.parse(json.toString())).projection(query);
final List<Document> resultList = new ArrayList<Document>();
projection.forEach(new Block<Document>() {
public void apply(Document document) {
resultList.add(document);
}
});
return JSON.toJSONString(resultList);
}
public void findOnessss(String collName){
//选择性的显示字段 0:不显示 ,1:显示
BasicDBObject exclude = new BasicDBObject();
exclude.append("_id", 1);
Document doc = getCollection(collName).find().projection(exclude).first();
System.out.println(JSON.toJSONString(doc));
}
private void remove(String collName,String json) {
BasicDBObject query = BasicDBObject.parse(json);
MongoCollection<Document> collection = getInstance().getCollection(collName);
DeleteResult deleteResult = collection.deleteOne(query);
long deletedCount = deleteResult.getDeletedCount();
System.out.println(deletedCount);
}
/**
* 修改数据
* @param collName (集合名称)
* @param queryFiled (查询条件字段名)
* @param queryCondition (查询条件内容)
* @param updateFiled (修改字段名)
* @param updateContent (修改内容)
* @return
*/
public boolean update(String collName,String queryFiled,String queryCondition,String updateFiled,Object updateContent){
MongoCollection<Document> collection = getInstance().getCollection(collName);
UpdateResult updateMany = collection.updateMany(Filters.eq(queryFiled, queryCondition), new Document("$set",new Document(updateFiled,updateContent)));
if(updateMany.getModifiedCount() > 0){
return true;
}
return false;
}
/**
* 条件查询(单条记录查询)
*
* @param collName
* @param json
* JSON数组字符串
* @return
*/
public String findOne(String collName, String json) {
BasicDBObject query = BasicDBObject.parse(json);
return JSON.toJSONString(getCollection(collName).find(query).first());
}
}