class Foo(calc: PGSimpleDataSource => Connection => PreparedStatement => ResultSet => Option[A] ??? ) {
here some logic like:
def runCalc = calc ( resultSet ( preparedStatement ( connection )
resultSet.close()
preparedStatement.close()
connection.close()
send result somewhere ...
}
准备一些功能
implicit val dataSource: PGSimpleDataSource = Service.ds
implicit def getConnection(implicit ds: PGSimpleDataSource): Connection = ds.getConnection
implicit def getPreparedStatement(userId: UUID)(implicit con: Connection): PreparedStatement ={
val st = con.prepareStatement("SELECT * FROM bar WHERE id = CAST(? as UUID)")
st.setString(1, id.toString)
st
}
implicit def getResultSet(implicit ps: PreparedStatement): ResultSet = ps.executeQuery()
implicit def mapping(implicit rs: ResultSet): Option[Bar] = {
Iterator.continually(rs.next)
.takeWhile(identity)
.map(_ => Bar(UUID.fromString(rs.getString(1)))).toList.headOption
}
然后是一些功能,例如:
def getInstance(id: UUID) = new Foo(???)
val foo = getInstance(id)
foo.runCalc()
有可能吗?请帮助
更新:
我试图像这样上课:
class Foo[A](
con: => Connection,
ps: => PreparedStatement,
rs: => ResultSet,
mapping: => Option[A],
calc: Connection => PreparedStatement => ResultSet => Option[A]
) {
def run(): Unit = {
val result: Option[A] = calc(con)(ps)(rs)(mapping)
rs.close()
ps.close()
con.close()
}
}
但是我不明白如何编写如下的“ f”函数
需要映射(getResultSet(getPreparedStatement(id,getConnection))
换句话说,映射需要ResultSet,而ResultSet需要带ID和Connection的PreparedStatement
答案 0 :(得分:1)
您可以做到。看起来像这样
case class Foo(calc: String => String => String => Option[String]) {
def run = {
val p1 = "p1"
val p2 = "p2"
val p3 = "p3"
calc(p1)(p2)(p3)
}
}
用法示例
object App extends App {
val f = (x: String) => (y: String) => (z: String) => {
Option(x + y + z)
}
val foo = Foo(f)
println(foo.run)
}
或者您可以使用currying
object App extends App {
val f = (x: String, y: String, z: String) => {
Option(x + y + z)
}
val foo = Foo(f.curried)
println(foo.run)
}
编辑
对于您的扩展问题,我可以建议此类:
case class Foo[A](
getConnection: () => Connection,
getStatement: Connection => PreparedStatement,
getResultSet: PreparedStatement => ResultSet,
mapping: ResultSet => Option[A]) {
def run(): Option[A] = {
val connection = getConnection()
try{
val statement = getStatement(connection)
try{
val resultSet = getResultSet(statement)
try{
mapping(resultSet)
}finally {
resultSet.close()
}
}finally{
statement.close()
}
} finally {
connection.close()
}
}
}
用法示例:
val foo = Foo(
() => new Connection(),
connection => new PreparedStatement(),
statement => new ResultSet(),
resultSet => Option("")
)
所有这些功能都具有上一步中的参数,因此,例如,当您创建ResultSet
时,可以使用statement
(但是不能使用connection
)。