2015-12-02 34 views
1

我需要调用一些存储过程来返回它们自己的记录,这些记录并不直接映射到表或视图。如何在Grails中建模存储过程记录?

我已经在过去使用存储过程与groovy.sql.Sql和平原(未建模)地图,但对于这个应用程序,我想这些记录有一个类似于域类,模型,以定义的数据类型,数据绑定,校验,与其他实体的关联等等。

什么是这样做的最佳方法是什么?

我应该将存储过程记录建模为适当的域类(实体),然后尝试禁用(或重新定义)其数据库持久性?怎么样?

我应该在使用非域名POJO的情况下选择性地启用我需要的功能吗? (如使用@Validatable进行验证)那么我如何处理关联? (当从SP返回的记录包含某个其他持久实体的外键时,会出现关联。)

回答

5

如果希望以简单的方式维护数据绑定,验证和关联,那么您应该使用域方法。

要禁用域类的数据库持久性,您可以将static mapWith = "none"添加到域类,并且不会为该域类创建表。

样品实体类:

@ToString 
public class SPTest { 

    Long idField 

    User user 

    GroupIntegrationKey integrationKey 

    static constraints = { 
    } 

    static mapWith = "none" 
} 

存储过程语句:

SELECT ID作为idField,USER_ID AS用户,键integrationKey FROM my_domain;

为了将SP的结果映射到实体,您可以使用结果变换器。

Query query = session.createSQLQuery("CALL getSPData()"); 

List<Map> results = query.with { 
    resultTransformer = AliasToEntityMapResultTransformer.INSTANCE 
    list() 
} 

现在遍历列表,并创建一个新的实体对象

List<MyDomain> list = results.collect { 
    new MyDomain(it) 
} 

System.err.println(list) 

缺点:

  1. 不能映射标识符字段
  2. 你将不得不再次遍历结果创建实体对象
  3. 您无法映射hasMany关系

如果你想要pojo,那么在这种情况下,你将不得不创建你自己的getter版本来获得关联的对象。

+0

谢谢!我会试试这个。有一件事:为什么我不能映射ID字段? – Tobia

+0

在域构造函数中使用map绑定数据时,它不会自动绑定id字段。作为其标识符,应自动分配或使用正确的id生成策略。但是你可以尝试使用setter来设置它。 –

+0

@SandeepPoonia优秀的答案! +1 –