如何使用 Mybatis 和 PostgreSQL 创建一个空数组?
How to create a empty Array using Mybatis and PostgreSQL?
当我使用 Mybatis 和 Postgres 编写项目时,发生了一些令人作呕的事情。
您知道 Postgres 有一个很棒的类型 ARRAY
,但是创建 java.sql.Array
的唯一方法是 java.sql.Connection:createOf(typeName, arrayContent)
,这是背景。
为了建立 List 和 ARRAY 之间的关系,我写了 TypeHandler
以下内容:
@MappedTypes(List.class)
@MappedJdbcTypes({JdbcType.ARRAY})
public class ListTypeHandler extends BaseTypeHandler<List> {
private static final String TYPE_NAME_UUID = "uuid";
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List list, JdbcType jdbcType) throws SQLException {
Connection conn = ps.getConnection();
if(list.size() != 0) {
Object[] parameter = list.toArray(new Object[0]);
String typeName = null;
// using a switch to determine how to map the Java type to the sql type
if (list.get(0) instanceof UUID) {
typeName = TYPE_NAME_UUID;
}
if (typeName == null) {
throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName());
}
Array array = conn.createArrayOf(typeName, parameter);
ps.setArray(i, array);
} else {
// here is the hard point
ps.setArray(i, conn.createArrayOf("uuid", new Object[0]));
}
}
private List getArray(Array array) {
try {
return Arrays.asList((Object[])array.getArray());
} catch (Exception e) {
return null;
}
}
}
因为 java.sql.Array
和 List 中都没有类型(因为 fxcking 擦除),而且我的数据库中有很多不同类型的数组,所以我必须统一 TypeHandler
来处理Array
和List
的关系。
我的解决方案是获取列表的第一个对象并查看类型是什么,然后将其映射到数据库偏好的类型。一切似乎都很好。
但是当一个空列表进入时,所有的事情都搞砸了。首先,我无法根据第一个元素来确定类型;其次,我无法使用 List 对象获取类型信息(再次诅咒类型擦除);第三,我无法使用 sql.Array
对象获得 sql 类型;第四,我不能创建一个空的 sql.Array
独立于类型(在我看来,如果将一个空数组传递给数据库,数据库应该根据它的实际类型创建它......)。所以一句话,我卡住了...
不知道有没有人能帮帮我?我是 SOOOOOOOO DADDDDDDDD.....
拜托Orz.......
出于我的目的,我将数组映射到 Set
,它与 PreparedStatement.setObject
一起工作得很好,您可以作为空列表的选项执行以下操作:
if (list.isEmpty()) {
ps.setObject(i, Collections.<Object>emptySet());
} else {
//process non-empty list
}
当我使用 Mybatis 和 Postgres 编写项目时,发生了一些令人作呕的事情。
您知道 Postgres 有一个很棒的类型 ARRAY
,但是创建 java.sql.Array
的唯一方法是 java.sql.Connection:createOf(typeName, arrayContent)
,这是背景。
为了建立 List 和 ARRAY 之间的关系,我写了 TypeHandler
以下内容:
@MappedTypes(List.class)
@MappedJdbcTypes({JdbcType.ARRAY})
public class ListTypeHandler extends BaseTypeHandler<List> {
private static final String TYPE_NAME_UUID = "uuid";
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List list, JdbcType jdbcType) throws SQLException {
Connection conn = ps.getConnection();
if(list.size() != 0) {
Object[] parameter = list.toArray(new Object[0]);
String typeName = null;
// using a switch to determine how to map the Java type to the sql type
if (list.get(0) instanceof UUID) {
typeName = TYPE_NAME_UUID;
}
if (typeName == null) {
throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName());
}
Array array = conn.createArrayOf(typeName, parameter);
ps.setArray(i, array);
} else {
// here is the hard point
ps.setArray(i, conn.createArrayOf("uuid", new Object[0]));
}
}
private List getArray(Array array) {
try {
return Arrays.asList((Object[])array.getArray());
} catch (Exception e) {
return null;
}
}
}
因为 java.sql.Array
和 List 中都没有类型(因为 fxcking 擦除),而且我的数据库中有很多不同类型的数组,所以我必须统一 TypeHandler
来处理Array
和List
的关系。
我的解决方案是获取列表的第一个对象并查看类型是什么,然后将其映射到数据库偏好的类型。一切似乎都很好。
但是当一个空列表进入时,所有的事情都搞砸了。首先,我无法根据第一个元素来确定类型;其次,我无法使用 List 对象获取类型信息(再次诅咒类型擦除);第三,我无法使用 sql.Array
对象获得 sql 类型;第四,我不能创建一个空的 sql.Array
独立于类型(在我看来,如果将一个空数组传递给数据库,数据库应该根据它的实际类型创建它......)。所以一句话,我卡住了...
不知道有没有人能帮帮我?我是 SOOOOOOOO DADDDDDDDD.....
拜托Orz.......
出于我的目的,我将数组映射到 Set
,它与 PreparedStatement.setObject
一起工作得很好,您可以作为空列表的选项执行以下操作:
if (list.isEmpty()) {
ps.setObject(i, Collections.<Object>emptySet());
} else {
//process non-empty list
}