scala03

一个JDBC测试工具,用于执行数据库操作并处理结果

简要概述

这段代码展示了如何在Scala中使用JDBC进行数据库操作,并通过面向对象的方式封装和处理操作结果。

代码中的to方法用于类型转换,允许从泛型Three对象转换为具体的子类对象。

具体阐述

包和对象定义:
包名为recovery.scala,包含一个名为JdbcTest的对象。

结果枚举:
Result枚举定义了三种可能的操作结果:异常(EX)、数据操作语言(DML)和数据查询语言(DQL)。

泛型类Three:
Three类是一个泛型类,它封装了操作结果,并提供了一个类型转换方法to。

异常类Ex:
Ex类继承自Three,用于封装异常信息。

DML结果类Dml:
Dml类继承自Three,用于封装DML操作影响的行数。

DQL结果类Dql:
Dql类继承自Three,用于封装DQL操作返回的ResultSet。

数据库操作函数:
jdbc函数接受数据库连接参数和SQL语句,执行相应的数据库操作,并返回Three类型的结果。

主函数:
main函数演示了如何使用jdbc函数执行DML和DQL操作,并处理结果。

数据库连接和SQL执行:
在jdbc函数中,首先装载JDBC驱动,创建数据库连接,然后根据SQL语句类型执行对应的操作。

参数化查询:
如果提供了参数,使用PreparedStatement设置参数。

结果处理:
根据SQL语句的类型,返回相应的Dml或Dql对象,或者在出现异常时返回Ex对象。

DQL结果生成:
Dql类的generate方法用于从ResultSet生成Scala集合。

测试示例:
代码中提供了DML和DQL操作的示例,以及如何将DQL结果转换为自定义的Test对象的集合。

package recovery.scala

import java.sql._

import scala.collection.mutable.ArrayBuffer

object JdbcTest {
  object Result extends Enumeration{
    val EX = Value(0)
    val DML = Value(1)
    val DQL = Value(2)
  }
  case class Three(rst:Result.Value){
    // 需要限制 T 的上限
    def to[T<:Three]():T = this.asInstanceOf[T]
  }
  class Ex(throwable: Throwable) extends Three(Result.EX){
    def ex = throwable
  }
  object Ex{
    def apply(throwable: Throwable): Ex = new Ex(throwable)
  }
  class Dml(affectedRows:Int) extends Three(Result.DML){
    def updated = affectedRows
  }
  object Dml{
    def apply(affectedRows: Int): Dml = new Dml(affectedRows)
  }
  class Dql(set:ResultSet) extends Three(Result.DQL){
    def generate[T](f:ResultSet=>T) ={
      val buffer:ArrayBuffer[T] = ArrayBuffer()
      while (set.next()) {
        buffer.append(f(set))
      }
      buffer
    }
  }
  object Dql{
    def apply(set: ResultSet): Dql = new Dql(set)
  }

  def jdbc(url:String,user:String,pass:String)(sql:String,params:Seq[Any]=null):Three={
    def con() = {
      // 1.1 装载驱动
      Class.forName("com.mysql.cj.jdbc.Driver")
      // 1.2 创建连接对象
      DriverManager.getConnection(url,user,pass)
    }
    def pst(con:Connection)={
      // 2.1 创建执行对象
      val pst: PreparedStatement = con.prepareStatement(sql)
      // 2.2 初始化 SQL 参数
      if(null != params && params.length>0){
        params.zipWithIndex.foreach(t=>pst.setObject(t._2+1,t._1))
      }
      pst
    }
    try{
      val connect: Connection = con()
      val prepared: PreparedStatement = pst(connect)
      sql match {
        case sql if sql.matches("^(insert|INSERT|delete|DELETE|update|UPDATE) .*")
        =>Dml(prepared.executeUpdate())
        case sql if sql.matches("^(select|SELECT) .*")
        => Dql(prepared.executeQuery())
        case _ => Ex(new SQLException(s"illegal sql command : $sql"))
      }
    }catch {
      case e:Exception => Ex(e)
    }
  }

  def main(args: Array[String]): Unit = {
    // 解决结果差异化(正常和异常)
    // import scala.util.control.Exception.{allCatch,failAsValue}

    // 分段(参数列表)提取以复用
    val operate: (String, Seq[Any]) => Three = jdbc(
      url = "jdbc:mysql://single01:3306/test_db_for_bigdata",
      user = "root",
      pass = "ybremote"
    )

    /**
     *  mysql 资源包依赖:pom.xml
     *  1.初始化
     *    driver: com.mysql.cj.jdbc.Driver
     *    url, username, password
     *    创建连接
     *  2.初始化执行器
     *    sql, parameters
     *    创建执行器[,并初始化参数]
     *  3.执行操作并返回【结果】
     *    DML:影响数据库表行数
     *    DQL:集合
     *    Exception:异常
     */

    val dml : Dml = operate(
      "insert into test_table1_for_hbase_import values(?,?,?,?,?)",
        Seq(3012,"国庆节",75,"男","18014499655")
    ).to[Dml]

    println(dml.updated)

    val dml : Dml = operate(
      "delete from test_table1_for_hbase_import where test_id between ? and ?",
      Seq(1,10)
    ).to[Dml]

    println(dml.updated)

    val dql : Dql = operate(
      "select * from test_table1_for_hbase_import limit 20",
      null
    ).to[Dql]

    case class Test(id:Int,name:String,age:Int,gender:String,phone:String)
    val tests: ArrayBuffer[Test] = dql.generate[Test](rst => Test(
      id = rst.getInt(1),
      name = rst.getString(2),
      age = rst.getInt(3),
      gender = rst.getString(4),
      phone = rst.getString(5)
    ))
    tests.foreach(println)
  }
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值