单例模式创建mongo对象(scala实现)

  在实际开发工作中,通常需要通过单例模式创建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


 

posted on 2017-02-13 10:58  taich-flute  阅读(1204)  评论(0编辑  收藏  举报

导航