2014-07-15 16 views
0

我想执行一个sql语句并将结果返回到Grails中的视图。为了澄清,我没有试图返回域对象并将它们显示在视图上。我有一个简单的查询,我加入了两个表格,我只想将结果传递给视图进行显示。将查询结果返回到Grails中的视图

这里是我的看法代码:

<%@ page contentType="text/html;charset=UTF-8" %> 
<html> 
<head> 
    <meta name='layout' content='main'/> 
    <title></title> 
</head> 

<body> 

<div id = 'overall'> 


    <g:if test="${queryResultMap.size() > 0}"> 

    <table border="1"> 

     <thead> 
     <tr> 
      <th>Banner ID</th> 
      <th>PIDM</th> 
      <th>Term</th> 
      <th>Processed Indicator</th> 
     </tr> 
     </thead> 
     <tbody> 
     <g:each in="${queryResultMap}" status="i" var="thisRecord"> 
      <tr> 
       <td>${thisRecord.SPRIDEN_ID}</td> 
       <td>${thisRecord.SFRWDRL_PIDM}</td> 
       <td>${thisRecord.SFRWDRL_TERM_CODE}</td> 
       <td>${thisRecord.SFRWDRL_PROCESSED_IND}</td> 
      </tr> 

     </g:each> 
     </tbody> 

    </table> 
    </g:if> 
    <g:else> 
     No records were found to update. 
    </g:else> 



</div> 

</body> 
</html> 

这里是我的控制器代码:

//Create our database connection... 
    Sql sqlStatement = new Sql(dataSource) 

    //Here is my simple query 
    def sqlString = 
      "SELECT S.SPRIDEN_ID, " + 
        "D.SFRWDRL_PIDM, " + 
        "D.SFRWDRL_PROCESSED_IND, " + 
        "D.SFRWDRL_USER, " + 
        "D.SFRWDRL_USER_ID, " + 
        "D.SFRWDRL_ACTIVITY_DATE, " + 
        "D.SFRWDRL_TERM_CODE " + 
      "FROM SATURN.SPRIDEN S, SATURN.SFRWDRL D \n" + 
        "WHERE S.SPRIDEN_PIDM = \'" + pidm + "\' " + 
        "AND S.SPRIDEN_CHANGE_IND IS NULL " + 
        "AND S.SPRIDEN_PIDM = D.SFRWDRL_PIDM " + 
        "AND D.SFRWDRL_TERM_CODE = '" + term + "\' " 

    def returnList = [] 

    //Put out query results into the queryResults array... 
    sqlStatement.eachRow(sqlString){ 
     returnList << it.toRowResult() 
    } 


    //Close our database connection... 
    sqlStatement.close() 


    println returnList 

    return [queryResultMap: returnList] 

当我运行这个我在控制台看到下面的,所以我知道returnList有查询的结果列表:

Error 500: Internal Server Error 

URI 
    /FinAid-WithdrawalProcessIndicatorUpdate/sfrwdrl/processWithdrawalIndicator 
Class 
    groovy.lang.MissingPropertyException 
Message 
    No such property: SPRIDEN_ID for class: edu.unm.processindicator.Sfrwdrl 

Grails表现得像是在寻找域对象(edu.unm.processindicator.Sfrwdrl),我试图显示一个来自returnList的值(而那些不是域对象)。我知道returnList阵列具有价值,因为这是我所看到的,当它打印输出到控制台return语句之前:

[SPRIDEN_ID:101638052, SFRWDRL_PIDM:1638080, SFRWDRL_PROCESSED_IND:Y, SFRWDRL_USER:P_SZPGF02_MAIN, SFRWDRL_USER_ID:null, SFRWDRL_ACTIVITY_DATE:2014-02-05 14:15:46.0, SFRWDRL_TERM_CODE:201410] 

