根据Slick 2.0文档,要获取表中的行数:
val q1 = coffees.length
// compiles to SQL (simplified):
// select count(1) from "COFFEES"
Run Code Online (Sandbox Code Playgroud)
然而,事实证明这coffees.length
是类型Column[Int]
.
如何执行查询并获取值?
我知道光滑的2.1.可以使用ConstColumn使用"Compiled"来获取和删除预编译的Query.
private val findXXXCompiled = Compiled {
(someId:Column[Long], sortBy:???, drop:ConstColumn[Long], take:ConstColumn[Long]) =>
val q = findXXX(someId) // returns a Query
// I want to use query composition on "q" in order to further restrict my result:
q.sortBy {
case (_, name, state) => sortBy match {
case ??? => name.asc
case ??? => name.desc
case ??? => state.asc
case ??? => state.desc
}
}.drop(drop).take(take) // possible since slick 2.1. as described above using type ConstColumn
}
Run Code Online (Sandbox Code Playgroud)
}
上面的示例代码由用户从具有表格布局的UI触发.如果用户单击"名称"标题,则应根据"名称"对表进行排序 - "状态"相同. …
我正在为我的play2/slick2项目开发一个抽象的CRUD-DAO.为了拥有方便的类型安全的主要ID我使用Unicorn作为额外的抽象和方便在光头MappedTo
和ColumnBaseType
.
Unicorn提供了一个基本的CRUD-DAO类BaseIdRepository
,我想进一步扩展它以满足项目的特定需求.班级的签名是
class BaseIdRepository[I <: BaseId, A <: WithId[I], T <: IdTable[I, A]]
(tableName: String, val query: TableQuery[T])
(implicit val mapping: BaseColumnType[I])
extends BaseIdQueries[I, A, T]
Run Code Online (Sandbox Code Playgroud)
这导致DAO实现看起来像
class UserDao extends
BaseIdRepository[UserId, User, Users]("USERS", TableQuery[Users])
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎是多余的.我能够提供tableName
和query
从T
我自己的抽象DAO给我以下签名
abstract class AbstractIdDao[I <: BaseId, A <: WithId[I], T <: IdTable[I, A]]
extends BaseIdRepository[I,A,T](TableQuery[T].baseTableRow.tableName, TableQuery[T])
Run Code Online (Sandbox Code Playgroud)
是否有可能在斯卡拉以某种方式推断类型I
并A
做出类似以下可能的签名?(Users
是一个类扩展IdTable
)
class UserDao extends AbstractIdDao[Users]
Run Code Online (Sandbox Code Playgroud)
这可能没有运行时反射吗?如果仅通过运行时反射:如何在类定义中使用Manifest以及在响应式应用程序中对性能的影响有多大?
另外,因为我对这门语言还很陌生并独立工作:这是scala中的好习惯吗?
谢谢你的帮助.随意批评我的问题和英语.当然,改进将提交给Unicorn …
在光滑,我们可以使用
query.filter( m => (m.state === state1 && m.status === status1) || (m.state === state2 && m.status == status2))
Run Code Online (Sandbox Code Playgroud)
对于where子句中的"OR"条件.但是我的要求是我在列表中有"OR"条件(由用户作为URL的一部分传递).条件列表包括状态和状态元组
List[(state1, status1),(state2, status2),(state3, status3)]
Run Code Online (Sandbox Code Playgroud)
所以我想要的是能够构建|| 过滤器内部的语句,以便我可以使用列表中的每个条件来生成查询,但我不知道如何实现.或者,如果有类似的东西
query.applyOrFilters.orFilter(condition1).orFilter(condition2)
Run Code Online (Sandbox Code Playgroud)
这实际上会对查询对象执行condition1 OR condition2.现在可以使用Slick还是用于理解?
我正在尝试打印插值的Slick2 SQL语句进行调试,我得到的只是带有问号的那个
def query(name: String) = sql"SELECT MAX(age) FROM users WHERE name = $name".as[Int]
println(query("Bob").getStatement)
Run Code Online (Sandbox Code Playgroud)
以上打印出来:
SELECT MAX(age) FROM users WHERE name = ?
Run Code Online (Sandbox Code Playgroud)
我怎样才能打印出来:
SELECT MAX(age) FROM users WHERE name = 'Bob'
Run Code Online (Sandbox Code Playgroud)
注意:这个问题与此不重复
如果列为空,如何在Slick中过滤行?
val employees = Queryable[Employees]
// Error
val query = employees.filter( _.terminationDate == Nil )
Run Code Online (Sandbox Code Playgroud)
可能需要注意的是
terminationDate: Option[String]
Run Code Online (Sandbox Code Playgroud)
我正在使用直接嵌入.
我想这样做SELECT MAX(age), MIN(age) FROM users WHERE name = 'Rick'
.我提出的最好的涉及2个查询:Users.filter(_.name === 'Rick').map(_.age).max
我正在开发一个sbt插件,它使用Slick代码生成器为数据库生成Scala模型
我当然希望用户覆盖代码生成器,所以我的插件需要支持这个:
无论如何,我可以动态加载一个Scala类,给出build.sbt插件中的路径吗?例如,在用户的父build.sbt,她会提供像codegen.override=com.company.project.CustomCodegenerator
它看起来是这样的
与上述有关; 自定义codegen可能会使用其他一些库,因此简单的动态类加载可能不够.无论如何,一个sbt插件可以使用该插件继承项目的依赖项?
以下是对此的全面讨论:https://github.com/papauschek/play-slick-evolutions-plugin/issues/1
使用自定义列类型时,我在Slick 2.1.0中查询/过滤时遇到一些困难.我的问题的简化版本:
import scala.slick.driver.MySQLDriver.simple._
sealed class Status(val intValue: Int)
case object Active extends Status(1)
case object Disabled extends Status(2)
case object Deleted extends Status(3)
case class TableMapping(id: Long, status: Status)
class MyTableDefinition(tag: Tag) extends Table[TableMapping](tag, "sometable") {
implicit val statusColumnType = MappedColumnType.base[Status, Int](statusToInt, intToStatus)
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def status = column[Status]("STATUS", O.NotNull, O.Default(Active))
def * = (id, status) <> (TableMapping.tupled, TableMapping.unapply)
private def statusToInt(s: Status): Int = s.intValue
private def intToStatus(i: Int): Status = i match { …
Run Code Online (Sandbox Code Playgroud) 我目前有一组以约定命名的数据访问对象*SlickRepo
.因此,例如,UserSlickRepo
,DistributionSlickRepo
,ContentSlickRepo
,等...
这些Repos中的每一个都有基于此约定的方法:
trait SomethingRepoImpl extends SomethingRepo {
val somethingRepo: SomethingRepo = new SomethingRepoImpl
class SomethingRepoImpl extends SomethingRepo with MySlickDatastore {
def getSomething(id: UUID): Either[SomethingNotFoundError, Something] = {
getDatabase withDynSession {
// Slick stuff
}
}
def createSomething .....
}
}
Run Code Online (Sandbox Code Playgroud)
现在在服务级别,我们在这个repo类中烘焙,我们的方法看起来像这样:
trait SomethingServiceImpl extends SomethingService {
dep: SomethingRepo with SomethingElseRepo =>
val somethingService = new SomethingServiceImpl
class SomethingServiceImpl extends SomethingService {
def createSomethingGood(): Either[SomeError, (Something, SomethingElse)] = {
(dep.somethingRepo.createSomething, dep.somethingElseRepo.createSomethingElse)
}
} …
Run Code Online (Sandbox Code Playgroud)