概述
背景
项目中使用MySQL数据库,然后用mybatis做数据持久化。最近使用时,想把一些model类的gmtCreate、gmtModified等字段从java.util.Date 改成java8的java.time.LocalDateTime,此类是不可变类,且自带很好用的日期函数api。
原本依赖如下:
compile "org.mybatis:mybatis:3.3.0"
compile "org.mybatis:mybatis-spring:1.2.5"
compile "org.mybatis.generator:mybatis-generator-core:1.3.2"
直接修改代码有两两个问题:
1. mapper、model、xml文件都是用generator插件生成,维护成本高。
2. 会报错如下:
Caused by: java.lang.IllegalStateException: No typehandler found for property createTime
at org.apache.ibatis.mapping.ResultMapping$Builder.validate(ResultMapping.java:151)
at org.apache.ibatis.mapping.ResultMapping$Builder.build(ResultMapping.java:140)
at org.apache.ibatis.builder.MapperBuilderAssistant.buildResultMapping(MapperBuilderAssistant.java:382)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildResultMappingFromContext(XMLMapperBuilder.java:378)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:280)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244)
at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116)
修改
首先,添加了以下依赖:(jsr310是java规范310)
compile "org.mybatis:mybatis-typehandlers-jsr310:1.0.2"
接着,在mybatis-config.xml 中添加如下配置:(该配置来源于官网)
<typeHandlers>
<!-- ... -->
<typeHandler handler="org.apache.ibatis.type.InstantTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.LocalTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.OffsetDateTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.OffsetTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.ZonedDateTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.YearTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.MonthTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.YearMonthTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.JapaneseDateTypeHandler" />
</typeHandlers>
看了文档发现需要mybatis 3.4.0版本
compile "org.mybatis:mybatis:3.4.0"
不过这里有个问题了,会出现版本不兼容问题,报错如下:
java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()Ljava/lang/Integer;
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
查看发现 SpringManagedTransaction未实现Transaction中的getTimeout() 方法
/**
* Wraps a database connection.
* Handles the connection lifecycle that comprises: its creation, preparation, commit/rollback and close.
*
* @author Clinton Begin
*/
public interface Transaction {
/**
* Retrieve inner database connection
* @return DataBase connection
* @throws SQLException
*/
Connection getConnection() throws SQLException;
/**
* Commit inner database connection.
* @throws SQLException
*/
void commit() throws SQLException;
/**
* Rollback inner database connection.
* @throws SQLException
*/
void rollback() throws SQLException;
/**
* Close inner database connection.
* @throws SQLException
*/
void close() throws SQLException;
}
查了文档发现:Spring版本跟Mybatis版本有个对照表要满足,详情见官网
而我需要的mapper.xml文件类似如下:
<mapper namespace="com.my.MyMapper">
<resultMap id="BaseResultMap" type="com.my.MyModel">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="gmt_create" jdbcType="OTHER" property="gmtCreate" typeHandler="org.apache.ibatis.type.LocalDateTimeTypeHandler"/>
</resultMap>
<!--- 省略 --->
</mapper>
之后,查了generator的官方文档,发现还是可以通过generator.xml的配置文件做到的。
<table tableName="my_table" domainObjectName="MyModel">
<generatedKey column="id" sqlStatement="JDBC" identity="true"/>
<columnOverride column="gmt_create" property="gmtCreate" typeHandler="org.apache.ibatis.type.LocalDateTimeTypeHandler" jdbcType="OTHER" javaType="java.time.LocalDateTime" />
<columnOverride column="gmt_modified" property="gmtModified" typeHandler="org.apache.ibatis.type.LocalDateTimeTypeHandler" jdbcType="OTHER"
<!-- 省略其他 -->
</table>
这里解释下:
columnOverride将数据库中的字段重命名为实体类的属性
column:数据库中字段名
property:POJO属性名
javaType:POJO类型,这里用的是java.time.LocalDateTime
jdbcType:数据库字段类型,SQL中是timestamp,但这里要写OTHER,否则typehandler不处理
typehandler:帮我们处理类型的
此时再用generator生成的mapper.xml就是我想要的了
扩展
严格来说生成的mapper.xml是不能修改的。可实际中,很多时候需要我们再手写自定义的查询。此时可以再生成一个扩展的xml文件。或者在generator里面配置插件也会生成一个空的:
mybatis-ext
转义字符
在xml里面有些表达式是不允许的,需要转义:
含意思 | 原符号 | 转义后 |
小于号 | < | < |
小于等于 | <= | <= |
大于号 | > | > |
大于等于 | >= | >= |
和 | & | & |
单引号 | ‘ | ' |
双引号 | “ | " |
最后
以上就是仁爱酒窝为你收集整理的MyBatis中使用LocalDateTime的全部内容,希望文章能够帮你解决MyBatis中使用LocalDateTime所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复