在Liftweb中使用Join的复杂SQL查询

在Liftweb中使用Join的复杂SQL查询,sql,scala,lift,Sql,Scala,Lift,我想知道是否有一种方法可以使用Liftweb中的Mapper进行一些复杂的SQL查询 事实上,我想做的是使用数据库员工和部门通过一对多关系链接的事实,从数据库中执行联接查询。 另一个例子也值得欢迎 提前谢谢 下面是一些更详细的信息:假设我有两个表: Employee : birthday, department ID, salary Department : department ID, budget, address 现在,我想获取对象员工(使用Mapper创建)的列表,该对象的工资>10

我想知道是否有一种方法可以使用Liftweb中的Mapper进行一些复杂的SQL查询

事实上,我想做的是使用数据库员工和部门通过一对多关系链接的事实,从数据库中执行联接查询。 另一个例子也值得欢迎

提前谢谢


下面是一些更详细的信息:假设我有两个表:

Employee : birthday, department ID, salary
Department : department ID, budget, address
现在,我想获取对象
员工
(使用Mapper创建)的列表,该对象的
工资>10美元
,部门预算<100美元


当然,我的原始代码要复杂得多,但我的目标是能够在自己的表或链接表中有一个对应于标准的映射对象列表(即
Employee

我对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;
SQL语句如下所示

SELECT * 
FROM Employee e 
    INNER JOIN Department d 
        ON e.departmentId = d.departmentId
WHERE d.budget < 100 AND e.salary > 10
选择*
来自雇员e
内联d部
在e.departmentId=d.departmentId上
其中d.预算<100,e.工资>10

我注意到department有两种拼写方式: 部门 系

也许映射程序不知道如何列出联接操作的*结果
你试过下列方法吗

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
选择
e、 生日就是生日,
e、 部门ID作为部门ID,
e、 以薪代薪
从…起
雇员e
内联d部
在e.departmentId=d.departmentId上
哪里
d、 预算<100和
e、 工资>10
免责声明:我没有使用Mapper/Lift的经验,但我有在Borland C++Builder、Delphi和Java中将查询结果集映射到对象的经验。其中一些基于对象的系统存在缺陷,无法将SELECT*扩展到所有字段,因此需要明确告诉它们要获取哪些字段

在您的例子中,您有e.departmentId和d.departmentId,这可能会混淆映射程序,使其不知道*中哪个是真正的departmentId。有些系统实际上会返回departmentId和departmentId_1(默认情况下,这个系统会将_1固定到末尾) 其他系统只是挂起、出错,具有不可预测的行为


我也看到了终止的存在与否在一些罐装SQL应用程序中,结尾字符可能是一个问题。

我已经查过了。看起来好像连接是在对象层中完成的

根据您的案例推断:

// 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))  
}  
如果要进行多对多映射,则需要提供自己的映射
使用外键将“join”类“join”到两个映射的实体

// 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)  
}  
接下来,我们定义我们的连接实体,如下所示。
与其他实体一样,它是一个长键的外观,
但它只包含其他实体的外键字段

// 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  
}  
要使用连接实体,您需要创建一个新实例并设置
适当的外键指向关联的实例。如您所见,
我们已经在我们的费用元对象上定义了一个方便的方法来实现这一点。
要使多对多作为实体上的字段进行访问,我们可以使用
具有许多大致特征,如下所示

// HasManyThrough for Many-to-Many Relationships  
class Employee ... {  
  object departmentids extends HasManyThrough(this, DepartmentId,   
    DepartmentIdTag, DepartmentIdTag.departmentid, DepartmentIdTag.Employee)  
}  

您始终可以使用exec或runQuery运行任何查询: 尽管您也可以在Mapper中进行连接

你可以使用或特征

若要使用多个字段,请放置联接字段。请参见示例代码:

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
}

它们是两个数据库还是两个表?对不起,我说的是两个表。然而,我通过在员工和部门之间建立多对多连接找到了解决方案。然后,我对员工进行请求,并在列表中筛选我希望从部门获得的选项。不过,如果您有完整的SQL解决方案,我将不胜感激。学习查询的最佳场所是[wiki]()。我很高兴你有一些有用的东西。你能提供一个你希望看到的结果集类型的例子吗?我想得到一个员工列表。我的目标是能够使用lift结构执行一些复杂的join-SQL查询。SQL部分不是问题,我尝试构建一个最简单的示例,可能太简单了。但是非常感谢你的帮助@ChrisJamesC:问题是连接依赖于数据吗?你是否需要根据数据进行不同的联接?@chris老实说,我不知道,当我在phpmyadmin上执行请求时,它会工作,而当我想在Scala中执行请求时,联接不会工作。非常感谢你非常完整的回答,阅读你提供的资料,我发现这一章也会有所帮助:我会做一些测试,如果它对我有用的话,我会发布一个答案。不过,你的答案非常有趣,肯定会帮助很多SO用户。谢谢你的打字错误,我是法国人,部门用法语拼写为department:)谢谢你的完整查询。嗨,你能扩展你的答案吗?对不起,花了这么长时间,扩展:)