给定具有am:n关系的遗留数据库以及关系的一些附加属性,如何使用squeryl定义.最后,表格应如下所示:
+--------------+ +---------------+ +----------------+
| TableA | | Rel_A_B | | TableB |
+--------------+ ____ +---------------+ ____ +----------------+
| id: Int | | tableA: int | | compkey_1: int |
| (more attrs) | | tableB_1: int | | compkey_2: int |
+--------------+ | tableB_2: int | | (more attrs) |
| value: Varchar| +----------------+
| date: Date |
+---------------+
使用squeryl手动定义三个表没有问题.但是,据我所知,目前的文档(0.9.4)没有可能与关系的其他属性定义多对多关系.
这就是我定义三个表和两个一对多关系的原因:
// TableA
class TableA(val id: Int, ...) extends KeyedEntity[Int] {
def this() = this(0, ...)
}
// TableB …Run Code Online (Sandbox Code Playgroud) 我正在学习Squeryl并尝试理解'using'语法,但无法找到它的文档.
在以下示例中,创建了两个数据库,A包含单词Hello,B包含Goodbye.目的是查询A的内容,然后附加单词World并将结果写入B.
预期的控制台输出是Inserted Message(2,HelloWorld)
object Test {
def main(args: Array[String]) {
Class.forName("org.h2.Driver");
import Library._
val sessionA = Session.create(DriverManager.getConnection(
"jdbc:h2:file:data/dbA","sa","password"),new H2Adapter)
val sessionB = Session.create(DriverManager.getConnection(
"jdbc:h2:file:data/dbB","sa","password"),new H2Adapter)
using(sessionA){
drop; create
myTable.insert(Message(0,"Hello"))
}
using(sessionB){
drop; create
myTable.insert(Message(0,"Goodbye"))
}
using(sessionA){
val results = from(myTable)(s => select(s))//.toList
using(sessionB){
results.foreach(m => {
val newMsg = m.copy(msg = (m.msg+"World"))
myTable.insert(newMsg)
println("Inserted "+newMsg)
})
}
}
}
case class Message(val id: Long, val msg: String) extends KeyedEntity[Long]
object Library extends …Run Code Online (Sandbox Code Playgroud) 在Squeryl 入门页面上有一个Scala代码示例:
import sbt._
class Project(info: ProjectInfo) extends DefaultProject(info) {
val squeryl = "org.squeryl" % "squeryl_2.8.1" % "0.9.4-RC3"
}
Run Code Online (Sandbox Code Playgroud)
我很困惑,因为%不是RichString或String类中定义的方法.我最好的猜测是它在别处定义并称为隐式转换.
在Scala中阅读和理解此类代码的最佳方法是什么?
我即将在Lift框架中开始我的第一个项目,我必须决定选择哪个持久性库.我即将使用关系后端,因此Mapper和Record都可以发挥作用.
在Mapper的情况下 - 我最想念的是能够控制发送到RDBMS的查询 - 特别是当涉及更复杂的查询时,这些查询将通过SQL中的连接,聚合等来解决.举几个例子 - 让我们有两个实体:
class BaseProduct extends LongKeyedMapper[BaseProduct] with IdPK {
// some fields
}
object BaseProduct extends BaseProduct with LongKeyedMetaMapper[BaseProduct]
class MyProduct extends LongKeyedMapper[MyProduct] with IdPK {
// some fields
object base extends MappedLongForeignKey(this, BaseProduct)
}
object MyProduct extends MyProduct with LongKeyedMetaMapper[MyProduct]
Run Code Online (Sandbox Code Playgroud)
其中MyProduct一个BaseProduct实体的专业化.这些实体之间显然存在一对一的关系.然而,我想出的最好的可能性是MyProduct与它一起查询确切的BaseProduct是这样的查询:
MyProduct.findAll(PreCache(MyProduct.base))
Run Code Online (Sandbox Code Playgroud)
哪个发出两个查询(而且我担心我无法控制MyProduct我想要选择的实体的哪些字段.
对Mapper库来说已经够糟了.我对Record/Squeryl API的主要关注是它缺少ProtoMapper API周围存在的所有类.是否有一些接近这些类的功能的记录?是否可以访问Squeryl中的数据库特定功能(例如PostgreSQL中的几何查询)?
这些层中的任何一层都有其他优缺点吗?还是有,如果我想有与数据库和通信体面类型安全的封装将提供体面的控制权查询(我是用来发出直接使用PHP的PDO层查询这将值得关注任何其他抽象层 - 我不想要这样的直接查询界面,但是控制查询的一些可能性很大.与Lift框架的集成绝对是一个优势.
谢谢!
我正在使用scala 2.8.1,scalatra 2.0.0.M2,squeryl 2.8.0和scalate 2.0.0以及sbt开发Web应用程序
我遇到了问题,显然是模型或架构类.当我运行我的测试时,我得到一个:
java.lang.NoClassDefFoundError: Could not initialize class org.mycompany.myproject.model.myschema
Run Code Online (Sandbox Code Playgroud)
如果我尝试在sbt的console-quick上运行以下代码,我会收到一个错误:
import org.mycompany.myproject.model.myschema
myschema.mytable
Run Code Online (Sandbox Code Playgroud)
错误:
java.lang.RuntimeException: Could not deduce Option[] type of field 'field1' of class org.mycompany.myproject.model.myotherclass
Run Code Online (Sandbox Code Playgroud)
正如我所料,无论我尝试在该架构上调用什么方法,都会弹出错误.
现在,这是我的架构在该表声明附近的样子:
object myschema extends Schema {
val myotherclasses = table[myotherclass]
val otherClassManyToMany = manyToManyRelation(yetanotherclass, mytables).
via[myotherclass]((e,ssr, sse) => (e.id === sse.leftId, sse.rightId === ssr.id))
...
}
Run Code Online (Sandbox Code Playgroud)
这是我的代码表的样子:
class myotherclass(
val rightId: Long,
val field1: Option[Long],
val field2: Option[Long],
val foreiginKey: Long,
val leftId: Long) extends KeyedEntity[CompositeKey2[Long, Long]] {
def id …Run Code Online (Sandbox Code Playgroud) 任何人都可以告诉我如何明确处理squeryl中的事务回滚?
还有我们如何动态添加或删除squeryl中的列?
感谢名单...
我正在尝试在查询中选择所有表.我必须指定一个where子句(或者我是tihnk),那么那里有什么?
def all() = transaction { from(AppDB.users)(s => where(WHAT GOES HERE?) select(s)).toIndexedSeq }
Run Code Online (Sandbox Code Playgroud) 我不确定squeryl在这里试图告诉我什么:
错误:无法证明org.squeryl.dsl.fsm.Unconditioned =:= org.squeryl.dsl.fsm.Conditioned.
上:
inTransaction {
update(AppDB.postTable) { p =>
where(p.id === postId)
set(p.upVotes := p.upVotes.~ + 1)
}
Run Code Online (Sandbox Code Playgroud)
错误发生在set子句中
模式:
object AppDB extends Schema {
val postTable = table[Post]("post")
val replyTable = table[Reply]("reply")
val postToReplies = oneToManyRelation(postTable, replyTable)
.via((p,r) => p.id === r.postId)
}
case class Post(body: String, image:Option[String]) extends KeyedEntity[Long] {
val id: Long = 0
val posted: Date = new Date()
var upVotes: Long = 0
var downVotes: Long = 0
}
case class Reply(postId: …Run Code Online (Sandbox Code Playgroud) 当我尝试使用Squeryl的Table.insert在PostgreSQL表中插入新记录时,它会触发此查询:
insert into "users" ("id", "email", "fullname") values (nextval('"s_users_id"'),?,?)
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为我没有定义序列,而是将id列定义为"autoincrement":
CREATE TABLE Users (
id BIGSERIAL,
email varchar(255) NOT NULL,
fullname varchar(255),
PRIMARY KEY (id)
);
Run Code Online (Sandbox Code Playgroud)
我在另一个论坛上读到了一些关于这个问题的老帖子,我想知道现在的状态.我们不鼓励使用自动增量并定义序列吗?或者有一个简单的解决方法来使这个工作?
编辑:事实上我刚才看到自动增量本身创建了一个序列,但是在另一个名称下:users_id_seq有没有办法告诉Squeryl看这个名字,或者遵循PostgreSQL的约定?
如何在squeryl模式中组合列中的唯一约束?
A | B
2 1 allow
2 3 allow
3 1 allow
2 1 don't allow same with row one
Run Code Online (Sandbox Code Playgroud) 这可能是由于我对 Squeryl 的工作方式的误解。我的实体定义为:
case class Wallet(userid: Int, amount: Long)
extends KeyedEntity[Int] with Optimistic {
def id = userid
}
Run Code Online (Sandbox Code Playgroud)
我的表变量定义为:
val walletTable = table[Wallet]("wallets")
on(walletTable) {
w =>
declare {
w.userid is (primaryKey)
}
}
Run Code Online (Sandbox Code Playgroud)
然后我只是调用一个方法来尝试向钱包中添加钱:
val requestedWallet = wallet.copy(amount = wallet.amount + amount)
try {
inTransaction {
walletTable.update(requestedWallet)
}
Run Code Online (Sandbox Code Playgroud)
在我调用更新的那一行,抛出一个异常: [ClassCastException: java.lang.Integer cannot be cast to org.squeryl.dsl.CompositeKey]
我根本没有使用复合键,所以这很令人困惑。这是否与我的 id 字段不被称为“id”,而是“userid”这一事实有关?