MongoDB學習(六) Java原生使用MongoDB
阿新 • • 發佈:2019-01-07
額外,可以參考用一個第三方框架:BuguMongo,或者後面的兩篇文章中的orm.但是這個bugumongo是2014年的框架,後來沒有更新了
官方文件和原始碼均建議在Java中使用MongoClient來操作MongoDB,而且,在不久的將來,會廢棄Mongo類。
這裡是簡單的一個操作封裝
DAO介面
import java.util.List; import org.bson.Document; import org.bson.conversions.Bson; public interface BaseMongoDao { boolean insertOne(String paramString, Document paramDocument); void insertMany(String paramString, List<Document> paramList); void delete(String paramString, Document paramDocument); void deleteAll(String paramString); List<Document> queryByCondition(String paramString, MongoCondition paramMongoCondition); Document findByCondition(String paramString, MongoCondition paramMongoCondition); Document findByCondition(String paramString, Bson paramBson); Document findByConditionSkip(String paramString, MongoCondition paramMongoCondition, int paramInt); Document findByConditionSkip(String paramString, Bson paramBson, int paramInt); int count(String paramString, MongoCondition paramMongoCondition); boolean update(String paramString, Document paramDocument1, Document paramDocument2); Document findAndUpdate(String paramString, Document paramDocument1, Document paramDocument2); }
DAO實現類
Formulaimport java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.bson.Document; import org.bson.conversions.Bson; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; import org.springframework.util.ObjectUtils; import com.mongodb.BasicDBObject; import com.mongodb.Bytes; import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import com.mongodb.client.result.UpdateResult; @Repository public class BaseMongoDaoImpl implements InitializingBean, BaseMongoDao { private static Logger logger = Logger.getLogger(BaseMongoDaoImpl.class); // mongo 客戶端 private static MongoClient mongoClient; private static MongoDatabase mongoDB; @Value("${mongo.connect}") private String connect; @Value("${mongo.username}") private String username; @Value("${mongo.password}") private String password; @Value("${mongo.database}") private String database; private int poolSize; @Override public boolean insertOne(String collectionName, Document document) { try { mongoDB.getCollection(collectionName).insertOne(document); return true; } catch (Exception e) { logger.error( "collectionName:" + collectionName + "\n document:" + document.toJson() + " \n" + e.getMessage()); } return false; } @Override public void insertMany(String collectionName, List<Document> documents) { try { mongoDB.getCollection(collectionName).insertMany(documents); } catch (Exception e) { logger.error("insertMany error . collectionName:" + collectionName + " \n" + e.getMessage()); } } @Override public void delete(String collectionName, Document filter) { try { mongoDB.getCollection(collectionName).deleteMany(filter); } catch (Exception e) { logger.error("delete error. collectionName:" + collectionName + "\n document:" + filter.toJson() + " \n" + e.getMessage()); } } @Override public void deleteAll(String collectionName) { try { Document document = new Document(); mongoDB.getCollection(collectionName).deleteMany(document); } catch (Exception e) { logger.error("delete error. collectionName:" + collectionName + " \n" + e.getMessage()); } } @Override public List<Document> queryByCondition(String collectionName, MongoCondition condition) { List<Document> objects = null; try { if (condition == null) { condition = new MongoCondition(); } Collection<QueryItem> items = condition.getQueryItems(); // 生成查詢條件 Bson bson = createBsonByQueryItemList(items); // 按指定地段排序 BasicDBObject sort = new BasicDBObject(); if (!(StringUtils.isEmpty(condition.getOrderbyProperty()))) { if (condition.isDesc()) { sort.put(condition.getOrderbyProperty(), -1); } else { sort.put(condition.getOrderbyProperty(), 1); } } else { sort.put("_id", 1); } // 分頁 int currentPage = condition.getCurrentPage(); int pageSize = condition.getPageSize(); if (pageSize < 0) { return null; } FindIterable<Document> iterable = null; if (bson == null) { iterable = mongoDB.getCollection(collectionName).find().sort(sort).skip((currentPage - 1) * pageSize) .limit(pageSize); } else { iterable = mongoDB.getCollection(collectionName).find(bson).sort(sort) .skip((currentPage - 1) * pageSize).limit(pageSize); } MongoCursor<Document> cursor = iterable.iterator(); objects = new ArrayList<Document>(); while (cursor.hasNext()) { Document document = cursor.next(); objects.add(document); } } catch (Exception e) { logger.error("queryByCondition error. collectionName:" + collectionName + " \n" + e.getMessage()); } return objects; } @Override public Document findByCondition(String collectionName, MongoCondition condition) { Document object = null; try { if (condition == null) { condition = new MongoCondition(); } Collection items = condition.getQueryItems(); Bson bson = createBsonByQueryItemList(items); if (bson == null) object = (Document) mongoDB.getCollection(collectionName).find().first(); else object = (Document) mongoDB.getCollection(collectionName).find(bson).first(); } catch (Exception e) { logger.error("findByCondition error. collectionName:" + collectionName + " \n" + e.getMessage()); } return object; } @Override public Document findByCondition(String collectionName, Bson bson) { Document object = null; try { if (bson == null) object = (Document) mongoDB.getCollection(collectionName).find().first(); else object = (Document) mongoDB.getCollection(collectionName).find(bson).first(); } catch (Exception e) { logger.error("findByCondition error. collectionName:" + collectionName + " \n" + e.getMessage()); } return object; } @Override public Document findByConditionSkip(String collectionName, MongoCondition condition, int skip) { Document object = null; try { if (condition == null) { condition = new MongoCondition(); } Collection<QueryItem> items = condition.getQueryItems(); Bson bson = createBsonByQueryItemList(items); if (bson == null) object = (Document) mongoDB.getCollection(collectionName).find().skip(skip).first(); else object = (Document) mongoDB.getCollection(collectionName).find(bson).skip(skip).first(); } catch (Exception e) { logger.error("findByCondition error. collectionName:" + collectionName + " \n" + e.getMessage()); } return object; } @Override public Document findByConditionSkip(String collectionName, Bson bson, int skip) { Document object = null; try { if (bson == null) object = (Document) mongoDB.getCollection(collectionName).find().skip(skip).first(); else object = (Document) mongoDB.getCollection(collectionName).find(bson).skip(skip).first(); } catch (Exception e) { logger.error("findByCondition error. collectionName:" + collectionName + " \n" + e.getMessage()); } return object; } @Override public int count(String collectionName, MongoCondition condition) { int count = 0; try { if (condition == null) { condition = new MongoCondition(); } Collection<QueryItem> items = condition.getQueryItems(); Bson bson = createBsonByQueryItemList(items); if (bson == null) count = (int) mongoDB.getCollection(collectionName).count(); else count = (int) mongoDB.getCollection(collectionName).count(bson); } catch (Exception e) { logger.error("count error. collectionName:" + collectionName + " \n" + e.getMessage()); } return count; } @Override public boolean update(String collectionName, Document filter, Document update) { try { UpdateResult result = mongoDB.getCollection(collectionName).updateMany(filter, new Document("$set", update)); return (result.getModifiedCount() > 0L); } catch (Exception e) { logger.error("update error. collectionName:" + collectionName + "\n filter:" + filter.toJson() + "\n update:" + update.toJson() + " \n" + e.getMessage()); } return false; } @Override public Document findAndUpdate(String collectionName, Document filter, Document update) { Document document = null; try { document = (Document) mongoDB.getCollection(collectionName).findOneAndUpdate(filter, update); } catch (Exception e) { logger.error("findAndUpdate error. collectionName:" + collectionName + "\n filter:" + filter.toJson() + "\n update:" + update.toJson() + " \n" + e.getMessage()); } return document; } @Override public void afterPropertiesSet() { try { if (mongoClient == null) { mongoClient = getMongoClient(); mongoDB = mongoClient.getDatabase(database); logger.info("MongoDB connect to : " + connect + ":" + mongoDB.getName()); } } catch (Exception e) { logger.error("get database " + database + " error .", e); } } //建立資料庫連線 //連線池大小,MongoDB預設連線池10個連線,且執行緒安全,增刪改查自動建立連線,用完後自動釋放連線 private MongoClient getMongoClient() { poolSize = ((poolSize <= 0) ? 10 : poolSize); try { if (StringUtils.isNotEmpty(connect)) { MongoClientOptions.Builder build = new MongoClientOptions.Builder(); build.connectionsPerHost(poolSize); String[] hosts = connect.split(","); List<ServerAddress> addressList = new ArrayList<ServerAddress>(); for (String h : hosts) { String[] path = h.split(":"); if (path.length > 1) { addressList.add(new ServerAddress(path[0], Integer.parseInt(path[1]))); } else { logger.error("invalidate config for mongodb :" + h); return null; } } if (addressList.size() == 0) { logger.error("invalidate mongo config , nothing to do : " + this.connect); return null; } if (!(StringUtils.isEmpty(username))) {// 有密碼配置 List<MongoCredential> mongoCredentialList = new ArrayList<MongoCredential>(); mongoCredentialList.add(MongoCredential.createCredential(username, database, password.toCharArray())); mongoClient = new MongoClient(addressList, mongoCredentialList); } else {//無密碼 mongoClient = new MongoClient(addressList); } mongoClient.addOption(Bytes.QUERYOPTION_SLAVEOK); } } catch (Exception e) { logger.error("getMongoClient error ", e); } return mongoClient; } //建立並格式化查詢條件 private Bson createBsonByQueryItemList(Collection<QueryItem> items) { Bson bson = null; try { List listC = new ArrayList(); if ((null != items) && (!(items.isEmpty()))) { for (QueryItem item : items) { if (null == item) { continue; } if (item.getFormula() == Formula.EQ) { listC.add(Filters.eq(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.LIKE) { listC.add(Filters.regex(item.getParam(), Pattern.compile("^.*" + item.getValue() + ".*$", 2))); } else if (item.getFormula() == Formula.IN) { if (ObjectUtils.isArray(item.getValue())) { Object[] values = (Object[]) (Object[]) item.getValue(); listC.add(Filters.in(item.getParam(), values)); } else if (item.getValue() instanceof List) { listC.add(Filters.in(item.getParam(), ((List) item.getValue()).toArray())); } else { listC.add(Filters.in(item.getParam(), new Object[] { item.getValue() })); } } else if (item.getFormula() == Formula.GE) { listC.add(Filters.gte(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.LE) { listC.add(Filters.lte(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.GT) { listC.add(Filters.gt(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.LT) { listC.add(Filters.lt(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.NE) { listC.add(Filters.ne(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.IS) { listC.add(Filters.eq(item.getParam(), item.getValue())); } else if (item.getFormula() == Formula.BETWEEN) { Object params = item.getValue(); if ((params != null) && (ObjectUtils.isArray(params))) { Object[] array = (Object[]) (Object[]) params; listC.add(Filters.gte(item.getParam(), array[0])); listC.add(Filters.lte(item.getParam(), array[1])); } } } if (listC.size() > 0) bson = Filters.and(listC); } } catch (Exception localException) { } return bson; } public String getConnect() { return this.connect; } public void setConnect(String connect) { this.connect = connect; } public String getUser() { return this.username; } public void setUser(String username) { this.username = username; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public String getDatabase() { return this.database; } public void setDatabase(String database) { this.database = database; } public int getPoolSize() { return this.poolSize; } public void setPoolSize(int poolSize) { this.poolSize = poolSize; } }
public enum Formula
{
EQ, //==
NE, //<>
LT, //<
GT, //>
LE, //<=
GE, //>=
LIKE, //like
IN, //in
BETWEEN, //between a and b
IS, //is a value null or not null
OR //or
}
MongoCondition.java
import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; public class MongoCondition implements Serializable { private static final long serialVersionUID = -5427500692306190991L; private Collection<QueryItem> queryItems = new LinkedHashSet<QueryItem>(); private String orderbyProperty; private boolean desc = true; //預設為降序 private int currentPage = 1; private int pageSize = 100; private String hint; //查詢結果需要排除的欄位 excludeFields和includeFields互斥,只能二選一 private Collection<String> excludeFields = new LinkedHashSet<String>(); private Collection<String> includeFields = new LinkedHashSet<String>(); public Collection<QueryItem> getQueryItems() { return this.queryItems; } public int getCurrentPage() { return this.currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getPageSize() { return this.pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public String getOrderbyProperty() { return this.orderbyProperty; } public boolean isDesc() { return this.desc; } public void setDesc(boolean desc) { this.desc = desc; } public void setOrderbyProperty(String orderbyProperty) { this.orderbyProperty = orderbyProperty; } public MongoCondition setOrderby(String orderProperty, boolean isAsc) { this.orderbyProperty = orderProperty; setDesc(!(isAsc)); return this; } public MongoCondition addItem(QueryItem item) { this.queryItems.add(item); return this; } public MongoCondition addItem(String param, Object value, Formula formula) { this.queryItems.add(new QueryItem(param, value, formula)); return this; } public MongoCondition addAll(Collection<QueryItem> items) { this.queryItems.addAll(items); return this; } public Collection<String> getExcludeFields() { return this.excludeFields; } public void addExcludeFields(String excludeField) { this.excludeFields.add(excludeField); } public void addIncludeFields(String includeField) { this.includeFields.add(includeField); } public Collection<String> getIncludeFields() { return this.includeFields; } public Map<String, Integer> getFields() { Map<String, Integer> includeMap = new HashMap(); Map<String, Integer> excludeMap = new HashMap(); // 限定排除 if (this.excludeFields.size() > 0) for (String tmp : excludeFields) { excludeMap.put(tmp, 0); } if (this.includeFields.size() > 0) { for (String tmp : includeFields) { includeMap.put(tmp, 1); } } if (this.includeFields.size() > 0) return includeMap; if (this.excludeFields.size() > 0) { return excludeMap; } return null; } public String getHint() { return this.hint; } public void setHint(String hint) { this.hint = hint; } public String toString() { return "MongoCondition [queryItems=" + this.queryItems + ", orderbyProperty=" + this.orderbyProperty + ", desc=" + this.desc + ", currentPage=" + this.currentPage + ", pageSize=" + this.pageSize + ", hint=" + this.hint + ", excludeFields=" + this.excludeFields + ", includeFields=" + this.includeFields + "]"; } }
QueryItem.java
import java.io.Serializable;
public class QueryItem implements Serializable {
private static final long serialVersionUID = 3207267704417597387L;
private String param;
private Object value;
private Object start;
private Object end;
private Formula formula;
private boolean ignoreCase = false;
public QueryItem() {
}
public QueryItem(String param, Object value, Formula formula) {
this.param = param;
this.value = value;
this.formula = formula;
}
public String getParam() {
return this.param;
}
public void setParam(String param) {
this.param = param;
}
public Object getValue() {
return this.value;
}
public void setValue(Object value) {
this.value = value;
}
public Object getStart() {
return this.start;
}
public void setStart(Object start) {
this.start = start;
}
public Object getEnd() {
return this.end;
}
public void setEnd(Object end) {
this.end = end;
}
public Formula getFormula() {
return this.formula;
}
public void setFormula(Formula formula) {
this.formula = formula;
}
public boolean isIgnoreCase() {
return this.ignoreCase;
}
public void setIgnoreCase(boolean ignoreCase) {
this.ignoreCase = ignoreCase;
}
public String toString() {
return "{param:" + this.param + ",formula:" + this.formula + ",value:" + this.value + "}";
}
public int hashCode() {
int prime = 31;
int result = 1;
result = 31 * result + ((this.end == null) ? 0 : this.end.hashCode());
result = 31 * result + ((this.formula == null) ? 0 : this.formula.hashCode());
result = 31 * result + ((this.ignoreCase) ? 1231 : 1237);
result = 31 * result + ((this.param == null) ? 0 : this.param.hashCode());
result = 31 * result + ((this.start == null) ? 0 : this.start.hashCode());
result = 31 * result + ((this.value == null) ? 0 : this.value.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (super.getClass() != obj.getClass())
return false;
QueryItem other = (QueryItem) obj;
if (this.end == null)
if (other.end != null)
return false;
else if (!(this.end.equals(other.end)))
return false;
if (this.formula != other.formula)
return false;
if (this.ignoreCase != other.ignoreCase)
return false;
if (this.param == null)
if (other.param != null)
return false;
else if (!(this.param.equals(other.param)))
return false;
if (this.start == null)
if (other.start != null)
return false;
else if (!(this.start.equals(other.start)))
return false;
if (this.value == null)
if (other.value != null)
return false;
else if (!(this.value.equals(other.value)))
return false;
return true;
}
}
測試用例:
import static org.junit.Assert.*;
import org.bson.Document;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.wqc.mongo.BaseMongoDao;
import com.wqc.mongo.Formula;
import com.wqc.mongo.MongoCondition;
/**
* @ClassName: JavaMongo
* @Description: TODO(這裡用一句話描述這個類的作用)
* @author:
* @date: 2018年5月30日 上午10:11:39
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class JavaMongoTest {
@Autowired
public BaseMongoDao baseMongoDao;
@Test
public void test_01() {
Document document = new Document();
document.append("name", "張三");
document.append("age", 18);
document.append("mobile", "13866666666");
baseMongoDao.insertOne("student", document);
}
@Test
public void test_02() {
MongoCondition mongoCondition = new MongoCondition();
mongoCondition.addItem("name","張三",Formula.EQ);
mongoCondition.addItem("age","18",Formula.EQ);
mongoCondition.addItem("mobile","16888888888", Formula.EQ);
Document document = baseMongoDao.findByCondition("student", mongoCondition);
if (document != null) {
System.out.println(document.toJson());
}
}
}
mongo.properties
mongo.database=mongodb
mongo.connect=127.0.0.1:27017
mongo.username=
mongo.password=