java - mybatis中如何选择文本数组类型的结果?

标签 java postgresql mybatis

例如,有一个表,其中有一列类型为text[] ,在 PostgreSQL 中:

CREATE TABLE t
(
    id integer,
    name text,
    tags text[],
    PRIMARY KEY (id)
)

现在,我想选择tags有两种方式:

  1. 选择tags使用主键id ,结果应为 List<String> 类型
  2. 选择tags使用name ,结果应为 List<List<String>> 类型

我应该如何编写 MyBatis 映射器来实现这一点?

最佳答案

您仍然可以使用 Java 映射器,但是,当返回类型为 List 时,MyBatis 内部会调用 SqlSession#selectList,而这不是您想要的。
因此,您需要使用 Object 作为返回类型。

@Select("select tags from t where id = #{id}")
Object getTagById(Integer id);

@Select("select tags from t where name = #{name}")
List<Object> getTagByName(String name);

并在配置中全局注册您的类型处理程序。即

<typeHandlers>
  <typeHandler handler="xxx.yyy.ListArrayTypeHandler" />
</typeHandlers>

configuration.getTypeHandlerRegistry()
  .register(ListArrayTypeHandler.class);

为了完整起见,这里是一个示例类型处理程序实现。

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

@MappedJdbcTypes({ JdbcType.ARRAY })
@MappedTypes({ Object.class })
public class ListArrayTypeHandler extends BaseTypeHandler<List<?>> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i,
      List<?> parameter, JdbcType jdbcType) throws SQLException {
    //  JDBC type is required
    Array array = ps.getConnection().createArrayOf("TEXT", parameter.toArray());
    try {
      ps.setArray(i, array);
    } finally {
      array.free();
    }
  }

  @Override
  public List<?> getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return extractArray(rs.getArray(columnName));
  }

  @Override
  public List<?> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return extractArray(rs.getArray(columnIndex));
  }

  @Override
  public List<?> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return extractArray(cs.getArray(columnIndex));
  }

  protected List<?> extractArray(Array array) throws SQLException {
    if (array == null) {
      return null;
    }
    Object javaArray = array.getArray();
    array.free();
    return new ArrayList<>(Arrays.asList((Object[])javaArray));
  }
}

仅供引用,要将List存储到tags列中,您可能必须显式指定类型处理程序。

insert into t (...) values (#{id}, #{name},
  #{tags,typeHandler=xxx.yyy.ListArrayTypeHandler})

关于java - mybatis中如何选择文本数组类型的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55931078/

相关文章:

postgresql - 在没有 SET_SRID 的情况下将 ST_Intersects 与 ST_MakePoint 结合使用

java - MyBatis 生成器 setDistinct(true)

java - 在MyBatis中插入子对象

java - 创建按钮网格

java - 如何正确设置 Getters setters 和 conversionmintosec?

Java 处理国际文件。编码的东西

java - 什么是 .struts-config.xml.strutsdia 文件?

ruby-on-rails - Rails CSV 导入导致带有前导 0 的数字困惑

sql - 对于 PostgreSQL 中的 boolean 数据类型,输出 "yes/no"而不是 "t/f"

java - 如何使用 MyBatis (Java) 在 postgres 中设置 INSERT 查询的超时