Chinaunix
標(biāo)題: MongoDB Java Driver 源碼分析(3):com.mongodb.DBCollection [打印本頁(yè)]
作者: 凝望長(zhǎng)空 時(shí)間: 2011-11-13 17:24
標(biāo)題: MongoDB Java Driver 源碼分析(3):com.mongodb.DBCollection
MongoDB Java Driver 源碼分析(3):com.mongodb.DBCollection
DBCollection 是表示數(shù)據(jù)集合的抽象類(lèi),它的實(shí)現(xiàn)可以簡(jiǎn)單地分為兩類(lèi):
一類(lèi)是抽象方法,由子類(lèi)(DBApiLayer.MyCollection)實(shí)現(xiàn);
另一類(lèi)委托給類(lèi)型為 "DB" 的屬性 _db,_db 實(shí)際上是 DBApiLayer 類(lèi)的實(shí)例(DBApiLayer 繼承抽象類(lèi) DB);
因此,DBCollection 類(lèi)是實(shí)現(xiàn)細(xì)節(jié)與 DBApiLayer 關(guān)系密切。
DBApiLyer 的實(shí)現(xiàn)細(xì)節(jié)我們將在后續(xù)文章中進(jìn)行詳細(xì)的描述,本文主要探討兩者之間的聯(lián)系。
由子類(lèi)實(shí)現(xiàn)的方法
以下方法是由子類(lèi)實(shí)現(xiàn)的,這些將在介紹 DBApiLayer 時(shí)再進(jìn)行詳細(xì)說(shuō)明:
Java代碼- 1.// 插入記錄
- 2.public abstract WriteResult insert(DBObject[] arr , WriteConcern concern )
- 3.
- 4.// 更新記錄
- 5.public abstract WriteResult update( DBObject q , DBObject o , boolean upsert , boolean multi , WriteConcern concern )
- 6.
- 7.// 保存數(shù)據(jù)之前附加額外屬性
- 8.protected abstract void doapply( DBObject o )
- 9.
- 10.// 刪除記錄
- 11.public abstract WriteResult remove( DBObject o , WriteConcern concern )
- 12.
- 13.// 查詢(xún)記錄
- 14.abstract Iterator<DBObject> __find( DBObject ref , DBObject fields , int numToSkip , int batchSize , int limit, int options )
- 15.
- 16.// 創(chuàng)建索引
- 17.public abstract void createIndex( DBObject keys , DBObject options )
- // 插入記錄
- public abstract WriteResult insert(DBObject[] arr , WriteConcern concern )
- // 更新記錄
- public abstract WriteResult update( DBObject q , DBObject o , boolean upsert , boolean multi , WriteConcern concern )
- // 保存數(shù)據(jù)之前附加額外屬性
- protected abstract void doapply( DBObject o )
- // 刪除記錄
- public abstract WriteResult remove( DBObject o , WriteConcern concern )
- // 查詢(xún)記錄
- abstract Iterator<DBObject> __find( DBObject ref , DBObject fields , int numToSkip , int batchSize , int limit, int options )
- // 創(chuàng)建索引
- public abstract void createIndex( DBObject keys , DBObject options )
復(fù)制代碼 此外,以下方法是在這些方法的基礎(chǔ)上,在進(jìn)行包裝和組合得到的:
Java代碼- 1.public final void ensureIndex( final DBObject keys , final DBObject optionsIN )
- 2.public final DBObject findOne( DBObject o, DBObject fields )
- 3.public final Object apply( DBObject jo , boolean ensureID )
- public final void ensureIndex( final DBObject keys , final DBObject optionsIN )
- public final DBObject findOne( DBObject o, DBObject fields )
- public final Object apply( DBObject jo , boolean ensureID )
復(fù)制代碼 ensurceIndex 方法用于創(chuàng)建索引,調(diào)用了抽象方法 createdIndex ,在此之前,先檢查數(shù)據(jù)庫(kù)是否為只讀,以及是否重復(fù)創(chuàng)建索引。
具體實(shí)現(xiàn)如下:
Java代碼- 1.public final void ensureIndex( final DBObject keys , final DBObject optionsIN )
- 2. throws MongoException {
- 3.
- 4. // 檢查是否為只讀
- 5. if ( checkReadOnly( false ) ) return;
- 6.
- 7. // 設(shè)置參數(shù)
- 8. final DBObject options = defaultOptions( keys );
- 9. for ( String k : optionsIN.keySet() )
- 10. options.put( k , optionsIN.get( k ) );
- 11.
- 12. // 取得參數(shù)中的索引名稱(chēng)
- 13. final String name = options.get( "name" ).toString();
- 14.
- 15. // 如果索引已經(jīng)創(chuàng)建,則返回,避免重復(fù)創(chuàng)建
- 16. if ( _createdIndexes.contains( name ) )
- 17. return;
- 18.
- 19. // 創(chuàng)建索引,并添加到 createdIndexes
- 20. createIndex( keys , options );
- 21. _createdIndexes.add( name );
- 22.}
- public final void ensureIndex( final DBObject keys , final DBObject optionsIN )
- throws MongoException {
- // 檢查是否為只讀
- if ( checkReadOnly( false ) ) return;
- // 設(shè)置參數(shù)
- final DBObject options = defaultOptions( keys );
- for ( String k : optionsIN.keySet() )
- options.put( k , optionsIN.get( k ) );
- // 取得參數(shù)中的索引名稱(chēng)
- final String name = options.get( "name" ).toString();
- // 如果索引已經(jīng)創(chuàng)建,則返回,避免重復(fù)創(chuàng)建
- if ( _createdIndexes.contains( name ) )
- return;
- // 創(chuàng)建索引,并添加到 createdIndexes
- createIndex( keys , options );
- _createdIndexes.add( name );
- }
復(fù)制代碼 findOne 方法用于查詢(xún)一個(gè)對(duì)象,第一個(gè)參數(shù)是表示查詢(xún)條件的 DBObject,第二個(gè)參數(shù)表示返回結(jié)果包含的字段。
調(diào)用了抽象方法 _find,并取第一條。
具體實(shí)現(xiàn)如下:
Java代碼- 1.public final DBObject findOne( DBObject o, DBObject fields ) {
- 2. // 調(diào)用 _find 方法
- 3. Iterator<DBObject> i = __find( o , fields , 0 , -1 , 0, getOptions() );
- 4.
- 5. // 讀取第一條記錄
- 6. if ( i == null || ! i.hasNext() )
- 7. return null;
- 8. return i.next();
- 9.}
- public final DBObject findOne( DBObject o, DBObject fields ) {
- // 調(diào)用 _find 方法
- Iterator<DBObject> i = __find( o , fields , 0 , -1 , 0, getOptions() );
- // 讀取第一條記錄
- if ( i == null || ! i.hasNext() )
- return null;
- return i.next();
- }
復(fù)制代碼 apply 方法用于在保存對(duì)象之前,為對(duì)象添加額外的屬性。
除了調(diào)用抽象方法 doapply,還可以根據(jù) ensureId 的值,生成 id。
具體實(shí)現(xiàn)如下:
Java代碼- 1.public final Object apply( DBObject jo , boolean ensureID ){
- 2. // 根據(jù) ensureId 的值,確定是否生成 id
- 3. Object id = jo.get( "_id" );
- 4. if ( ensureID && id == null ){
- 5. id = ObjectId.get();
- 6. jo.put( "_id" , id );
- 7. }
- 8.
- 9. // 調(diào)用抽象方法 doapply,為對(duì)象附加額外屬性。
- 10. doapply( jo );
- 11.
- 12. return id;
- 13.}
- public final Object apply( DBObject jo , boolean ensureID ){
- // 根據(jù) ensureId 的值,確定是否生成 id
- Object id = jo.get( "_id" );
- if ( ensureID && id == null ){
- id = ObjectId.get();
- jo.put( "_id" , id );
- }
- // 調(diào)用抽象方法 doapply,為對(duì)象附加額外屬性。
- doapply( jo );
- return id;
- }
復(fù)制代碼 委托給 _db 的方法
Java代碼- 1.// 查詢(xún)并修改對(duì)象
- 2.public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort,
- 3. boolean remove, DBObject update, boolean returnNew, boolean upsert)
- 4.
- 5.// 刪除索引
- 6.public void dropIndexes( String name )
- 7.
- 8.// 刪除該數(shù)據(jù)集
- 9.public void drop()
- 10.
- 11.// 統(tǒng)計(jì)數(shù)量
- 12.public long getCount(DBObject query, DBObject fields, long limit, long skip )
- 13.
- 14.// 重命名該集合
- 15.public DBCollection rename( String newName, boolean dropTarget )
- 16.
- 17.// 執(zhí)行 Group 操作
- 18.public DBObject group( GroupCommand cmd )
- 19.
- 20.// 查詢(xún)對(duì)象并去除重復(fù)
- 21.public List distinct( String key , DBObject query )
- 22.
- 23.// 執(zhí)行 Map Reduce 操作
- 24.public MapReduceOutput mapReduce( MapReduceCommand command )
- 25.
- 26.// 獲取索引信息
- 27.public List<DBObject> getIndexInfo()
- 28.
- 29.// 獲取子數(shù)據(jù)集
- 30.public DBCollection getCollection( String n )
- // 查詢(xún)并修改對(duì)象
- public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort,
- boolean remove, DBObject update, boolean returnNew, boolean upsert)
- // 刪除索引
- public void dropIndexes( String name )
- // 刪除該數(shù)據(jù)集
- public void drop()
- // 統(tǒng)計(jì)數(shù)量
- public long getCount(DBObject query, DBObject fields, long limit, long skip )
- // 重命名該集合
- public DBCollection rename( String newName, boolean dropTarget )
- // 執(zhí)行 Group 操作
- public DBObject group( GroupCommand cmd )
- // 查詢(xún)對(duì)象并去除重復(fù)
- public List distinct( String key , DBObject query )
- // 執(zhí)行 Map Reduce 操作
- public MapReduceOutput mapReduce( MapReduceCommand command )
- // 獲取索引信息
- public List<DBObject> getIndexInfo()
- // 獲取子數(shù)據(jù)集
- public DBCollection getCollection( String n )
復(fù)制代碼 以 findAndModify 為例。
findAndModify 方法用于查詢(xún)并修改對(duì)象,實(shí)際調(diào)用的是 _db.command( cmd ) 方法;
在調(diào)用 _db 的方法之前,先對(duì) cmd 進(jìn)行組裝,添加查詢(xún)條件、查詢(xún)字段、排序條件等;
然后調(diào)用 _db.command( cmd ),返回結(jié)果或拋出異常。
具體實(shí)現(xiàn)如下:
Java代碼- 1.public DBObject findAndModify(DBObject query, DBObject fields, DBObject sort,
- 2. boolean remove, DBObject update, boolean returnNew, boolean upsert) {
- 3. // 創(chuàng)建 cmd 對(duì)象
- 4. BasicDBObject cmd = new BasicDBObject( "findandmodify", _name);
- 5.
- 6. // 添加查詢(xún)條件
- 7. if (query != null && !query.keySet().isEmpty())
- 8. cmd.append( "query", query );
- 9.
- 10. // 添加查詢(xún)字段
- 11. if (fields != null && !fields.keySet().isEmpty())
- 12. cmd.append( "fields", fields );
- 13.
- 14. // 添加排序字段
- 15. if (sort != null && !sort.keySet().isEmpty())
- 16. cmd.append( "sort", sort );
- 17.
- 18. // 是否執(zhí)行刪除
- 19. if (remove)
- 20. cmd.append( "remove", remove );
- 21. else {
- 22. // 添加更新的字段
- 23. if (update != null && !update.keySet().isEmpty()) {
- 24. // if 1st key doesnt start with $, then object will be inserted as is, need to check it
- 25. String key = update.keySet().iterator().next();
- 26. if (key.charAt(0) != '$')
- 27. _checkObject(update, false, false);
- 28. cmd.append( "update", update );
- 29. }
- 30. // 是否返回新創(chuàng)建的對(duì)象
- 31. if (returnNew)
- 32. cmd.append( "new", returnNew );
- 33.
- 34. // 被查詢(xún)的對(duì)象不存在時(shí)是否創(chuàng)建一個(gè)
- 35. if (upsert)
- 36. cmd.append( "upsert", upsert );
- 37. }
- 38.
- 39. // 刪除操作與更新操作不能混合,拋異常
- 40. if (remove && !(update == null || update.keySet().isEmpty() || returnNew))
- 41. throw new MongoException("FindAndModify: Remove cannot be mixed with the Update, or returnNew params!");
- 42.
- 43. // 執(zhí)行 _db.command( cmd )
- 44. CommandResult res = this._db.command( cmd );
- 45.
- 46. // 返回結(jié)果或拋異常
- 47. if (res.ok() || res.getErrorMessage().equals( "No matching object found" ))
- 48. return (DBObject) res.get( "value" );
- 49. res.throwOnError();
- 50. return null;
- 51.}
復(fù)制代碼
作者: 寂寞沖咖啡 時(shí)間: 2011-11-14 09:38
謝謝分享
歡迎光臨 Chinaunix (http://72891.cn/) |
Powered by Discuz! X3.2 |