2017-01-06 5 views
0

После этой темы в PostgreSQL JDBC driver Я ищу элегантный способ использования возможностей кеширования MyBatis для ResultSet, содержащих sql.Array.Правильный способ использования кеширования sql.Array в MyBatis

Отрывок из MyBatis documentation:

Кэш чтения-записи будет возвращать копию (с помощью сериализации) кэшированных объекта.

С MyBatis могут только объекты кэша, который реализует Serializable интерфейс и ни sql.Array интерфейс не делает продлить его, ни PgArray в моем конкретном случае это реализовать, MyBatis бросает org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException при запросе на ResultSet содержащий array или результат array_agg() function.

Что было бы предпочтительным способом достижения кеширования в этом сценарии?

Могу ли я использовать javax.sql.rowset.serial.SerialArray в сочетании с MyBatis ResultMap collection or association?

например.

<association property="values" column="myArrayColumn" javaType="ArrayList" jdbcType ="SerialArray"/> 

ответ

0

Насколько я понимаю, столбец в вашем результирующем наборе имеет тип SQL Array. И вы хотите выполнить один и тот же запрос с одинаковыми параметрами несколько раз в сеансе, на самом деле попали в базу данных в первый раз и затем попали в кеш.

Ассоциация Mybatis используется для сопоставления строкой результата результата с строкой объекта. Цель коллекции Mybatis состоит в том, чтобы сопоставить несколько строк результатов, вложенных в объект (например: выберите родительский элемент и дочерние элементы). здесь не действуют. Вот этот массив/коллекция элементов, но встроенный в столбцы для каждой строки.

Вы не должны беспокоиться о кешировании 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, который закрыт после того, как она забирается и в зависимости от Подготовлено Утверждение закрыто.

Результат, который кэшируется, представляет собой совокупность объекта отображаемого типа результата, который должен быть сериализуемым.