【问题标题】:How to read value from properties using picocli and using it connect postgres如何使用 picocli 从属性中读取值并使用它连接 postgres
【发布时间】:2021-04-22 15:08:10
【问题描述】:

我使用 picocli,我想构建 cli 从数据库中获取数据并将其发送到另一个服务。所以我的配置看起来像

object Student : Table("student") {
    val id = integer("student_id").autoIncrement().primaryKey()
    val name = varchar("name", 50)
    val grade = integer("grade")
}

class App() : Callable<Integer> {
    @CommandLine.Option(names = ["-ho", "--host"], description = arrayOf("Host database"), defaultValue = "localhost")
    var host: String? = null

    @CommandLine.Option(names = ["-p", "--port"], description = arrayOf("port database"), defaultValue = "5432")
    var port: String? = null

    @CommandLine.Option(names = ["-d", "--database"], description = arrayOf("database"), defaultValue = "postgres")
    var database: String? = null

    @CommandLine.Option(names = ["-u", "--username"], description = arrayOf("username of database"), defaultValue = "postgres")
    var username: String? = null

    @CommandLine.Option(names = ["-w", "--password"], description = arrayOf("password off database"), defaultValue = "password")
    var password: String? = null

    override fun call(): Integer {
       connectDB()
       createStudent()
       return Integer(0)
    }

    fun createStudent() {
        println("Begin create student")
        transaction {
            create(Student)
        }
        println("End create student")
    }

    fun connectDB() {
        try {
            Database.connect("jdbc:postgresql://${this.host}:${this.port}/${this.database}", "org.postgresql.Driver",this.username.toString(),this.password.toString())
            print("Connect db")
        } catch (e : Exception) {
            println("Connect db fail with error ${e.message}")
        }
    }
}

fun main(args: Array<String>) {
    val existCode = CommandLine(App()).execute(*args)
    System.exit(existCode);
}

当我执行时,它连接成功。但我不想从 args 解析值。我想从我的文件属性示例中读取:db.propertiesdb.yml。怎么办?

我搜索了文档 picocli,但找不到任何内容。所以现在我在我的 postgres 中使用 org.jetbrains.exposed:exposed crud。它可以与 picoli 一起使用吗?如果从数据库中获取数据并将其发送到另一个 api,是否有任何建议的框架?非常感谢你

【问题讨论】:

    标签: kotlin-exposed picocli


    【解决方案1】:

    您提到的要求是一种常见的 CLI 设计模式:用户可以在命令行或配置文件中指定值(或两者都指定,在这种情况下,命令行会覆盖配置文件)。

    在 picocli 中,实现这一目标的最简单方法是使用 default provider:如果未在命令行上指定该值,则从该默认提供程序获取该值。

    您的默认提供程序实现可以从属性文件或 yaml 文件中读取,这完全取决于您。

    例如:

    @Command(name = "db", defaultValueProvider = MyDefaultProvider.class)
    class App() : Callable<Integer> {
       // ...
    }
    
    class MyDefaultProvider implements picocli.CommandLine.IDefaultValueProvider {
        public String defaultValue(ArgSpec argSpec) throws Exception {
            // read db.properties (or db.yml or something) from some location
            Properties defaultValues = readProperties();
    
            // return the default value for the argument
            if (argSpec.isOption()) {
                OptionSpec option = (OptionSpec) argSpec;
                return defaultValues.getProperty(option.longestName());
            }
        }
    
        private Properties readProperties() throws IOException {
            //...
        }
    }
    

    Picocli 还提供了内置的PropertiesDefaultProvider 实现,它在用户主目录中查找名为.${COMMAND-NAME}.properties 的文件,其中${COMMAND-NAME} 是命令的名称。 (在您的示例中,App 类没有 @Command(name = "xxx") 注释,如果您选择使用内置的 PropertiesDefaultProvider,则可能需要添加此注释。)

    【讨论】:

    • 非常感谢。所以现在我想使用 jpa 连接 crud 数据库?那么当我使用 cli 时,我使用什么框架呢?我使用 micronaut 但是当我使用 @inject 依赖时它总是抛出异常而不是初始化?所以当我连接休息或其他服务时,我可以使用 micronaut http 客户端?
    • 你看过Micronaut picocli integration上的指南吗?它有一些@inject 示例。
    • 非常感谢。我有一个问题:如果我不想为 db 调用命令并且我希望每个我创建学生 picocli 它都会自动连接 db 并使用 picocli 将 arg 解析到数据库?怎么做 ?所以我想使用 app.yml 而不是 app.properties。有可能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    相关资源
    最近更新 更多