英文:
How to insert an array value to postgreSQL with mybatis
问题
My class
class PgFolder {
long id;
int[] pgFeature;
}
getter...
setter...
My table
CREATE TABLE folder {
ID BIGSERIAL PRIMARY KEY,
feature INT[]
}
My xml
<insert id="insertManyFolder" parameterType="java.util.List">
INSERT INTO
folder
(feature)
VALUES
<foreach collection="list" item="item" index="" separator=",">
(#{item.pgFeature})
</foreach>
</insert>
I want to insert a List<PgFolder>
list. There are many PgFolder instances in the list. When I run the program, I got an error:
>org.apache.ibatis.exceptions.PersistenceException: <br>
Error updating the database. Cause: java.lang.IllegalStateException: The type handler was null on the parameter mapping for property '__frch_item_0.pgFeature'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.<br>
> Cause: java.lang.IllegalStateException: The type handler was null on the parameter mapping for property '__frch_item_0.pgFeature'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.**
Why did I get this error message? How can I insert the array value correctly?
I can insert an array value if I use the SQL in the PostgreSQL client. So, the version of PostgreSQL I installed can support the array value.
英文:
My class
class PgFolder {
long id;
int[] pgFeature;
}
getter...
setter...
My table
CREATE TABLE folder {
ID BIGSERIAL PRIMARY KEY,
feature INT[]
}
My xml
<insert id="insertManyFolder" parameterType="java.util.List">
INSERT INTO
folder
(feature)
VALUES
<foreach collection="list" item="item" index="" separator=",">
(#{item.pgFeature})
</foreach>
</insert>
I want to insert a List<PgFolder>
list. There are many PgFolder instance in the list. When I run the program, I got an error:
>org.apache.ibatis.exceptions.PersistenceException: <br>
Error updating database. Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0.pgFeature'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.<br>
> Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0.pgFeature'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.**
Why I got this error message? How to insert the array value in the right way?
I can insert an array value if I use the sql in postgres client. so the postgres of the version I installed can support the array value.
答案1
得分: 4
Mapping Integer[]
class PgFolder {
long id;
Integer[] pgFeature;
// getter / setter
}
在这种情况下,您可以使用 MyBatis 的内置 ArrayTypeHandler
。 在参数引用中指定 typeHandler
即可。
<foreach ...>
(#{item.pgFeature,typeHandler=org.apache.ibatis.type.ArrayTypeHandler})
</foreach>
映射 int[]
由于内置的 ArrayTypeHandler
可能无法处理原始数组,您可能需要编写一个自定义类型处理器。例如:
package pkg;
import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
public class PgIntArrayTypeHandler extends BaseTypeHandler<int[]>{
@Override
public void setNonNullParameter(PreparedStatement ps, int i, int[] parameter, JdbcType jdbcType)
throws SQLException {
ps.setObject(i, parameter);
}
@Override
public int[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
return extractArray(rs.getArray(columnName));
}
@Override
public int[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return extractArray(rs.getArray(columnIndex));
}
@Override
public int[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return extractArray(cs.getArray(columnIndex));
}
protected int[] extractArray(Array array) throws SQLException {
if (array == null) {
return null;
}
// pgjdbc returns Integer[] for the INT[] column
Integer[] wrapperArray = (Integer[]) array.getArray();
int[] result = Arrays.stream(wrapperArray).mapToInt(Integer::intValue).toArray();
array.free();
return result;
}
}
然后在参数引用中指定类型处理器。
<foreach ...>
(#{item.pgFeature,typeHandler=pkg.PgIntArrayTypeHandler})
</foreach>
已在 MyBatis 3.5.5 和 pgjdbc 42.2.15 上进行测试。
英文:
I'll explain both solutions i.e. mapping Integer[]
property and mapping int[]
property.
Mapping Integer[]
class PgFolder {
long id;
Integer[] pgFeature;
// getter / setter
}
In this case, you can use MyBatis' built-in ArrayTypeHandler
.
Specifying typeHandler
in the parameter reference is sufficient.
<foreach ...>
(#{item.pgFeature,typeHandler=org.apache.ibatis.type.ArrayTypeHandler})
</foreach>
Mapping int[]
As the built-in ArrayTypeHandler
may not work with primitive arrays, you may have to write a custom type handler. e.g.
package pkg;
import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
public class PgIntArrayTypeHandler extends BaseTypeHandler<int[]>{
@Override
public void setNonNullParameter(PreparedStatement ps, int i, int[] parameter, JdbcType jdbcType)
throws SQLException {
ps.setObject(i, parameter);
}
@Override
public int[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
return extractArray(rs.getArray(columnName));
}
@Override
public int[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return extractArray(rs.getArray(columnIndex));
}
@Override
public int[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return extractArray(cs.getArray(columnIndex));
}
protected int[] extractArray(Array array) throws SQLException {
if (array == null) {
return null;
}
// pgjdbc returns Integer[] for the INT[] column
Integer[] wrapperArray = (Integer[]) array.getArray();
int[] result = Arrays.stream(wrapperArray).mapToInt(Integer::intValue).toArray();
array.free();
return result;
}
}
Then specify the type handler in the parameter reference.
<foreach ...>
(#{item.pgFeature,typeHandler=pkg.PgIntArrayTypeHandler})
</foreach>
Tested with MyBatis 3.5.5 and pgjdbc 42.2.15.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论