0

我正在尝试创建一个可供多个类使用的单个数据库实例(object在 Kotlin 中使用关键字)。但是,我希望能够在创建单例实例之前指定数据库名称。

由于无法使用参数初始化单例对象,我想知道我正在做的事情是否有效,或者是否有更好的做事方式:

object DatabaseSingleton {

    private lateinit var databaseName: String
    private lateinit var mongoClient: MongoClient

    val database: DatabaseContainer by lazy {
        DatabaseContainer(databaseName, mongoClient)
    }

    fun init(databaseName: String, mongoClient: MongoClient): DatabaseSingleton {
        this.databaseName = databaseName
        this.mongoClient = mongoClient
        return this
    }
}

在另一个文件中

class DatabaseContainer(databaseName: String, val mongoClient: MongoClient) {

    val db: MongoDatabase = mongoClient.getDatabase(databaseName)
    val table: MongoCollection<Settings> = db.getCollection<Settings>(TABLE_NAME)

}

基本上,我在单例对象中封装了一个“数据库容器”,方法是对数据库容器使用延迟初始化,并提供用于指定数据库名称的 lateinit 变量,并在单例对象中使用初始化函数来初始化数据库容器。这样一来,当我第一次启动应用程序时,在我的 main 方法中,我可以从一些本地属性文件中加载数据库名称并调用val database = DatabaseSingleton.init("DATABASE_NAME", client)以创建需要由多个其他类访问的数据库单例。

这是做我想做的事的好方法,还是有更好的做事方法?

4

1 回答 1

2

尝试从系统属性(或系统环境变量)中获取 databaseName。您可以在启动脚本中设置该属性。

例如:java -DdatabaseName=databaseA ....

object DatabaseSingleton {
    private const var DB_NAME_SYS_KEY = "databaseName"

    private lateinit var databaseName: String
    private lateinit var mongoClient: MongoClient

    val database: DatabaseContainer by lazy {
        DatabaseContainer(databaseName, mongoClient)
    }

    fun init(mongoClient: MongoClient): DatabaseSingleton {
        this.databaseName = System.getProperty(DB_NAME_SYS_KEY)
        this.mongoClient = mongoClient
        return this
    }
}
于 2017-03-27T10:55:34.040 回答