我想知道是否有办法在Liftweb中使用Mapper进行一些复杂的SQL查询。
实际上,我想要做的是从数据库雇员和部门执行加入查询,使用它们通过1对多关系链接的事实。 另一个例子也是受欢迎的。
提前致谢。
以下是一些更多细节:假设我有2个表:
Employee : birthday, department ID, salary
Department : department ID, budget, address
现在我想获得一个对象Employee
(使用Mapper创建)的列表,其中包含salary > 10$
和department budget < 100$
。
当然我的原始代码要复杂得多,但我的目标是能够拥有一个映射对象列表(即Employee
),对应于自己的表或链接表中的标准。
答案 0 :(得分:4)
我看了这个。看起来好像是在对象层中完成了连接。
从http://exploring.liftweb.net/master/index-8.html推断到您的案例:
// Accessing foreign objects
class Employee extends LongKeyedMapper[Employee] with IdPK {
...
object department extends MappedLongForeignKey(this, Department)
def departmentName =
Text("My department is " + (department.obj.map(_.name.is) openOr "Unknown"))
}
class Department ... {
...
def entries = Employee.findAll(By(Employee.department, this.id))
}
如果你想做多对多的映射,你需要自己提供 “连接”类,其中包含两个映射实体的外键。
// DepartmentId Entity
class DepartmentId extends LongKeyedMapper[DepartmentId] with IdPK {
def getSingleton = DepartmentId
object name extends MappedString(this,100)
}
object DepartmentId extends DepartmentId with LongKeyedMetaMapper[DepartmentId] {
override def fieldOrder = List(name)
}
接下来,我们定义我们的连接实体,如下所示
它就像其他实体一样是LongKeyedMapper,
但它只包含其他实体的外键字段。
// Join Entity
class DepartmentIdTag extends LongKeyedMapper[DepartmentIdTag] with IdPK {
def getSingleton = DepartmentIdTag
object departmentid extends MappedLongForeignKey(this,DepartmentId)
object Employee extends MappedLongForeignKey(this,Employee)
}
object DepartmentIdTag extends DepartmentIdTag with LongKeyedMetaMapper[DepartmentIdTag] {
def join (departmentid : DepartmentId, tx : Employee) =
this.create.departmentid(departmentid).Employee(tx).save
}
要使用连接实体,您需要创建一个新实例并设置
适当的外键指向关联的实例。如你所见,
我们在Expense元对象上定义了一个方便的方法来做到这一点
为了使多对多可以作为我们实体的字段访问,我们可以使用
HasManyThrough trait,如下所示
// HasManyThrough for Many-to-Many Relationships
class Employee ... {
object departmentids extends HasManyThrough(this, DepartmentId,
DepartmentIdTag, DepartmentIdTag.departmentid, DepartmentIdTag.Employee)
}
答案 1 :(得分:1)
我注意到部门拼写有两种方式: DEPARTEMENT 系
也许映射器不知道如何列出来自连接操作的*结果 您是否尝试过以下
SELECT
e.birthday as birthDay ,
e.departmentId as departmentId ,
e.salary as salary
FROM
Employee e
INNER JOIN Department d
ON e.departmentId = d.departmentId
WHERE
d.budget < 100 AND
e.salary > 10
免责声明:我有使用Mapper / Lift的经验,但我确实具有将查询结果集映射到Borland C ++ Builder,Delphi和Java中的对象的经验。其中一些基于对象的系统是错误的,无法将SELECT *扩展到所有字段,因此您需要明确告诉他们要获取哪些字段。
在你的情况下,你有e.departmentId和d.departmentId可能会混淆Mapper而不知道哪个是*中的真实departmentId。有些系统实际上会返回departmentId和departmentId_1(默认情况下,这个系统会将_1加到最后) 其他系统只是挂起,出错,有不可预测的行为。
我也看到终止存在或不存在';'最终的字符在一些固定的SQL应用程序中是一个问题。
答案 2 :(得分:1)
您始终可以使用exec或runQuery运行您喜欢的任何查询: http://scala-tools.org/mvnsites/liftweb-2.4-M1/#net.liftweb.db.DB 虽然你也可以在Mapper中进行连接。
您可以使用OneToMany或ManyToMany特征
要使用ManyToMany,请添加连接字段。请参阅示例代码:
class Meeting extends LongKeyedMapper[Meeting] with IdPK with CreatedUpdated with OneToMany[Long, Meeting] with ManyToMany {
def getSingleton = Meeting
object owner extends MappedLongForeignKey(this, User)
object title extends MappedString(this, 100)
object beginDate extends MappedDateTime(this)
object endDate extends MappedDateTime(this)
object location extends MappedString(this,100)
object description extends MappedText(this)
object allDay extends MappedBoolean(this)
object users extends MappedManyToMany(MeetingUser, MeetingUser.meeting, MeetingUser.user, User)
object contacts extends MappedManyToMany(MeetingContact, MeetingContact.meeting, MeetingContact.contact, Contact)
}
以下是加入实体。
class MeetingContact extends LongKeyedMapper[MeetingContact] with IdPK with CreatedUpdated {
def getSingleton = MeetingContact
object meeting extends MappedLongForeignKey(this, Meeting)
object contact extends MappedLongForeignKey(this, Contact)
}
object MeetingContact extends MeetingContact with LongKeyedMetaMapper[MeetingContact] {
def join(m: Meeting, c: Contact) = this.create.meeting(m).contact(c).save
def assignedTo(c: Contact) = this.findAll(By(MeetingContact.contact, c)).filter(_.meeting.obj.isDefined).map(_.meeting.obj.open_!)
override def beforeCreate() = MailSender.sendInviteToMeetingContact _ :: super.beforeCreate
}
答案 3 :(得分:-1)
嗯,我对Liftweb mapper一无所知,但就SQL而言,它看起来像是:
select e.birthday, e.department_id, e.salary from
employee e left join department d on d.department_id=e.department_id
where d.budget>100 and e.salary>10;
答案 4 :(得分:-1)
SQL如下。
SELECT *
FROM Employee e
INNER JOIN Department d
ON e.departmentId = d.departmentId
WHERE d.budget < 100 AND e.salary > 10