在PostgreSQL JDBC driver中关注此主题后,我正在寻找一种优雅的方法来利用包含sql.Array的ResultSet
的MyBatis内置缓存功能。
读写缓存将返回缓存对象的副本(通过序列化)。
由于MyBatis只能缓存实现Serializable
接口的对象,并且sql.Array
接口没有扩展它,在我的特定情况下PgArray
也没有实现它,MyBatis抛出
查询包含array array_agg() function或javax.sql.rowset.serial.SerialArray结果的org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException
时的ResultSet
。
在这种情况下,实现缓存的首选方法是什么?
我可以将MyBatis ResultMap collection or association与{{3}}结合使用吗?
e.g。
<association property="values" column="myArrayColumn" javaType="ArrayList" jdbcType ="SerialArray"/>
答案 0 :(得分:0)
据我所知,结果集中的列是SQL Array类型。 并且您希望在会话中多次使用相同的参数执行相同的查询,实际上第一次点击数据库然后点击缓存。
Mybatis关联用于将平面结果行映射到对象结构。 Mybatis集合的目的是映射嵌套在对象中的多个结果行(例如:select parent和children)。 这两个都不适用于此。 这是一个元素的数组/集合,但是在每列的列中内联。
您不必担心缓存SQL数组:您必须将其映射到结果类型并忘记它。
然后延伸org.apache.ibatis.type.BaseTypeHandler
:
@Override
public final Object getNullableResult(final ResultSet resultSet, final String columnName) throws SQLException {
LOGGER.debug("getNullableResult - resultSet/columnName");
final Array array = resultSet.getArray(columnName);
return array.getArray();
}
@Override
public final Object getNullableResult(final ResultSet resultSet, final int columnIndex) throws SQLException {
LOGGER.debug("getNullableResult - resultSet/columnIndex");
final Array array = resultSet.getArray(columnIndex);
return array.getArray();
}
这里返回的值是一个基本的java数组,但你可以列出或构建你想要的任何结构。
引用要在resultMap中使用的类型处理程序:
<result column="arrayColumnName" property="destinationProperty" typeHandler="yourArrayTypeHandlerClass.fullQualifiedName" />
SQL数组无法序列化:这是一种资源:它取决于 ResultSet 在获取后关闭,并取决于 PreparedStatement 关闭。
缓存的结果是映射的结果类型的对象集合,应该是可序列化的。