Как создать программу Scala Jdb c, используя Option для обработки нуля при возврате соединения? - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь написать программу scala -jdb c, которая будет выполнять оператор анализа для таблиц, представленных в нашей базе данных. Для этого я написал код следующим образом.

object Trip {
    def main(args: Array[String]): Unit = {
        val gs = new GetStats(args(0))
        gs.run_analyze()
    }
}
-----------------------------------------------------------------
class GetStats {
    var tables = ""
    def this(tables:String){
        this
        this.tables = tables
    }
    def run_analyze():Unit = {
        val tabList = tables.split(",")
        val gpc = new GpConnection()
        val con = gpc.getGpCon()
        val statement = con.get.createStatement()
        try {
            for(t<-tabList){
                val rs = statement.execute(s"analyze ${t}")
                if(rs.equals(true)) println(s"Analyzed ${t}")
                else println(s"Analyze failed ${t}")
            }
        } catch {
            case pse:PSQLException => pse.printStackTrace()
            case e:Exception       => e.printStackTrace()
        }
    }
}
-----------------------------------------------------------------
class GpConnection {
    var gpCon: Option[Connection] = None
    def getGpCon():Option[Connection] = {
        val url      = "jdbc:postgresql://.."
        val driver   = "org.postgresql.Driver"
        val username = "user"
        val password = "1239876"
        Class.forName(driver)
            if(gpCon==None || gpCon.get.isClosed) {
            gpCon = DriverManager.getConnection(url, username, password).asInstanceOf[Option[Connection]]
            gpCon
        } else gpCon
    }    
}

Я создаю файл jar по своей идее (IntelliJ) и отправляю jar, как показано ниже.

scala -cp /home/username/jars/postgresql-42.1.4.jar analyzetables_2.11-0.1.jar schema.table

Когда я отправляю В jar-файле я вижу исключение ClassCastException, как указано ниже.

java.lang.ClassCastException: org.postgresql.jdbc.PgConnection cannot be cast to scala.Option
    at com.db.manager.GpConnection.getGpCon(GpConnection.scala:15)
    at com.gp.analyze.GetStats.run_analyze(GetStats.scala:19)
    at com.runstats.Trip$.main(Trip.scala:8)
    at com.runstats.Trip.main(Trip.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:32)
    at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:30)
    at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:90)
    at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:22)

Исключение говорит о том, что соединение не может быть преобразовано в scala.option, но если я не использую Option, я не могу использовать null чтобы инициализировать объект подключения, и я вижу NullPointerException, когда я запускаю код. Может ли кто-нибудь сообщить мне, какую ошибку я здесь совершаю и как я могу это исправить?

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

asInstanceOf[] не работает таким образом. Он не просто создаст Option[] для вас.

val x:Option[Int] = 5.asInstanceOf[Option[Int]]  //not gonna happen

Вы должны явно создать Option[].

val x:Option[Int] = Option(5)
1 голос
/ 13 февраля 2020

Вы можете использовать неинициализированную переменную как:

var gpCon: Connection = _

Но так как вы используете scala.util.Option, что лучше сделать, делайте это функционально и не пишите императив Java код в Scala, например:

// a singleton object (Scala provided)
object GpConnection {
    private var gpCon: Option[Connection] = None

    // returns a Connection (no option - as we need it!)
    def getOrCreateCon(): Connection = gpCon match {
        case conOpt if conOpt.isEmpty || conOpt.get.isClosed =>
            // connection not present or is closed
            val url      = "jdbc:postgresql://.."
            val driver   = "org.postgresql.Driver"
            val username = "user"
            val password = "1239876"

            // may throw an exception - you can even handle this
            Class.forName(driver)

            // may throw an exception - you can even handle this
            gpCon = Option(DriverManager.getConnection(url, username, password).asInstanceOf[Connection])
            gpCon.getOrElse(throw new RuntimeException("Cannot create connection"))
        case Some(con) => con
    }    
}

используйте его как:

val con = GpConnection.getOrCreateCon
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...