我在HQL中代表以下MySQL查询
SELECT t1.id as user_id, t2.id as follow_id
FROM user t1
INNER JOIN follows t2 ON
(t2.follower_id = <user id> AND t2.followee_id = t1.id) OR
(t2.follower_id = t1.id AND t2.followee_id = <user id>)
WHERE t1.active = true
ORDER BY t1.id
你能帮我解决一下这个问题吗?
谢谢!
修改
到目前为止,我已尝试过以下HQL查询,但无法返回正确的数据:
SELECT t1
FROM User t1
JOIN t1.follows t2
JOIN t2.follower follower
JOIN t2.followee followee
WHERE (follower.id = :usr AND followee.id = t1.id) OR
(follower.id = t1.id AND followee.id = :usr)
AND t1.active = true
ORDER BY t1.id
我的想法是我有两张桌子:
User table: +------+--------+-------------+ | id | name | last_name | +------+--------+-------------+ | 1 | Jhon | Doe | | 2 | Jane | Doe | | 3 | Alfred | Hitchcock | +------+--------+-------------+
Follows table: +------+-------------+-------------+ | id | follower_id | followee_id | +------+-------------+-------------+ | 1 | 1 | 3 | | 2 | 3 | 2 | | 3 | 2 | 1 | +------+-------------+-------------+
我需要的是,例如,获取所有关注或被关注的用户的姓名和名字,例如,用户ID 1。
我发布的SQL查询就是这样做的,但我似乎无法在HQL中复制相同的行为。
第二次编辑: 我的简化域类是:
class User {
String name
String lastName
...
static hasMany = [ follows: Follows ]
static mappedBy = [ follows: 'follower' ]
}
和...
class Follows {
User Followee
...
static belongsTo = [follower: User]
}
答案 0 :(得分:1)
在编写HQL查询时要记住的重要一点是域类加入(HQL处理域类,而不是表)完全依赖于域类关联。换句话说,关联实际上创建了(内部)连接,但是HQL允许您更改连接类型(LEFT OUTER,RIGHT OUTER和Cartesian)。请参阅我的from clause文章。
我尝试从您的HQL和表格描述中获取您的域类关联,但它并不匹配。但这是另一种方法。
域模型非常简单。那个&#39; sa User
类包含一对多与自身的关联(但它不是自我加入,因为你会在力矩)。
class User {
String name
String lastName
static hasMany = [followees: User]
}
假设您有User
个实例。
def user = User.get(1)
user.followees
包含User
后跟 user
。
使用这样的域模型,表格看起来像这样:
+------+--------+-------------+
| id | name | last_name |
+------+--------+-------------+
| 1 | John | Doe |
| 2 | Jane | Doe |
| 3 | Alfred | Hitchcock |
+------+--------+-------------+
+-----------+-------------------+
| user_id | followees_user_id |
+-----------+-------------------+
| 1 | 2 |
| 3 | 1 |
+-----------+-------------------+
所展示的数据表明:
这个简单的一对多关联可用于建模双向关系,即跟随。使用两个一对多关联也可以完成相同的操作,这将简化查询,但会使数据维护变得复杂。使用此模型,双向以下关系将使用单个user.addToFollowee()
或user.removeFromFollowee()
进行维护。
使用我描述的域模型,您可以查询被关注者和关注者。给定user
...
def followees = user.followees // <-- contains Jane Doe
def followers = User.executeQuery
'SELECT u FROM User as u INNER JOIN u.followees as followee WHERE followee = :user',
[user: user] // <-- contains Alfred Hithchcock
def following = followees + followers
请注意,GORM / Hibernate不支持SQL的 UNION 子句,因此您需要两个查询。有关GORM等效于where子句的更多详细信息,请参阅我的where clause文章。
还可以使用 where 或条件查询来获取关注者:
def followers = User.where { followees.id == user.id }.list()
def followers = User.withCriteria { followees { eq 'id', user.id } }
答案 1 :(得分:1)
仅仅是为了简单起见,因为我只是在阅读数据,所以我最终使用Grails接受的Groovy SQL,并且本身接受我原始帖子中包含的简单SQL查询(并且不需要匹配任何特定的域模型,在这种情况下对我来说很重要)
这里是JavaDoc的链接,我特意使用行(String sql,Map params)方法定义来查询de DB并返回我正在搜索的数据。
为了在Grails中使用groovy.sql.Sql,我建议将它作为bean添加到resources.groovy文件中:
beans = {
groovySql(groovy.sql.Sql, ref('dataSource'))
}
然后将其注入您想要使用的地方:
class MyService {
def groovySql
...
def myMethod() {
String query = "SELECT * FROM user WHERE ..."
Map params = [param1: p1]
List<GroovyRowResult> result = groovySql.rows(query, params)
...
}
}
希望这可以帮助任何尝试执行纯SQL查询的人,而无需将其转换为HQL或Criteria。