简体   繁体   中英

Return Query Results To The View In Grails

I would like to execute a sql statement and return the results to a view in Grails. To clarify, I'm not trying to return domain objects and display them on a view. I have a simple query where I am joining two tables and I just want to pass the results to the view for display.

Here is the code in my view:

<%@ 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>

Here is the code in my Controller:

    //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]

When I run this I see the following in the console so I know that returnList has the result list from the query:

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 is behaving like it's looking for a domain object (edu.unm.processindicator.Sfrwdrl) and I'm trying to display a value from the returnList (and those are not domain objects). And I know that returnList array has values because this is what I see when it prints the output to the console before the return statement:

[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]

If I can be routed to some concrete examples that show how to return query results and display them in a view that would be very much appreciated. Or... am I just going about this all wrong and I need to define one to many relationships in my domain objects if I want to display information from more than one table? Is what I'm trying to do even possible in Grails? I've done a bunch of searches and been looking at the tags info in the Grails documenation but I am having trouble finding an answer. Thanks in advance!

First, your question that you pose in your comment about "Can Grails actually return simple query results?". The answer to this is: Absolutely, yes.

Using Groovy's Sql class you can do this quite easily. However, it appears that you are making things more difficult for yourself.

Starting with the fact your building the SQL in a manner which is prone to SQL injection. I highly recommend you consider using at least a GString and doing variable substitution.

Next, there is no need to put the query results into returnList in your example. Simply calling .executeQuery and returning the ResultSet to your GSP is something to consider.

Finally, displaying the results in your GSP. Given your non-standard bean name columns that are in your results it's best you refer to them using quotes when accessing them from the ResultSet. For example:

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

This way there isn't any confusion about what you want Groovy to do. Simply access the property by that name.

In summary, Yes Grails can be used when dealing with 3rd party or legacy databases where using an ORM isn't possible or desirable. I personally have had great success in doing so.

I discovered that my code does work. The error that I was getting was the following:

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

The Controller code that I originally posted was an shortened version of what I was actually doing. I was originally using the returnList Array to grab domain objects:

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)
        }

    }         

I then ended up reusing that returnList in the code above. In the code above I am defining the variable, but in my original code I thought that doing the following would clear out the array so I could reuse it:

returnList = []

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

            println 'Here are the results!'
            println returnResults

            sqlStatement.close()

            return [returnMap: returnResults]

When that ArrayList was originally created, I'm thinking it's type must have been of my domain object(edu.unm.processindicator.Sfrwdrl). I then mistakenly placed the query results in that list (which are of the GroovyRowResult type.

Sending the returnList Array(which was of type Sfrwdrl) to the view with GroovyRowResult objects inside of it is what was causing the problem. The view expected the objects to be of type Sfrwdrl (my domain objects).

I'm now seeing my query results in the view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM