如何使用 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来处理ArrayList的关系。

我的解决方案是获取列表的第一个对象并查看类型是什么,然后将其映射到数据库偏好的类型。一切似乎都很好。

但是当一个空列表进入时,所有的事情都搞砸了。首先,我无法根据第一个元素来确定类型;其次,我无法使用 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
}