說起Java操作資料庫自然會想到Sun的知名品牌JDBC,對於MongoDB這樣的NoSQL資料庫,暫時沒有像JDBC這樣的標準。
這篇文章中對目前的形勢做了分析和憧憬http://www.csdn.net/article/2012-06-21/2806842
回到正題記錄下熟悉MongoDB為Java語言提供的操作介面mongo-java-driver.jar
1.基本的根基不變,串連資料庫
2.基本的資料庫操作不變,CRUD
3.變化的是提供的介面,實作類別名,操作對象大不相同
4.變化的是沒有標準的Java操作MongoDB的標準API
MongoDB提供的Java操作API可以說是對Mongo資料庫命令的Java翻譯,熟悉Mongo命令,熟悉Java操作資料庫的基本思路,很容易掌握基本操作。
資料庫連接
package com.im;public final class SystemConstant { public static final class Configure { public static final String HOST = "127.0.0.1"; public static final int PORT = 27017; public static final String USERNAME = ""; public static final String PASSWORD = ""; public static final String DATABASE = "im"; }}
package com.im;import java.net.UnknownHostException;import com.mongodb.Mongo;import com.mongodb.MongoException;public class MongoFactory { private static MongoFactory mongoFactory; private MongoFactory() { } public static MongoFactory getInstance() { if (mongoFactory == null) { mongoFactory = new MongoFactory(); } return mongoFactory; } public Mongo getMongo() { Mongo mongo = null; try { mongo = new Mongo(SystemConstant.Configure.HOST, SystemConstant.Configure.PORT); } catch (UnknownHostException e) { e.printStackTrace(); } catch (MongoException e) { e.printStackTrace(); } return mongo; }}
資料庫連結少不了的主機名稱,連接埠號碼,資料庫名稱。上面代碼中的Mongo對象就相當與Connection對象。
資料庫的操作
下面的每個方法代表一個方面的測試
測試類別初始化方法:
private static BaseDao dao; @BeforeClass public static void start() { dao = new BaseDao("users","uf"); }
關於BaseDao是對Mongo操作資料庫的基本常用的方法做了封裝的一個DAO對象,代碼會在本文末尾附上。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131229/2215252E5-0.gif" alt="j_0001.gif" /> 插入:
// 添加一條記錄 public void test1() { BasicDBObject jo = new BasicDBObject(); jo.put("_id", "00001"); jo.put("name", "Tomcat"); jo.put("age", 22); jo.put("interest", new String[] { "swimming", "Taiji", "football" }); int actual = dao.insert(jo); System.out.println(actual); Assert.assertEquals(1, actual); }
// 添加多條記錄 public void test2() { int actual = 0; int size = 0; for (int i = 2; i < 11; i++) { BasicDBObject jo = new BasicDBObject(); jo.put("_id", "0000" + i); jo.put("name", "Tomcat_" + i); jo.put("age", i * 2); jo.put("interest", new String[] { "swimming", "Taiji" }); actual += dao.insert(jo); size++; } Assert.assertEquals(size, actual); }
BasicDBObject對象是Mongo的BSONObject的基本實作類別,而BSONObject對象正是Key-Value的形式的Map儲存到資料庫中。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131229/2215252E5-0.gif" alt="j_0001.gif" /> 基本的查詢主鍵查詢,查詢集合,條件查詢)
// 查詢指定編號的記錄 public void test3() { BasicDBObject query = new BasicDBObject(); query.put("_id", "00001"); List<DBObject> dboList = dao.query(query); System.out.println(dboList.get(0).toString()); Assert.assertEquals(1, dboList.size()); } // 模糊查詢,統計記錄結果數量 public void test4() { BasicDBObject query = new BasicDBObject(); query.put("interest", new String[] { "swimming", "Taiji" }); long count = dao.getCount(query); Assert.assertEquals(9, count); } // 模組查詢,查詢結果集合 public void test5() { BasicDBObject query = new BasicDBObject(); query.put("interest", new String[] { "swimming", "Taiji" }); List<DBObject> dboList = dao.query(query); for (DBObject jo : dboList) { System.out.println(jo.toString()); } Assert.assertEquals(9, dboList.size()); }
下面是插入資料後的資料庫的資料情況,圖中資料是各種測試後的資料,不完全對於每個方法的操作後資料庫情況。
650) this.width=650;" src="http://img1.51cto.com/attachment/201312/213445907.png" title="mongo-test-data.png" alt="213445907.png" />
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131229/2215252E5-0.gif" alt="j_0001.gif" />更新操作
Mongo更新操作要準備兩個BasicDBObject對象,一個是要更新的對象,另一個是更新後的對象。
// 更新指定記錄的資訊 public void test6() { BasicDBObject query = new BasicDBObject(); query.put("_id", "00001"); BasicDBObject jo = new BasicDBObject(); jo.put("_id", "00001"); jo.put("name", "Jackson"); jo.put("interest", new String[] { "Song", "Taiji", "Running" }); jo.put("firends", new BasicDBObject[] { (BasicDBObject) dao.query( new BasicDBObject("_id", "00002")).get(0), (BasicDBObject) dao.query( new BasicDBObject("_id", "00002")).get(0) }); int actual = dao.update(query, jo); Assert.assertEquals(1, actual); }
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131229/2215252E5-0.gif" alt="j_0001.gif" />刪除操作
// 刪除指定記錄 public void test7() { BasicDBObject query = new BasicDBObject(); query.put("_id", "000010"); dao.delete(query); List<DBObject> dboList = dao.query(query); Assert.assertEquals(0, dboList.size()); }
Mongo刪除比較容易,指定一個BasicDBObject作為匹配條件,將刪除匹配的所有記錄文檔對象)。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131229/2215252E5-0.gif" alt="j_0001.gif" />多條件查詢
在資料庫的CRUD操作中查詢操作更加多樣化和頻繁,Mongo的Java驅動程式中對Mongo資料自身的各種條件查詢做了封裝,提供一個QueryBuilder的類,將Mongo中的查詢操作對象化,用此類來建立出要查詢的條件,然後在進行基本查詢。
// 指定多條件的查詢 public void test8() { BasicDBObject query = new BasicDBObject(); BasicDBObject condition = new BasicDBObject(); condition.put(QueryOperators.GTE, 10); query.put("age", condition); List<DBObject> dboList = dao.query(query); for (DBObject jo : dboList) { System.out.println(jo.toString()); } Assert.assertEquals(5, dboList.size()); } public void test9() { BasicDBObject query = new BasicDBObject(); BasicDBObject condition = new BasicDBObject(); condition.put(QueryOperators.GTE, 10); condition.put(QueryOperators.LTE, 16); query.put("age", condition); List<DBObject> dboList = dao.query(query); for (DBObject jo : dboList) { System.out.println(jo.toString()); } Assert.assertEquals(4, dboList.size()); } public void test10() { QueryBuilder qb = new QueryBuilder(); BasicDBObject query = (BasicDBObject) qb.and("age") .greaterThanEquals(10).lessThanEquals(14).and("interest") .in(new String[] { "swimming", "Taiji","football" }).get(); List<DBObject> dboList = dao.query(query); for (DBObject jo : dboList) { System.out.println(jo.toString()); } }
在test8方法中的查詢條件是通過建立BasicDBObject來實現,如果條件更多這樣操作會寫很多代碼而且不易將各個條件關聯起來,後面的test9和test10方法則使用QueryBuilder來實現。
上述對Mongo資料的操作側重於準備查詢條件,插入對象,刪除條件,更新條件等,主要原因是Mongo資料庫操作再不是我們以前SQL那樣具有高度標準化的操作,相反更多的注意力集中到如何在程式語言中翻譯Mongo命令操作,原因很簡單沒有統一的標準實現。
至於資料庫的基本操作Mongo的Java驅動自然要提供最基本的操作功能。
附上BaseDao代碼:
package com.im.dao;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import com.im.MongoFactory;import com.im.SystemConstant;import com.mongodb.BasicDBObject;import com.mongodb.DB;import com.mongodb.DBCollection;import com.mongodb.DBCursor;import com.mongodb.DBObject;import com.mongodb.WriteResult;import com.mongodb.gridfs.GridFS;import com.mongodb.gridfs.GridFSDBFile;import com.mongodb.gridfs.GridFSInputFile;public class BaseDao { /** * 資料庫物件 */ private DB db; /** * 資料庫文檔對象相當於RDBMS中的表) */ private DBCollection dbCollection; /** * 資料庫檔案存在集合 */ private GridFS fs; public BaseDao(String docBucket, String fileBucket) { db = MongoFactory.getInstance().getMongo() .getDB(SystemConstant.Configure.DATABASE); this.dbCollection = db.getCollection(docBucket); if (fileBucket.endsWith("") || fileBucket == null) { fileBucket = "fs"; } this.setFs(new GridFS(db, fileBucket)); } /** * 插入文檔 * * @param jo * @return */ public int insert(DBObject jo) { WriteResult wr = dbCollection.save(jo); return wr.getN(); } /** * 刪除文檔 * * @param jo * 刪除的匹配文檔 */ public void delete(DBObject jo) { dbCollection.remove(jo); } /** * 更新文檔 * * @param query * 指定更新的文檔 * @param jo * 更新後的文檔 * @return */ public int update(DBObject query, DBObject jo) { WriteResult wr = dbCollection.update(query, jo); return wr.getN(); } /** * 查詢文檔 * * @param query * 查詢的匹配文檔 * @return */ public List<DBObject> query(DBObject query) { DBCursor dbc = dbCollection.find(query); List<DBObject> joList = new ArrayList<DBObject>(); while (dbc.hasNext()) { DBObject jo = dbc.next(); joList.add(jo); } return joList; } /** * 隱藏檔 * * @param file */ public void saveFile(File file) { try { GridFSInputFile gif = fs.createFile(file); gif.save(); } catch (IOException e) { e.printStackTrace(); } } /** * 儲存輸入資料流,並指定的一些描述資訊 * * @param in * @param id * @param filename * 檔案名稱 * @param contentType * 檔案內容類型 */ public void saveFile(InputStream in, Object id, String filename, Object contentType) { DBObject query = (DBObject) new BasicDBObject("_id", id); GridFSDBFile gff = fs.findOne(query); if (gff == null) { GridFSInputFile gif = fs.createFile(in); gif.setFilename(filename); gif.put("_id", id); gif.put("contentType", contentType); gif.save(); } } /** * 查詢指定ID的檔案 * * @param id * @return */ public GridFSDBFile queryFile(Object id) { DBObject query = (DBObject) new BasicDBObject("_id", id); return fs.findOne(query); } /** * 查詢指定檔案名稱的檔案 * * @param filename * @return */ public GridFSDBFile queryFile(String filename) { DBObject query = (DBObject) new BasicDBObject("filename", filename); return fs.findOne(query); } /** * 查詢檔案 * * @param query * 查詢的匹配檔案 * @return */ public List<GridFSDBFile> queryFile(DBObject query) { return fs.find(query); } /** * 統計查詢結果數 * * @param query * 查詢匹配的文檔 * @return */ public long getCount(DBObject query) { return dbCollection.getCount(query); } public GridFS getFs() { return fs; } public void setFs(GridFS fs) { this.fs = fs; } public DBCollection getDbCollection() { return dbCollection; } public void setDbCollection(DBCollection dbCollection) { this.dbCollection = dbCollection; }}
本文出自 “野馬紅塵” 部落格,謝絕轉載!