Fra*_*sco 6 arrays postgresql spring jdbctemplate
我正在使用 Spring JdbcTemplate,并且我陷入了一个查询,该查询更新实际上是一个 int 数组的列。数据库是postgres 8.3.7。这是我正在使用的代码:
public int setUsersArray(int idUser, int idDevice, Collection<Integer> ids) {
int update = -666;
int[] tipi = new int[3];
tipi[0] = java.sql.Types.INTEGER;
tipi[1] = java.sql.Types.INTEGER;
tipi[2] = java.sql.Types.ARRAY;
try {
update = this.jdbcTemplate.update(setUsersArrayQuery, new Object[] {
ids, idUser, idDevice }, tipi);
} catch (Exception e) {
e.printStackTrace();
}
return update;
}
Run Code Online (Sandbox Code Playgroud)
查询是“update table_name set array_column = ? where id_user = ? and id_device = ?”。我得到这个例外:
org.springframework.dao.DataIntegrityViolationException:PreparedStatementCallback;SQL [更新acotel_msp.users_mau 设置denied_sub_client = ? 其中 id_users = ? 和 id_mau = ?]; 列索引超出范围:4,列数:3。;嵌套异常是 org.postgresql.util.PSQLException:列索引超出范围:4,列数:3。
引起原因:org.postgresql.util.PSQLException:列索引超出范围:4,列数:3。
我已经查看了 spring jdbc 模板文档,但找不到任何帮助,我会继续寻找,无论如何有人可以指出我正确的方向吗?谢谢!
编辑 :
显然顺序错了,我的错......
我尝试了您的两种解决方案,在第一种情况下我有这样的:
org.springframework.jdbc.BadSqlGrammarException:PreparedStatementCallback;错误的 SQL 语法 [更新用户设置 Denied_sub_client = ? 其中 id_users = ? 和 id_device = ?]; 嵌套异常是 org.postgresql.util.PSQLException:无法将 java.util.ArrayList 的实例强制转换为 Types.ARRAY 类型
尝试第二个解决方案我有这样的:
org.springframework.jdbc.BadSqlGrammarException:PreparedStatementCallback;错误的 SQL 语法 [更新用户设置 Denied_sub_client = ? 其中 id_users = ? 和 id_device = ?]; 嵌套异常是 org.postgresql.util.PSQLException: 无法转换 [Ljava.lang.Object; 的实例; 输入 Types.ARRAY
我想我需要一个 java.sql.Array 的实例,但是如何使用 JdbcTemplate 创建它?
squ*_*dle 10
经过多次尝试后,我们决定使用一个小助手 ArraySqlValue 来为 Java 数组类型创建 Spring SqlValue 对象。
用法是这样的
jdbcTemplate.update(
"UPDATE sometable SET arraycolumn = ?",
ArraySqlValue.create(arrayValue))
Run Code Online (Sandbox Code Playgroud)
ArraySqlValue 还可以在 MapSqlParameterSource 中与 NamedParameterJdbcTemplate 一起使用。
import static com.google.common.base.Preconditions.checkNotNull;
import java.sql.Array;
import java.sql.JDBCType;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Locale;
import org.springframework.jdbc.core.StatementCreatorUtils;
import org.springframework.jdbc.support.SqlValue;
public class ArraySqlValue implements SqlValue {
private final Object[] arr;
private final String dbTypeName;
public static ArraySqlValue create(final Object[] arr) {
return new ArraySqlValue(arr, determineDbTypeName(arr));
}
public static ArraySqlValue create(final Object[] arr, final String dbTypeName) {
return new ArraySqlValue(arr, dbTypeName);
}
private ArraySqlValue(final Object[] arr, final String dbTypeName) {
this.arr = checkNotNull(arr);
this.dbTypeName = checkNotNull(dbTypeName);
}
@Override
public void setValue(final PreparedStatement ps, final int paramIndex) throws SQLException {
final Array arrayValue = ps.getConnection().createArrayOf(dbTypeName, arr);
ps.setArray(paramIndex, arrayValue);
}
@Override
public void cleanup() {}
private static String determineDbTypeName(final Object[] arr) {
// use Spring Utils similar to normal JdbcTemplate inner workings
final int sqlParameterType =
StatementCreatorUtils.javaTypeToSqlParameterType(arr.getClass().getComponentType());
final JDBCType jdbcTypeToUse = JDBCType.valueOf(sqlParameterType);
// lowercasing typename for Postgres
final String typeNameToUse = jdbcTypeToUse.getName().toLowerCase(Locale.US);
return typeNameToUse;
}
}
Run Code Online (Sandbox Code Playgroud)
该代码在公共领域提供
这个解决方案是一种使用 postgreSQL 内置函数的解决方法,这对我来说绝对有效。
1) 将字符串数组转换为逗号分隔字符串
如果您使用 Java8,这非常简单。其他选项在这里
String commaSeparatedString = String.join(",",stringArray); // Java8 feature
Run Code Online (Sandbox Code Playgroud)
2)PostgreSQL内置函数string_to_array()
你可以在这里找到其他 postgreSQL 数组函数
// tableName ( name text, string_array_column_name text[] )
String query = "insert into tableName(name,string_array_column_name ) values(?, string_to_array(?,',') )";
int[] types = new int[] { Types.VARCHAR, Types.VARCHAR};
Object[] psParams = new Object[] {"Dhruvil Thaker",commaSeparatedString };
jdbcTemplate.batchUpdate(query, psParams ,types); // assuming you have jdbctemplate instance
Run Code Online (Sandbox Code Playgroud)
参数类型和参数不匹配。
尝试更改参数类型顺序
int[] tipi = new int[3];
tipi[0] = java.sql.Types.ARRAY;
tipi[1] = java.sql.Types.INTEGER;
tipi[2] = java.sql.Types.INTEGER;
Run Code Online (Sandbox Code Playgroud)
或使用
update = this.jdbcTemplate.update(setUsersArrayQuery, new Object[] {
ids.toArray(), idUser, idDevice })
Run Code Online (Sandbox Code Playgroud)
看看是否有效