Используйте неявный TypeHandler на основе resultType для select в MyBatis
Я пытаюсь выбрать временную метку в MyBatis и вернуть ее как LocalDateTime (от joda-time).
моя конфигурация отлично работает, если я попытаюсь вернуть результат как java.sql.Timestamp
. Я доказал, что мой обработчик типов работает нормально: если я использую класс упаковки с LocalDateTime
как только поле и resultMap в файле MyBatis mapper, я получаю правильные результаты.
однако, когда я пытаюсь указать org.joda.time.LocalDateTime
as resultType
для этого выберите, я всегда получаю null
, а если типа обработчик игнорируется.
насколько я понимаю, MyBatis использует typeHandler по умолчанию в случае я resultType="java.sql.Timestamp"
. Как следствие, я ожидал, что он будет использовать один из typeHandlers, которые я настроил при встрече resultType="org.joda.time.LocalDateTime"
.
Я что-то пропустил? Есть ли способ использовать мой typeHandler или я вынужден сделать класс-оболочку и resultMap? Это мое резервное решение, но я хотел бы избежать его, если это возможно.
любая помощь ценится. Благодарить вы.
mybatis-config.в XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeHandlers>
<typeHandler javaType="org.joda.time.LocalDate" jdbcType="DATE" handler="...LocalDateTypeHandler"/>
<typeHandler javaType="org.joda.time.LocalDateTime" jdbcType="TIMESTAMP" handler="...LocalDateTimeTypeHandler"/>
</typeHandlers>
</configuration>
NotifMailDao.java
import org.joda.time.LocalDateTime;
public interface NotifMailDao {
LocalDateTime getLastNotifTime(String userId);
}
NotifMailDao.в XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="lu.bgl.notif.mail.dao.NotifMailDao">
<select id="getLastNotifTime" resultType="org.joda.time.LocalDateTime">
SELECT current_timestamp
AS last_time
FROM DUAL
</select>
</mapper>
1 ответов
чтобы использовать конфигурацию TypeHandler, MyBatis должен знать как тип Java результирующего объекта, так и тип SQL исходного столбца.
здесь мы используем resultType
на <select />
таким образом, MyBatis знает тип Java, но он не может знать тип SQL, если мы его не установим. Единственный способ-использовать <resultMap />
.
решение
вам нужно создать Bean с одним полем, содержащим объект, который вы хотите вернуть (назовем это поле time
) и использовать <resultMap />
:
<select id="getLastNotifTime" resultMap="notifMailResultMap">
<resultMap id="mapLastTime" type="MyWrapperBean">
<result property="time" column="my_sql_timestamp" javaType="org.joda.time.LocalDateTime"
jdbcType="TIMESTAMP" />
</resultMap>
если вы хотите сэкономить на создании выделенного компонента, вы также можете использовать атрибут type=hashmap
на <resultMap />
как было предложено Shobit.
вариант: установите свойство на LocalDateTime
A решение было предложено на Google Groups, который устанавливает непосредственно информацию о LocalDateTime
.
мое понимание этого (пожалуйста, прокомментируйте, если я ошибаться) заключается в том, что он устанавливает свойство LocalDateTime
. Я не ручаюсь за это, так как не нахожу соответствующего в API doc (и я не тестировал его), но не стесняйтесь использовать его, если вы считаете его лучше.
<resultMap id="mapLastTime" type="org.joda.time.LocalDateTime">
<result property="lastTime" column="my_sql_timestamp" javaType="org.joda.time.LocalDateTime"
jdbcType="TIMESTAMP" />
</resultMap>
почему он работает с java.sql.Timestamp
Timestamp
является стандартным типом Java для SQL, с реализацией JDBC по умолчанию (ResultSet.getTimestamp(int/String)
). Обработчик по умолчанию для MyBatis использует этот getter1 и, следовательно, не нужно любое отображение TypeHandler. Я ожидаю, что это происходит каждый раз, когда вы используете один из обработчиков по умолчанию.
1: это догадка. Требуется цитата!
этот ответ только ждет замены на что-то лучшее. Пожалуйста, внесите свой вклад!