Save This Page
Home » groovy-src-1.6.5 » groovy » sql » [javadoc | source]
groovy.sql
public class: Sql [javadoc | source]
java.lang.Object
   groovy.sql.Sql

Direct Known Subclasses:
    DataSet

A facade over Java's normal JDBC APIs providing greatly simplified resource management and result set handling. Under the covers the facade hides away details associated with getting connections, constructing and configuring statements, interacting with the connection, closing resources and logging errors. Special features of the facade include using closures to iterate through result sets, a special GString syntax for representing prepared statements and treating result sets like collections of maps with the normal Groovy collection methods available.

The class provides numerous extension points for overriding the facade behavior associated with the various aspects of managing the interaction with the underlying database.

Nested Class Summary:
abstract protected class  Sql.AbstractQueryCommand   
protected final class  Sql.PreparedQueryCommand   
protected final class  Sql.QueryCommand   
Field Summary
protected static  Logger log    Hook to allow derived classes to access the log 
public static final  OutParameter ARRAY     
public static final  OutParameter BIGINT     
public static final  OutParameter BINARY     
public static final  OutParameter BIT     
public static final  OutParameter BLOB     
public static final  OutParameter BOOLEAN     
public static final  OutParameter CHAR     
public static final  OutParameter CLOB     
public static final  OutParameter DATALINK     
public static final  OutParameter DATE     
public static final  OutParameter DECIMAL     
public static final  OutParameter DISTINCT     
public static final  OutParameter DOUBLE     
public static final  OutParameter FLOAT     
public static final  OutParameter INTEGER     
public static final  OutParameter JAVA_OBJECT     
public static final  OutParameter LONGVARBINARY     
public static final  OutParameter LONGVARCHAR     
public static final  OutParameter NULL     
public static final  OutParameter NUMERIC     
public static final  OutParameter OTHER     
public static final  OutParameter REAL     
public static final  OutParameter REF     
public static final  OutParameter SMALLINT     
public static final  OutParameter STRUCT     
public static final  OutParameter TIME     
public static final  OutParameter TIMESTAMP     
public static final  OutParameter TINYINT     
public static final  OutParameter VARBINARY     
public static final  OutParameter VARCHAR     
Constructor:
 public Sql(DataSource dataSource) 
    Constructs an SQL instance using the given DataSource. Each operation will use a Connection from the DataSource pool and close it when the operation is completed putting it back into the pool.
    Parameters:
    dataSource - the DataSource to use
 public Sql(Connection connection) 
    Constructs an SQL instance using the given Connection. It is the caller's responsibility to close the Connection after the Sql instance has been used. You can do this on the connection object directly or by calling the Connection#close() method.
    Parameters:
    connection - the Connection to use
 public Sql(Sql parent) 
