Java 如何使用JPA防止本机插入查询中的SQL注入?

Java 如何使用JPA防止本机插入查询中的SQL注入?,java,postgresql,hibernate,jpa,sql-injection,Java,Postgresql,Hibernate,Jpa,Sql Injection,我使用JPA/Hibernate的本机查询对PostgreSQL执行插入或更新(“upsert”),具体取决于对象是否存在。代码如下所示: val values: String = items.joinToString(", ", transform = this::convertItemToSqlValue) val query = """ insert into item (field1, field2) values $values on conflict on c

我使用JPA/Hibernate的本机查询对PostgreSQL执行插入或更新(“upsert”),具体取决于对象是否存在。代码如下所示:

val values: String = items.joinToString(", ", transform = this::convertItemToSqlValue)
val query = """
    insert into item (field1, field2)
    values $values
    on conflict on constraint item_pkey
    do update set 
        field1 = excluded.field1,
        field2 = excluded.field2
"""
entityManager.createNativeQuery(query).executeUpdate()
函数
convertItemToSqlValue
创建一个字符串,格式为
('value a',123)

位置参数(
值?
)不起作用(并导致语法错误)


如何防止使用这种语句进行SQL注入?

从用户输入动态生成SQL语句不是最好的主意。最好使用事先准备好的语句。然而,在这种情况下,使用JPA EntityManager执行补丁更新似乎不是一种简单的方法

使用JDBC可以设置多个值。以下示例显示了与的用法:

val项:列表=。。。
val语句=
"""
插入项目(字段1、字段2)
值(?,)
论约束上的冲突
更新集
field1=排除在外。field1,
field2=已排除。field2
"""
jdbcTemplate.batchUpdate(
陈述
对象:BatchPreparedStatementSetter{
重写设置值(语句:PreparedStatement,索引:Int){
val项目=项目[索引]
语句.设置字符串(1,项.字段1)
语句.setInt(2,项.field2)
}
重写getBatchSize():Int=items.size
}
)
val items: List<Item> = ...

val statement = 
    """
    insert into item (field1, field2)
    values (?,?)
    on conflict on constraint arbeit_pkey
    do update set 
        field1 = excluded.field1,
        field2 = excluded.field2
    """
jdbcTemplate.batchUpdate(
    statement, 
    object : BatchPreparedStatementSetter {
        override fun setValues(statement: PreparedStatement, index: Int) {
            val item = items[index]
            statement.setString(1, item.field1)
            statement.setInt(2, item.field2)
        }
        override fun getBatchSize(): Int = items.size
    }
)