带命名参数的 Groovy 准备语句

标签 groovy

我使用以下方式使用 JDBC Prepared Statement 执行命名参数。有什么建议可以改善这一点吗?

import java.sql.*;

def sqlQuery = "select * from table where col1=:col1 and col2=:col2"
def namedParameters =[
  ['ColumnName':'col1','Value':'test', 'DataType': 'int'],
  ['ColumnName':'col2','Value':'testsdfdf', 'DataType':'string'],
];

PreparedStatement stmt;

namedParameters.eachWithIndex{ k, v -> 
println "Index: " + v
println "Name: " + k.ColumnName
println "Value: " + k.Value

//To replace named parameters with ?
sqlQuery  = sqlQuery .replace(":" + k.ColumnName, "?")
println sqlQuery 

println "DataType: " + k.DataType

switch(k.DataType.toLowerCase())
{
    case('int'):
    stmt.setInt(v+1, k.Value)
    break;

    case('string'):
    stmt.setString(v+1, k.Value)
    break;

    default:
    stmt.setObject(v+1, k.Value)
}

};

println "End"
  • 我正在做一个字符串替换来替换命名参数?
  • 并根据提供的 map ,识别数据类型将其设置为 PreparedStatement相应地
  • 最佳答案

    您可以使用 groovy.sql.Sql类及其 execute(Map params, String query, Closure processResults 方法。考虑以下示例脚本:

    sql.groovy:

    @Grab(group='com.h2database', module='h2', version='1.4.197')
    
    import groovy.sql.Sql
    
    // (1) Configure JDBC connection (use H2 in-memory DB in this example)
    def config = [
            url:'jdbc:h2:mem:test',
            user:'sa',
            password:'',
            driver: 'org.h2.Driver'
    ]
    
    // (2) Connect to the database
    def sql = Sql.newInstance(config.url, config.user, config.password, config.driver)
    
    // (3) Create table for testing
    sql.execute '''
         create table test (
             id integer not null,
             name varchar(50)
         )
    '''
    
    // (4) Insert some test data
    def query = 'insert into test (id, name) values (?,?)'
    sql.withBatch(3, query) { stmt ->
        stmt.addBatch(1, 'test 1')
        stmt.addBatch(2, 'test 2')
        stmt.addBatch(3, 'test 3')
    }
    
    // (5) Execute SELECT query
    sql.execute([id: 1, name: 'test 1'], 'select * from test where id >= :id and name != :name', { _, result ->
        result.each { row ->
            println "id: ${row.ID}, name: ${row.NAME}"
        }
    })
    

    最后一部分展示了如何使用带有命名参数的准备好的语句。在这个例子中,我们要列出所有行 id大于或等于 1哪里name不等于 test 1 .
    sql.execute()的第一个参数方法是一个保存命名参数的映射(每个 key 映射到 SQL 查询中的 :key)。第二个参数是您的 SQL 查询,其中 :key格式用于命名参数。而第三个参数是一个闭包,定义了处理业务逻辑 - result持有 map 列表(例如 [[ID: 2, NAME: test 2], [ID:3 name: test 3]] 在这种情况下),您必须定义如何处理此结果。

    控制台输出
    id: 2, name: test 2
    id: 3, name: test 3
    
    sql.eachRow()选择

    或者,您可以使用 sql.eachRow(String sql, Map params, Closure closure) 反而:
    sql.eachRow('select * from test where id > :id', [id: 1], { row ->
        println "id: ${row.ID}, name: ${row.NAME}"
    })
    

    它将产生相同的输出。

    关于带命名参数的 Groovy 准备语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49492658/

    相关文章:

    gradle - 可以在Gradle中使用C++类,因为它支持groovy

    grails - Grails Blob为pdf

    grails - Groovy HTTPBuilder + RxJava返回一个空对象/可观察到

    groovy - 使用 Groovy 特征编写 Geb 页面

    jenkins - Jenkins-Groovy脚本返回了退出代码126

    gradle - 如何将管道添加到 groovy exec 命令行?

    java - 使用 appium whlie 客户端访问 Android 设置中的切换按钮是用 groovy 和 java 编写的

    java - 如何使用 MarkupBuilder 将 xml 写入文件

    groovy - Groovy ASTTransformation-在闭包内部执行forLoop的collectionExpression

    unit-testing - 在Grails中通过BuildConfig.groovy使用依赖关系解析时,如何有效地进行单元测试?