Method from groovy.sql.Sql Summary:
ARRAY,   BIGINT,   BINARY,   BIT,   BLOB,   BOOLEAN,   CHAR,   CLOB,   DATALINK,   DATE,   DECIMAL,   DISTINCT,   DOUBLE,   FLOAT,   INTEGER,   JAVA_OBJECT,   LONGVARBINARY,   LONGVARCHAR,   NULL,   NUMERIC,   OTHER,   REAL,   REF,   SMALLINT,   STRUCT,   TIME,   TIMESTAMP,   TINYINT,   VARBINARY,   VARCHAR,   asList,   asSql,   cacheConnection,   cacheStatements,   call,   call,   call,   call,   call,   close,   closeResources,   closeResources,   commit,   configure,   createConnection,   createPreparedQueryCommand,   createQueryCommand,   dataSet,   dataSet,   eachRow,   eachRow,   eachRow,   eachRow,   execute,   execute,   execute,   executeInsert,   executeInsert,   executeInsert,   executePreparedQuery,   executeQuery,   executeUpdate,   executeUpdate,   executeUpdate,   expand,   findWhereKeyword,   firstRow,   firstRow,   firstRow,   getConnection,   getDataSource,   getParameters,   getResultSetConcurrency,   getResultSetHoldability,   getResultSetType,   getUpdateCount,   in,   inout,   isCacheStatements,   loadDriver,   newInstance,   newInstance,   newInstance,   newInstance,   newInstance,   newInstance,   nullify,   out,   query,   query,   query,   resultSet,   rollback,   rows,   rows,   rows,   rows,   setCacheStatements,   setInternalConnection,   setObject,   setParameters,   setResultSetConcurrency,   setResultSetHoldability,   setResultSetType,   withBatch,   withStatement,   withTransaction
Methods from java.lang.Object:
clone,   equals,   finalize,   getClass,   hashCode,   notify,   notifyAll,   toString,   wait,   wait,   wait
Method from groovy.sql.Sql Detail:
 public static InParameter ARRAY(Object value) 
 public static InParameter BIGINT(Object value) 
 public static InParameter BINARY(Object value) 
 public static InParameter BIT(Object value) 
 public static InParameter BLOB(Object value) 
 public static InParameter BOOLEAN(Object value) 
 public static InParameter CHAR(Object value) 
 public static InParameter CLOB(Object value) 
 public static InParameter DATALINK(Object value) 
 public static InParameter DATE(Object value) 
 public static InParameter DECIMAL(Object value) 
 public static InParameter DISTINCT(Object value) 
 public static InParameter DOUBLE(Object value) 
 public static InParameter FLOAT(Object value) 
 public static InParameter INTEGER(Object value) 
 public static InParameter JAVA_OBJECT(Object value) 
 public static InParameter LONGVARBINARY(Object value) 
 public static InParameter LONGVARCHAR(Object value) 
 public static InParameter NULL(Object value) 
 public static InParameter NUMERIC(Object value) 
 public static InParameter OTHER(Object value) 
 public static InParameter REAL(Object value) 
 public static InParameter REF(Object value) 
 public static InParameter SMALLINT(Object value) 
 public static InParameter STRUCT(Object value) 
 public static InParameter TIME(Object value) 
 public static InParameter TIMESTAMP(Object value) 
 public static InParameter TINYINT(Object value) 
 public static InParameter VARBINARY(Object value) 
 public static InParameter VARCHAR(Object value) 
 protected List<GroovyRowResult> asList(String sql,
    ResultSet rs) throws SQLException 
    Hook to allow derived classes to override list of result collection behavior. The default behavior is to return a list of GroovyRowResult objects corresponding to each row in the ResultSet.
 protected String asSql(GString gstring,
    List<Object> values) 
    Hook to allow derived classes to override sql generation from GStrings.
 public synchronized  void cacheConnection(Closure closure) throws SQLException 
    Caches the connection used while the closure is active. If the closure takes a single argument, it will be called with the connection, otherwise it will be called with no arguments.
 public synchronized  void cacheStatements(Closure closure) throws SQLException 
    Caches every created preparedStatement in Closure closure
    Every cached preparedStatement is closed after closure has been called. If the closure takes a single argument, it will be called with the connection, otherwise it will be called with no arguments.
 public int call(String sql) throws Exception 
    Performs a stored procedure call.

    Example usage (tested with MySQL) - suppose we have the following stored procedure:

    sql.execute """
        CREATE PROCEDURE HouseSwap(_first1 VARCHAR(50), _first2 VARCHAR(50))
        BEGIN
            DECLARE _loc1 INT;
            DECLARE _loc2 INT;
            SELECT location_id into _loc1 FROM PERSON where firstname = _first1;
            SELECT location_id into _loc2 FROM PERSON where firstname = _first2;
            UPDATE PERSON
            set location_id = case firstname
                when _first1 then _loc2
                when _first2 then _loc1
            end
            where (firstname = _first1 OR firstname = _first2);
        END
    """
    
    then you can invoke the procedure as follows:
    def rowsChanged = sql.call("{call HouseSwap('Guillaume', 'Paul')}")
    assert rowsChanged == 2
    
 public int call(GString gstring) throws Exception 
    Performs a stored procedure call with the given embedded parameters.

    Example usage - see #call(String) for more details about creating a HouseSwap(IN name1, IN name2) stored procedure. Once created, it can be called like this:

    def p1 = 'Paul'
    def p2 = 'Guillaume'
    def rowsChanged = sql.call("{call HouseSwap($p1, $p2)}")
    assert rowsChanged == 2
    
 public int call(String sql,
    List<Object> params) throws Exception 
    Performs a stored procedure call with the given parameters.

    Example usage - see #call(String) for more details about creating a HouseSwap(IN name1, IN name2) stored procedure. Once created, it can be called like this:

    def rowsChanged = sql.call("{call HouseSwap(?, ?)}", ['Guillaume', 'Paul'])
    assert rowsChanged == 2
    
 public  void call(GString gstring,
    Closure closure) throws Exception 
    Performs a stored procedure call with the given parameters, calling the closure once with all result objects.

    See #call(String, List, Closure) for more details about creating a Hemisphere(IN first, IN last, OUT dwells) stored procedure. Once created, it can be called like this:

    def first = 'Scott'
    def last = 'Davis'
    sql.call "{call Hemisphere($first, $last, ${Sql.VARCHAR})}", { dwells ->
        println dwells
    }
    

    As another example, see #call(String, List, Closure) for more details about creating a FullName(IN first) stored function. Once created, it can be called like this:

    def first = 'Sam'
    sql.call("{$Sql.VARCHAR = call FullName($first)}") { name ->
        assert name == 'Sam Pullara'
    }
    
 public  void call(String sql,
    List<Object> params,
    Closure closure) throws Exception 
    Performs a stored procedure call with the given parameters. The closure is called once with all the out parameters.

    Example usage - suppose we create a stored procedure (ignore its simplistic implementation):

    // Tested with MySql 5.0.75
    sql.execute """
        CREATE PROCEDURE Hemisphere(
            IN p_firstname VARCHAR(50),
            IN p_lastname VARCHAR(50),
            OUT ans VARCHAR(50))
        BEGIN
        DECLARE loc INT;
        SELECT location_id into loc FROM PERSON where firstname = p_firstname and lastname = p_lastname;
        CASE loc
            WHEN 40 THEN
                SET ans = 'Southern Hemisphere';
            ELSE
                SET ans = 'Northern Hemisphere';
        END CASE;
        END;
    """
    
    we can now call the stored procedure as follows:
    sql.call '{call Hemisphere(?, ?, ?)}', ['Guillaume', 'Laforge', Sql.VARCHAR], { dwells ->
        println dwells
    }
    
    which will output 'Northern Hemisphere'.

    We can also access stored functions with scalar return values where the return value will be treated as an OUT parameter. Here are examples for various databases for creating such a procedure:

    // Tested with MySql 5.0.75
    sql.execute """
        create function FullName(p_firstname VARCHAR(40)) returns VARCHAR(80)
        begin
            declare ans VARCHAR(80);
            SELECT CONCAT(firstname, ' ', lastname) INTO ans FROM PERSON WHERE firstname = p_firstname;
            return ans;
        end
    """
    
    // Tested with MS SQLServer Express 2008
    sql.execute """
        {@code create function FullName(@firstname VARCHAR(40)) returns VARCHAR(80)}
        begin
            declare {@code @ans} VARCHAR(80)
            {@code SET @ans = (SELECT firstname + ' ' + lastname FROM PERSON WHERE firstname = @firstname)}
            return {@code @ans}
        end
    """
    
    // Tested with Oracle XE 10g
    sql.execute """
        create function FullName(p_firstname VARCHAR) return VARCHAR is
        ans VARCHAR(80);
        begin
            SELECT CONCAT(CONCAT(firstname, ' '), lastname) INTO ans FROM PERSON WHERE firstname = p_firstname;
            return ans;
        end;
    """
    
    and here is how you access the stored function for all databases:
    sql.call("{? = call FullName(?)}", [Sql.VARCHAR, 'Sam']) { name ->
        assert name == 'Sam Pullara'
    }
    
 public  void close() throws SQLException 
    If this SQL object was created with a Connection then this method closes the connection. If this SQL object was created from a DataSource then this method does nothing.
 protected  void closeResources(Connection connection,
    Statement statement) 
    An extension point allowing the behavior of resource closing to be overridden in derived classes.
 protected  void closeResources(Connection connection,
    Statement statement,
    ResultSet results) 
    An extension point allowing derived classes to change the behavior of resource closing.
 public  void commit() throws SQLException 
    If this SQL object was created with a Connection then this method commits the connection. If this SQL object was created from a DataSource then this method does nothing.
 protected  void configure(Statement statement) 
    Provides a hook for derived classes to be able to configure JDBC statements. Default behavior is to call a previously saved closure, if any, using the statement as a parameter.
 protected Connection createConnection() throws SQLException 
    An extension point allowing derived classes to change the behavior of connection creation. The default behavior is to either use the supplied connection or obtain it from the supplied datasource.
 protected AbstractQueryCommand createPreparedQueryCommand(String sql,
    List<Object> queryParams) 
    Factory for the PreparedQueryCommand command pattern object allows subclass to supply implementations of the command class.
 protected AbstractQueryCommand createQueryCommand(String sql) 
    Factory for the QueryCommand command pattern object allows subclasses to supply implementations of the command class. The factory will be used in a pattern similar to
    AbstractQueryCommand q = createQueryCommand("update TABLE set count = 0) where count is null");
    try {
    	   ResultSet rs = q.execute();
        return asList(rs);
    } finally {
        q.closeResources();
    }
    
 public DataSet dataSet(String table) 
 public DataSet dataSet(Class<?> type) 
 public  void eachRow(String sql,
    Closure closure) throws SQLException 
    Performs the given SQL query calling the given Closure with each row of the result set. The row will be a GroovyRowResult which is a Map that also supports accessing the fields using ordinal index values.

    Example usages:

    sql.eachRow("select * from PERSON where firstname like 'S%'") { row ->
       println "$row.firstname ${row[2]}}"
    }
    
    sql.eachRow "call my_stored_proc_returning_resultset()", {
        println it.firstname
    }
    
 public  void eachRow(GString gstring,
    Closure closure) throws SQLException 
    Performs the given SQL query calling the given Closure with each row of the result set. The row will be a GroovyRowResult which is a Map that also supports accessing the fields using ordinal index values. The query may contain GString expressions.

    Example usage:

    def location = 25
    sql.eachRow("select * from PERSON where location_id < $location") { row ->
        println row.firstname
    }
    
 public  void eachRow(String sql,
    Closure metaClosure,
    Closure rowClosure) throws SQLException 
    Performs the given SQL query calling the given rowClosure with each row of the result set. The row will be a GroovyRowResult which is a Map that also supports accessing the fields using ordinal index values. In addition, the metaClosure will be called once passing in the ResultSetMetaData as argument.

    Example usage:

    def printColNames = { meta ->
        (1..meta.columnCount).each {
            print meta.getColumnLabel(it).padRight(20)
        }
        println()
    }
    def printRow = { row ->
        row.toRowResult().values().each{ print it.toString().padRight(20) }
        println()
    }
    sql.eachRow("select * from PERSON", printColNames, printRow)
    
 public  void eachRow(String sql,
    List<Object> params,
    Closure closure) throws SQLException 
    Performs the given SQL query calling the given Closure with each row of the result set. The row will be a GroovyRowResult which is a Map that also supports accessing the fields using ordinal index values. The query may contain placeholder question marks which match the given list of parameters.

    Example usage:

    sql.eachRow("select * from PERSON where lastname like ?", ['%a%']) { row ->
        println "${row[1]} $row.lastname"
    }
    
 public boolean execute(String sql) throws SQLException 
    Executes the given piece of SQL. Also saves the updateCount, if any, for subsequent examination.

    Example usages:

    sql.execute "drop table if exists PERSON"
    
    sql.execute """
        create table PERSON (
            id integer not null,
            firstname varchar(100),
            lastname varchar(100),
            location_id integer
        )
    """
    
    sql.execute """
        insert into PERSON (id, firstname, lastname, location_id) values (4, 'Paul', 'King', 40)
    """
    assert sql.updateCount == 1
    
 public boolean execute(GString gstring) throws SQLException 
    Executes the given SQL with embedded expressions inside. Also saves the updateCount, if any, for subsequent examination.

    Example usage:

    def scott = [firstname: "Scott", lastname: "Davis", id: 5, location_id: 50]
    sql.execute """
        insert into PERSON (id, firstname, lastname, location_id) values ($scott.id, $scott.firstname, $scott.lastname, $scott.location_id)
    """
    assert sql.updateCount == 1
    
 public boolean execute(String sql,
    List<Object> params) throws SQLException 
    Executes the given piece of SQL with parameters. Also saves the updateCount, if any, for subsequent examination.

    Example usage:

    sql.execute """
        insert into PERSON (id, firstname, lastname, location_id) values (?, ?, ?, ?)
    """, [1, "Guillaume", "Laforge", 10]
    assert sql.updateCount == 1
    
 public List<Object> executeInsert(String sql) throws SQLException 
    Executes the given SQL statement (typically an INSERT statement). Use this variant when you want to receive the values of any auto-generated columns, such as an autoincrement ID field. See #executeInsert(GString) for more details.
 public List<Object> executeInsert(GString gstring) throws SQLException 

    Executes the given SQL statement (typically an INSERT statement). Use this variant when you want to receive the values of any auto-generated columns, such as an autoincrement ID field. The query may contain GString expressions.

    Generated key values can be accessed using array notation. For example, to return the second auto-generated column value of the third row, use keys[3][1]. The method is designed to be used with SQL INSERT statements, but is not limited to them.

    The standard use for this method is when a table has an autoincrement ID column and you want to know what the ID is for a newly inserted row. In this example, we insert a single row into a table in which the first column contains the autoincrement ID:

        def sql = Sql.newInstance("jdbc:mysql://localhost:3306/groovy",
                                  "user",
                                  "password",
                                  "com.mysql.jdbc.Driver")
    

    def keys = sql.executeInsert("insert into test_table (INT_DATA, STRING_DATA) " + "VALUES (1, 'Key Largo')")

    def id = keys[0][0]

    // 'id' now contains the value of the new row's ID column. // It can be used to update an object representation's // id attribute for example. ...

 public List<Object> executeInsert(String sql,
    List<Object> params) throws SQLException 
    Executes the given SQL statement (typically an INSERT statement). Use this variant when you want to receive the values of any auto-generated columns, such as an autoincrement ID field. The query may contain placeholder question marks which match the given list of parameters. See #executeInsert(GString) for more details.
 protected final ResultSet executePreparedQuery(String sql,
    List<Object> params) throws SQLException 
    Hook to allow derived classes to access ResultSet returned from query.
 protected final ResultSet executeQuery(String sql) throws SQLException 
    Hook to allow derived classes to access ResultSet returned from query.
 public int executeUpdate(String sql) throws SQLException 
    Executes the given SQL update.
 public int executeUpdate(GString gstring) throws SQLException 
    Executes the given SQL update with embedded expressions inside.
 public int executeUpdate(String sql,
    List<Object> params) throws SQLException 
    Executes the given SQL update with parameters.
 public static ExpandedVariable expand(Object object) 
    When using GString SQL queries, allows a variable to be expanded in the Sql string rather than representing an sql parameter.

    Example usage:

    def fieldName = 'firstname'
    def fieldOp = Sql.expand('like')
    def fieldVal = '%a%'
    sql.query "select * from PERSON where ${Sql.expand(fieldName)} $fieldOp ${fieldVal}", { ResultSet rs ->
        while (rs.next()) println rs.getString('firstname')
    }
    // query will be 'select * from PERSON where firstname like ?'
    // params will be [fieldVal]
    
 protected int findWhereKeyword(String sql) 
    Hook to allow derived classes to override where clause sniffing. Default behavior is to find the first 'where' keyword in the sql doing simple avoidance of the word 'where' within quotes.
 public Object firstRow(String sql) throws SQLException 
    Performs the given SQL query and return the first row of the result set.

    Example usage:

    def ans = sql.firstRow("select * from PERSON where firstname like 'S%'")
    println ans.firstname
    
 public Object firstRow(GString gstring) throws SQLException 
    Performs the given SQL query and return the first row of the result set. The query may contain GString expressions.

    Example usage:

    def location = 25
    def ans = sql.firstRow("select * from PERSON where location_id < $location")
    println ans.firstname
    
 public Object firstRow(String sql,
    List<Object> params) throws SQLException 
    Performs the given SQL query and return the first row of the result set. The query may contain placeholder question marks which match the given list of parameters.

    Example usages:

    def ans = sql.firstRow("select * from PERSON where lastname like ?", ['%a%'])
    println ans.firstname
    
    If your database returns scalar functions as ResultSets, you can also use firstRow to gain access to stored procedure results, e.g. using hsqldb 1.9 RC4:
    sql.execute """
        create function FullName(p_firstname VARCHAR(40)) returns VARCHAR(80)
        BEGIN atomic
        DECLARE ans VARCHAR(80);
        SET ans = (SELECT firstname || ' ' || lastname FROM PERSON WHERE firstname = p_firstname);
        RETURN ans;
        END
    """
    
    assert sql.firstRow("{call FullName(?)}", ['Sam'])[0] == 'Sam Pullara'
    
 public Connection getConnection() 
    If this instance was created with a single Connection then the connection is returned. Otherwise if this instance was created with a DataSource then this method returns null
 public DataSource getDataSource() 
 protected List<Object> getParameters(GString gstring) 
    Hook to allow derived classes to override behavior associated with extracting params from a GString.
 public int getResultSetConcurrency() 
    Gets the resultSetConcurrency for statements created using the connection.
 public int getResultSetHoldability() 
    Gets the resultSetHoldability for statements created using the connection.
 public int getResultSetType() 
    Gets the resultSetType for statements created using the connection.
 public int getUpdateCount() 
 public static InParameter in(int type,
    Object value) 
    Create a new InParameter
 public static InOutParameter inout(InParameter in) 
    Create an inout parameter using this in parameter.
 public boolean isCacheStatements() 
 public static  void loadDriver(String driverClassName) throws ClassNotFoundException 
    Attempts to load the JDBC driver on the thread, current or system class loaders
 public static Sql newInstance(String url) throws SQLException 
    Creates a new Sql instance given a JDBC connection URL.
 public static Sql newInstance(String url,
    Properties properties) throws SQLException 
    Creates a new Sql instance given a JDBC connection URL and some properties.
 public static Sql newInstance(String url,
    String driverClassName) throws SQLException, ClassNotFoundException 
    Creates a new Sql instance given a JDBC connection URL and a driver class name.
 public static Sql newInstance(String url,
    Properties properties,
    String driverClassName) throws SQLException, ClassNotFoundException 
    Creates a new Sql instance given a JDBC connection URL, some properties and a driver class name.
 public static Sql newInstance(String url,
    String user,
    String password) throws SQLException 
    Creates a new Sql instance given a JDBC connection URL, a username and a password.
 public static Sql newInstance(String url,
    String user,
    String password,
    String driverClassName) throws SQLException, ClassNotFoundException 
    Creates a new Sql instance given a JDBC connection URL, a username, a password and a driver class name.
 protected String nullify(String sql) 
    Hook to allow derived classes to override null handling. Default behavior is to replace ?'"? references with NULLish
 public static OutParameter out(int type) 
    Create a new OutParameter
 public  void query(String sql,
    Closure closure) throws SQLException 
    Performs the given SQL query, which should return a single ResultSet object. The given closure is called with the ResultSet as its argument.

    Example usages:

    sql.query("select * from PERSON where firstname like 'S%'") { ResultSet rs ->
        while (rs.next()) println rs.getString('firstname') + ' ' + rs.getString(3)
    }
    
    sql.query("call get_people_places()") { ResultSet rs ->
        while (rs.next()) println rs.toRowResult().firstname
    }
    
    All resources including the ResultSet are closed automatically after the closure is called.
 public  void query(GString gstring,
    Closure closure) throws SQLException 
    Performs the given SQL query, which should return a single ResultSet object. The given closure is called with the ResultSet as its argument. The query may contain GString expressions.

    Example usage:

    def location = 25
    sql.query "select * from PERSON where location_id < $location", { ResultSet rs ->
        while (rs.next()) println rs.getString('firstname')
    }
    
    All resources including the ResultSet are closed automatically after the closure is called.
 public  void query(String sql,
    List<Object> params,
    Closure closure) throws SQLException 
    Performs the given SQL query, which should return a single ResultSet object. The given closure is called with the ResultSet as its argument. The query may contain placeholder question marks which match the given list of parameters.

    Example usage:

    sql.query('select * from PERSON where lastname like ?', ['%a%']) { ResultSet rs ->
        while (rs.next()) println rs.getString('lastname')
    }
    
    All resources including the ResultSet are closed automatically after the closure is called.
 public static ResultSetOutParameter resultSet(int type) 
    Create a new ResultSetOutParameter
 public  void rollback() throws SQLException 
    If this SQL object was created with a Connection then this method rolls back the connection. If this SQL object was created from a DataSource then this method does nothing.
 public List<GroovyRowResult> rows(String sql) throws SQLException 
    Performs the given SQL query and return the rows of the result set.

    Example usage:

    def ans = sql.rows("select * from PERSON where firstname like 'S%'")
    println "Found ${ans.size()} rows"     * 
 public List<GroovyRowResult> rows(GString gstring) throws SQLException 
    Performs the given SQL query and return the rows of the result set. The query may contain GString expressions.

    Example usage:

    def location = 25
    def ans = sql.rows("select * from PERSON where location_id < $location")
    println "Found ${ans.size()} rows"
    
 public List<GroovyRowResult> rows(String sql,
    Closure metaClosure) throws SQLException 
    Performs the given SQL query and return the rows of the result set.

    Example usage:

    def printNumCols = { meta -> println "Found $meta.columnCount columns" }
    def ans = sql.rows("select * from PERSON", printNumCols)
    println "Found ${ans.size()} rows"
    
 public List<GroovyRowResult> rows(String sql,
    List<Object> params) throws SQLException 
    Performs the given SQL query and return the rows of the result set. The query may contain placeholder question marks which match the given list of parameters.

    Example usage:

    def ans = sql.rows("select * from PERSON where lastname like ?", ['%a%'])
    println "Found ${ans.size()} rows"
    
 public synchronized  void setCacheStatements(boolean cacheStatements) 
    Enables statement caching.
    if b is true, cache is created and all created prepared statements will be cached.
    if b is false, all cached statements will be properly closed.
 protected  void setInternalConnection(Connection conn) 
    Stub needed for testing. Called when a connection is opened by one of the command-pattern classes so that a test case can monitor the state of the connection through its subclass.
 protected  void setObject(PreparedStatement statement,
    int i,
    Object value) throws SQLException 
    Strategy method allowing derived classes to handle types differently such as for CLOBs etc.
 protected  void setParameters(List<Object> params,
    PreparedStatement statement) throws SQLException 
    Hook to allow derived classes to override behavior associated with setting params for a prepared statement. Default behavior is to append the parameters to the given statement using setObject.
 public  void setResultSetConcurrency(int resultSetConcurrency) 
    Sets the resultSetConcurrency for statements created using the connection. May cause SQLFeatureNotSupportedException exceptions to occur if the underlying database doesn't support the requested concurrency value.
 public  void setResultSetHoldability(int resultSetHoldability) 
    Sets the resultSetHoldability for statements created using the connection. May cause SQLFeatureNotSupportedException exceptions to occur if the underlying database doesn't support the requested holdability value.
 public  void setResultSetType(int resultSetType) 
    Sets the resultSetType for statements created using the connection. May cause SQLFeatureNotSupportedException exceptions to occur if the underlying database doesn't support the requested type value.
 public synchronized int[] withBatch(Closure closure) throws SQLException 
    Performs the closure within a batch using a cached connection. The closure will be called with a single argument; the statement associated with this batch. Use it like this:
    def updateCounts = sql.withBatch { stmt ->
        stmt.addBatch("insert into TABLENAME ...")
        stmt.addBatch("insert into TABLENAME ...")
        stmt.addBatch("insert into TABLENAME ...")
    }
    
 public  void withStatement(Closure configureStatement) 
    Allows a closure to be passed in to configure the JDBC statements before they are executed. It can be used to do things like set the query size etc. When this method is invoked, the supplied closure is saved. Statements subsequently created from other methods will then be configured using this closure. The statement being configured is passed into the closure as its single argument, e.g.:
    sql.withStatement{ stmt -> stmt.maxRows == 10 }
    def firstTenRows = sql.rows("select * from table")
    
 public synchronized  void withTransaction(Closure closure) throws SQLException 
    Performs the closure within a transaction using a cached connection. If the closure takes a single argument, it will be called with the connection, otherwise it will be called with no arguments.