Java 基于DTO中属性的存在动态构建SQLWHERE子句

Java 基于DTO中属性的存在动态构建SQLWHERE子句,java,sql,groovy,Java,Sql,Groovy,我有一个屏幕,用户可以根据一个或多个列搜索表。我将用户希望筛选的列作为DTO传递到后端 在这里,我通过检查DTO中是否存在这些字段来构建一个SQL查询 Object transactionSearch (TransactionSearchDTO dto ){ StringBuilder transactionQuery = new StringBuilder() transactionQuery.append("SELECT id, delivery_date, or

我有一个屏幕,用户可以根据一个或多个列搜索表。我将用户希望筛选的列作为DTO传递到后端

在这里,我通过检查DTO中是否存在这些字段来构建一个SQL查询

Object transactionSearch (TransactionSearchDTO dto ){

    StringBuilder transactionQuery = new StringBuilder()
    transactionQuery.append("SELECT id, delivery_date, order_date, customer_name FROM transaction where 1=1 ")

    if (dto.order_id) {
     transactionQuery.append("and order_id = ${dto.order_id}")
    }
    if (delivery_date) {
     transactionQuery.append("and order_id = ${delivery_date}")
    }
    if (customer_name) {
     transactionQuery.append("and order_id = ${customer_name}")
    }

}
我最后得到的是每一列的大量if语句

有没有一种方法可以实现这一点,而不必为每个过滤器设置if块


我找到了一些想法,但我需要Groovy或Java中的解决方案。

我建议使用GString而不是StringBuilder将参数正确地传递给Groovy.sql.sql

class DTO{
    int id
    String name
    Date created
}

def a = new DTO(id:123, created:new Date())

GString f(DTO a){
    GString q = GString.EMPTY + 'select ' + a.getProperties().collect{k,v-> k}.join(',')+' from T'
    
    a.getProperties().each{k,v->
        if(k!='class' && v!=null){
            q = q + ( q.getValueCount()==0 ? ' WHERE ' : ' AND ' )
            q = q + k + " = ${v}"
        }
    }
    
    return q
}

def s = f(a)

println s
println s.getValues()
println s.getStrings()

您的示例是否需要调整为在所有三个
if
测试中都不使用
order\u id