在实际开发工作中,通常需要通过单例模式创建mongo数据库对象,Casbah 是 Mongodb 官方的 Scala 驱动程序包,本文基于scala语言实现对Casbah的单例模式包装。
1. Singleton 特征
package com.flute.mongo import java.util.UUID /** * Created by xpli on 03/05/16. */ trait Singleton { protected val instanceID:String=UUID.randomUUID().toString def getInstanceID=this.instanceID }
2. MongoCollection类,对Casbah 官方DBCollection类的包装
package com.flute.mongo import com.mongodb.{DBCollection, DBObject} import scala.collection.mutable /** * Created by xpli on 30/04/16. */ class MongoCollection(override val underlying: com.mongodb.DBCollection) extends com.mongodb.casbah.MongoCollection(underlying) with Singleton { def saveDBObject(obj: DBObject) = underlying.save(obj) } object MongoCollection { private val instanceMap = new mutable.HashMap[String, MongoCollection] def apply(collection: DBCollection, dbId: String): MongoCollection = { val instanceKey = s"${dbId}:${collection.getName}" if (!instanceMap.contains(instanceKey)) { this.synchronized { if (!instanceMap.contains(instanceKey)) instanceMap += (instanceKey -> new MongoCollection(collection)) } } instanceMap(instanceKey) } }
3.MongoDB类,对对Casbah 官方com.mongodb.DB类的包装
package com.flute.mongo import scala.collection.mutable /** * Created by xpli on 30/04/16. */ class MongoDB(override val underlying: com.mongodb.DB) extends com.mongodb.casbah.MongoDB(underlying) with Singleton { // println("new MongoDB****") override def apply(collName: String): MongoCollection = MongoCollection(underlying.getCollection(collName), instanceID) // override val instanceID: String =UUID.randomUUID().toString } object MongoDB { private val instanceMap = new mutable.HashMap[String, MongoDB] def apply(db: com.mongodb.DB, clientId: String): MongoDB = { val instanceKey = s"${clientId}:${db.getName}" if (!instanceMap.contains(instanceKey)) { this.synchronized { if (!instanceMap.contains(instanceKey)) instanceMap += (instanceKey -> new MongoDB(db)) } } instanceMap(instanceKey) } }
4. MongoClient类
package com.flute.mongo import com.flute.exception.Exception.MongoUriFormatIllegalException import com.mongodb.ServerAddress import com.mongodb.casbah.MongoClientOptions import scala.collection.mutable /** * Created by xpli on 30/04/16. */ class MongoClient(ip: String, port: Int) extends Singleton { // override val instanceID: String = UUID.randomUUID().toString val build: MongoClientOptions.Builder = new MongoClientOptions.Builder build.connectionsPerHost(50) // build.autoConnectRetry(true) // println(s"MongoClient:${ip}:${port}") build.threadsAllowedToBlockForConnectionMultiplier(50) build.maxWaitTime(1000 * 60 * 2) build.connectTimeout(1000 * 60 * 1) private val client = com.mongodb.casbah.MongoClient(new ServerAddress(ip, port), build.build) def apply(dbName: String): MongoDB = MongoDB(client.underlying.getDB(dbName), instanceID) def getDB(dbName: String): MongoDB = MongoDB(client.underlying.getDB(dbName), instanceID) // class save(dBObject: DBObject) { // def to(dbName: String)(collName: String): Unit = getDB(dbName)(collName).saveDBObject(dBObject) // } // // object save { // def apply(dBObject: DBObject): save = new save(dBObject) // } } object MongoClient { def apply(ip: String, port: Int): MongoClient = { val uri = getMongoUri(ip, port) if (!instanceMap.contains(uri)) { this.synchronized { if (!instanceMap.contains(uri)) instanceMap += (uri -> new MongoClient(ip, port.toInt)) } } instanceMap(uri) } def apply(uri: String): MongoClient = { val uriPattern = "mongodb://(\d+\.\d+\.\d+\.\d+):(\d+)".r uri match { case uriPattern(ip, port) => this.apply(ip, port.toInt) case _ => throw MongoUriFormatIllegalException(uri) } } private def getMongoUri = (ip: String, port: Int) => s"mongodb://${ip}:${port}" private val instanceMap = new mutable.HashMap[String, MongoClient] }
5. 使用示例
object Demo { def main(args: Array[String]) { val client1 = MongoClient("192.168.86.23", 27017) val client2 = MongoClient("192.168.86.23", 27017) val client3 = MongoClient("192.168.86.154", 27017) println(s"client1:${client1}") println(s"client2:${client2}") println(s"client3:${client3}") } }
打印结果:
client1:com.flute.mongo.MongoClient@f6fb957
client2:com.flute.mongo.MongoClient@f6fb957
client3:com.flute.mongo.MongoClient@4868bd35