Slick plain SQL如何传递List[Int]参数

最近用slick作为数据库访问框架,有些功能不好实现,用plain SQL,sql是根据查询条件生成的,所以参数也不是固定的个数。但StaticQuery[T, Entity]里面的T,默认只支持数据库支持的类型比如Int,Double等,以及对应的Optional,也可以支持Tuple1--Tuple22,只要里面的类型是数据库支持的类型。但因为我要传递的参数在编译期没法知道有多少个,所以只能用List[Int]来传递,结果报错说找不到对应的隐式转化。

[error] D:\xx.scala:49: could not
find implicit value for parameter pconv1: scala.slick.jdbc.SetParameter[List[Int]]
[error]     val query = Q[List[Int], Entity] + sql
[error]                  ^
[error] one error found
[error] (compile:compile) Compilation failed

首先想到的是有没有办法把List[Int],转化成Tuple呢,仔细一想,发现不对,List[Int],里面包含参数是不固定的,但是TupleX,需要在编译期就指定,到底是几个参数。google一下,发现果然不行。

然后就想看看StaticQuery这个类具体做了什么,点进去看源码,发现它需要一个implicit的参数

object StaticQuery {
.............
  def apply[P, R](implicit pconv1: SetParameter[P],  rconv: GetResult[R]) = query[P,R]("")
............
}

然后继续看SetParameter,

trait SetParameter[-T] extends ((T, PositionedParameters) => Unit) { self =>
  def applied(value: T): SetParameter[Unit] = new SetParameter[Unit] {
    def apply(u: Unit, pp: PositionedParameters) {
      self.apply(value, pp)
    }
  }
}

并且在object SetParameter里面定了了一堆刚说过的默认支持的参数类型,包括Int, Optional[Int], Tuple2[Int, Int]等,看了下实现

implicit object SetInt extends SetParameter[Int] { def apply(v: Int, pp: PositionedParameters) { pp.setInt(v) } }

很简单就想到了List[Int]的实现方法,于是在自己的类里面定义了一个List[Int]的隐式转化

implicit object SetListInt extends SetParameter[List[Int]] {
    def apply(vList: List[Int], pp: PositionedParameters) {
      for (v <- vList)
        pp.setInt(v)
    }
  }

因为经常用到,所以放在BaseDao里面,搞定。

总结

以后遇到问题,首先想想是否可以转化为以后的实现方式(List[Int] -> TupleX[Int]);如果不行,Google、StackOverflow等查查有没有其他解决方法;最后不行,就只能自己看source code去掌握原理,自己实现了。

时间: 2024-10-10 00:25:00

Slick plain SQL如何传递List[Int]参数的相关文章

mybatis 中sql语句传递多个参数

Available parameters are [2, 1, 0, param1, param2, param3] <select id="loginByTeacher" parameterType="String" resultType="User">     SELECT * FROM `user` WHERE LoginID=#{0} and LoginPwd=#{1} AND Role=2  </select>

关于向Mybatis传递多个参数进行SQL查询的用法

当只向xxxMapper.xml文件中传递一个参数时,可以简单的用"_parameter"来接收xxxMapper.java传递进来的参数,并代入查询,比如说这样: (1)xxxMapper.java文件中这样定义: List<String> selectAllAirportCode(Boolean mapping); (2)这时在对应的xxxMapper.xml文件中可以使用"_parameter"来接收这个参数: <select id=&quo

Linux/Unix shell sql 之间传递变量

灵活结合Linux/Unix Shell 与SQL 之间的变量传输,极大程度的提高了DBA的工作效率,本文针对Linux/Unix shell sql 之间传递变量给出几个简单的示例以供参考. Linux/Unix 下调用SQL,RAMN 请参考:Linux/Unix shell 脚本中调用SQL,RMAN脚本 一.示例 [python] view plain copy print? 1.shell变量接受sql返回值之方式一 [email protected]:~> more ./retval

SQL Server 2008 表变量参数(表值参数)用法

表值参数是 SQL Server 2008 中的新参数类型.表值参数是使用用户定义的表类型来声明的.使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据. 表值参数与 OLE DB 和 ODBC 中的参数数组类似,但具有更高的灵活性,且与 Transact-SQL 的集成更紧密.表值参数的另一个优势是能够参与基于数据集的操作. (注意:Transact-SQL 通过引用向例程传递表值参数,以避免创建输入数据的副本.) 在 Tra

转载 C#中使用结构来传递多个参数

C#中当参数超过5个时,建议用结构来传递多个参数. 示例代码如下: 1 public struct MyStruct 2 { 3 public string str; 4 public int number; 5 } 6 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 MyStruct myStruct = new MyStruct(); 12 myStruct.str = "Number :"; 13 myS

C# 使用Tuple传递多个参数

Tuple是基于.NET Framework 4.0 及以上版本才有的.微软称它为元组,如果有三个参数那就是三元组.如 Tuple(T1, T2, T3) Tuple的命名空间在 System 很短吧,也就是说只要是基于.NET Framework 4.0 及以上版本的,创建项目就可以直接在Visual Studio中敲出来. 程序集: mscorlib(在 mscorlib.dll 中) 为什么要使用Tuple 来!先看看下面这个方法. public bool MyMethod(out str

sql数据库表名做参数

declare @tablename nvarchar(50)declare @count intset @tablename = 'SplitzRank'declare @sqlstr nvarchar(512)set @sqlstr = 'select @count=count(*) from '[email protected]select @sqlstrexec sp_executesql @sqlstr,N'@count int output',@count outputselect

sql中获得时间的参数

返回表示指定日期的指定日期部分的整数. 语法 DATEPART ( datepart , date ) 参数 datepart 指定要返回的日期部分的参数.有关详细信息,请参阅本主题后面的“备注”部分. date 返回 datetime 值(或可隐式转换为 datetime 值的值)的表达式.date 参数也可以是日期格式的字符串.datetime 数据类型仅用于 1753 年 1 月 1 日之后的日期. 对于之前的日期,将存储为字符数据.在输入 datetime 值时,请始终使用单引号将它们括

问题:子信息不能够传递多个参数,利用脚本可以做到

问题:子信息不能够传递多个参数,利用脚本可以做到.1.加前端脚本function GridRowOnDblClick(strFile,pkValue,rowIndex){var ksrq = document.all.val_KSRQ.value;//2个控件的值var jsrq = document.all.val_JSRQ.value;//2个控件的值strFile=strFile+"&ksrq="+ksrq+"&jsrq="+jsrq;if (