来自Grails的INNER JOIN HQL查询

时间:2011-10-25 17:02:49

标签: sql grails hql

我正在试图弄清楚如何使这段代码工作:

def searchString = unchecked.join(",");
        searchString = searchString.replace("\"", "'")
        println("searchString: " + searchString);

        def matches=Employee.executeQuery("select e.id from Employee as e INNER JOIN Education as ed ON e.id = ed.employee_id INNER JOIN education_type AS et ON et.id = ed.type_id WHERE et.name  in (" +searchString + ")");

这是传递给executeQuery的查询字符串

select e.id from Employee as e INNER JOIN Education as ed ON e.id = ed.employee_id INNER JOIN education_type AS et ON et.id = ed.type_id WHERE et.name  in ('AA','BS')

我可以在SQL Server中运行并返回正确的结果,但我的grails代码抱怨:

Stacktrace follows:
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ON near line 1, column 59 [select e.id from Employee as e INNER JOIN Education as ed ON e.id = ed.employee_id INNER JOIN education_type AS et ON et.id = ed.type_id WHERE et.name  in ('AA','BS')]

那么我做错了什么?它是执行查询的错误域对象吗?

2 个答案:

答案 0 :(得分:2)

考虑这样做:

def employee = Employee.withCriteria {
    education {
        educationType {
            in("name", ["AA", "BS"])
        }
    }
}

答案 1 :(得分:0)

HQL与标准SQL略有不同。假设Hibernate知道这些对象之间的关系,您可以将查询简化为

List<String> typeNames = unchecked.collect { it.replace("\"", "") }
String query = """FROM Employee e
                  WHERE e.education.educationType.name IN (:typeNames)"""
List<Employee> = Employee.executeQuery(query, [typeNames: typeNames])

在查询中使用命名参数或位置参数以防止sql注入非常重要。此外,如果您真的只想要一个员工ID列表而不是实例,您可以将SELECT e.id放回去。也没有理由包含引号,因为当params绑定时,它们将使用您正在使用的数据库的正确引号,因为上面的代码片段也会删除引号,但您可能会重新考虑甚至让它们包含在第一名。