Grails:在域 class 中使用继承进行搜索
Grails: Search with inheritance in domain class
我的 Grails 应用程序中有这两个域模型
class Pet {
String prop1
String prop2
}
还有这个
class Cat extends Pet {
String prop3
String prop4
}
现在,在我的应用程序中,我有许多 类 正在扩展 Pets
,我想使用条件搜索 Pet
,指定一些其他宠物中不存在的属性。
我怎样才能使这个操作成为可能?如果我尝试进行搜索,当结果不包含 属性 时,引发异常。
我认为,你正在尝试的事情是不可能的。但是您可以使用两个查询来实现它:
首先做一个较低级别的查询:
// Inject the bean
def sessionFactory
String statement = "select id from pet where prop1 = 'foo' or prop3 = 'bar'";
def session = sessionFactory.getCurrentSession()
def queryResult = session.createSQLQuery(statement)
由于父 class Pet
将拥有所有字段,因此对任何字段进行上述较低级别的查询都可以。
现在,使用 id 获取域实例:
def pets = Pet.getAll(queryResult)
由于 object-oriented 编程的工作方式,您尝试做的事情是不可能的。
class Foo { }
class Bar extends Foo { }
在此示例中,Bar
的实例也是 Foo
。但是,Foo
的实例不是 Bar
。换句话说,super-class 不知道 它的子类类,而子类 知道 它的子类super-class.
回到您的示例,您无法从 Pet
访问 prop3
或 prop4
,因为它们不是 Pet
属性。
正在努力寻找解决方案
考虑到您的 类,我同意 Shashank Agrawal 的解决方案。 SQL(不是 HQL 或任何其他 GORM 查询)是通过查询 pet
table 访问所有属性(实际上是列)的唯一方法。当然,这假定您使用默认的 table-per-hierarchy 继承。它不适用于 table-per-subclass 继承。
鉴于 table-per-hierarchy 的假设意味着您已经在所有 Pet
的子 类 中接受可为 null 的属性。这是一个要求。所以,你能做的是
- 弃子类
- 将所有属性放入
Pet
- 在
Pet
中添加属性以指定宠物类型。
请注意,这基本上是 table-per-hierarchy 在数据库级别所做的。区别在于它不是继承,这使得所有属性都可以从 Pet
.
def pets = Pet.withCriteria { eq('prop3', 'whatever') }
我的 Grails 应用程序中有这两个域模型
class Pet {
String prop1
String prop2
}
还有这个
class Cat extends Pet {
String prop3
String prop4
}
现在,在我的应用程序中,我有许多 类 正在扩展 Pets
,我想使用条件搜索 Pet
,指定一些其他宠物中不存在的属性。
我怎样才能使这个操作成为可能?如果我尝试进行搜索,当结果不包含 属性 时,引发异常。
我认为,你正在尝试的事情是不可能的。但是您可以使用两个查询来实现它:
首先做一个较低级别的查询:
// Inject the bean
def sessionFactory
String statement = "select id from pet where prop1 = 'foo' or prop3 = 'bar'";
def session = sessionFactory.getCurrentSession()
def queryResult = session.createSQLQuery(statement)
由于父 class Pet
将拥有所有字段,因此对任何字段进行上述较低级别的查询都可以。
现在,使用 id 获取域实例:
def pets = Pet.getAll(queryResult)
由于 object-oriented 编程的工作方式,您尝试做的事情是不可能的。
class Foo { }
class Bar extends Foo { }
在此示例中,Bar
的实例也是 Foo
。但是,Foo
的实例不是 Bar
。换句话说,super-class 不知道 它的子类类,而子类 知道 它的子类super-class.
回到您的示例,您无法从 Pet
访问 prop3
或 prop4
,因为它们不是 Pet
属性。
正在努力寻找解决方案
考虑到您的 类,我同意 Shashank Agrawal 的解决方案。 SQL(不是 HQL 或任何其他 GORM 查询)是通过查询 pet
table 访问所有属性(实际上是列)的唯一方法。当然,这假定您使用默认的 table-per-hierarchy 继承。它不适用于 table-per-subclass 继承。
鉴于 table-per-hierarchy 的假设意味着您已经在所有 Pet
的子 类 中接受可为 null 的属性。这是一个要求。所以,你能做的是
- 弃子类
- 将所有属性放入
Pet
- 在
Pet
中添加属性以指定宠物类型。
请注意,这基本上是 table-per-hierarchy 在数据库级别所做的。区别在于它不是继承,这使得所有属性都可以从 Pet
.
def pets = Pet.withCriteria { eq('prop3', 'whatever') }