如果我能排到显示如何返回查询结果一些具体的例子并将它们显示在非常赞赏的视图中。或者...我只是想说这些都是错误的,如果我想要显示来自多个表的信息,我需要在我的域对象中定义一对多关系。我在Grails中甚至有可能做到这一点?我做了一堆搜索,并一直在查看Grails文档中的标签信息,但我无法找到答案。提前致谢!

+0

如果这是两个表的简单查询,为什么使用SQL直接? –

+0

我组织即将开始使用Grails,现在我们正处于探索阶段,我们将使用我们未设计的供应商提供的数据库。我们希望通过许多连接执行复杂的查询。这个问题不仅仅是我问如何解决这个问题。我们需要知道Grails实际上是否可以返回简单的查询结果(而不是域对象),因为它会影响我们的开发人员代码的标准... –

回答

3

首先,您在您的评论中提出的关于“Can Grails实际上是否可以返回简单查询结果?”的问题。答案是:当然,是的。

使用Groovy的Sql class你可以很容易地做到这一点。但是,看起来你正在为自己制造困难。

从您以一种容易出现SQL注入的方式构建SQL开始。我强烈建议你考虑使用至少一个GString并进行变量替换。

接下来,在您的示例中没有必要将查询结果放入returnList。只需调用.executeQuery并将ResultSet返回给您的GSP即可。

最后,在您的GSP中显示结果。鉴于您的结果中包含非标准bean名称列,最好在从ResultSet访问它们时使用引号引用它们。例如:

<td>${thisRecord.'SPRIDEN_ID'}</td> 

这种方式对于您希望Groovy做什么没有任何困惑。只需通过该名称访问该房产。

总之,在处理使用ORM的第三方或旧数据库是不可能或不可取的情况下,可以使用是Grails。我个人在这方面取得了巨大的成功。

+0

谢谢Joshua - 当涉及到这个问题和您的建议时,我们就是nubes SQL注入 - 已经让我们看到了一些东西。感谢您花时间回复!我弄清楚根本问题是什么,并在下面发布。如果我真的发布了控制器的所有代码,我相信你会对我的错误置之不理。再次感谢。 –

0

我发现我的代码确实有效。我得到的错误如下:

Error 500: Internal Server Error 

URI 
    /FinAid-WithdrawalProcessIndicatorUpdate/sfrwdrl/processWithdrawalIndicator 
Class 
    groovy.lang.MissingPropertyException 
Message 
    No such property: SPRIDEN_ID for class: edu.unm.processindicator.Sfrwdrl 

我最初发布的控制器代码是我实际上做的事情的缩短版本。我原来用的是returnList阵列抢域对象:

private void updateSfrwdrlAndAddToList(pidm, unmId, term, ArrayList returnList) 
    { 
     def results 

     results = Sfrwdrl.where 
     { 
      sfrwdrlTermCode == term 
      sfrwdrlPidm == pidm 
      sfrwdrlProcessedInd == "Y" 
     } 

     for (i in results) 
     { 
      i.sfrwdrlProcessedInd = 'N' 
      i.sfrwdrlActivityDate = new Date() 
      i.sfrwdrlUserId = unmId 

      returnList.add(i) 
     } 

    }   

然后我结束了重复使用returnList在上面的代码。在上面的代码,我定义变量,但在我的原代码,我认为做以下的将清除出数组,所以我可以重复使用它:

returnList = [] 

sqlStatement.eachRow(sqlString){ 
       returnResults << it.toRowResult() 
      } 

      println 'Here are the results!' 
      println returnResults 

      sqlStatement.close() 

      return [returnMap: returnResults] 

当最初创建的ArrayList,我想它的类型必须是我的域对象(edu.unm.processindicator.Sfrwdrl)。然后我错误地将查询结果放在该列表中(这些列表是GroovyRowResult类型的)

将returnList Array(其类型为Sfrwdrl)发送到其中包含GroovyRowResult对象的视图是导致该问题的原因。鉴于预期的对象为类型Sfrwdrl(我的域对象)。

现在我看到在我的视图查询结果。