本文主要介绍在Joda DateTime使用过程中遇到的一些问题,包括 Joda DateTime字段配置Json序列化格式,Mybatis持久化层用Joda DateTime与Timestamp映射。
Joda DateTime字段配置Json序列化格式
Joda DateTime字段如果不做json序列化处理,再转为json时会带有DateTime类本身的属性信息造成冗余,同时没有格式化处理,使用不友好。
首先在maven需要额外引入包:
1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> <version>2.3.0</version> </dependency>
|
版本可以参考maven仓库自行修改。
然后自定义实现json序列化与反序列化处理,以下以“yyyy-MM-dd HH:mm:ss”格式输出为例:
序列化:
1 2 3 4 5 6 7 8 9 10
| public class CustomDateTimeSerializer extends JsonSerializer<DateTime> {
private final static DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
@Override public void serialize(DateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(value.toString(FORMATTER)); } }
|
反序列化:
1 2 3 4 5 6 7 8 9 10 11 12
| public class CustomDateTimeDeserializer extends JsonDeserializer<DateTime> {
private final static DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
@Override public DateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); String s = node.asText(); return DateTime.parse(s, FORMATTER); } }
|
最后在持久层对象的DateTime类型字段加上如下注解:
1 2 3
| @JsonSerialize(using = CustomDateTimeSerializer.class) @JsonDeserialize(using = CustomDateTimeDeserializer.class) private DateTime datetime;
|
搞定。
Mybatis持久化层用Joda DateTime与Timestamp映射
mybatis没有内置的typeHandler处理joda time类型,因此需要自定义DateTimeTypeHandler,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package com.qunar.echarts.util;
import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import org.joda.time.DateTime;
import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp;
public class DateTimeTypeHandler implements TypeHandler<DateTime> { @Override public void setParameter(PreparedStatement preparedStatement, int i, DateTime datetime, JdbcType jdbcType) throws SQLException { if (datetime != null) { preparedStatement.setTimestamp(i, new Timestamp(datetime.getMillis())); } else { preparedStatement.setTimestamp(i, null); } }
@Override public DateTime getResult(ResultSet resultSet, String s) throws SQLException { return toDateTime(resultSet.getTimestamp(s)); }
@Override public DateTime getResult(ResultSet resultSet, int i) throws SQLException { return toDateTime(resultSet.getTimestamp(i)); }
@Override public DateTime getResult(CallableStatement callableStatement, int i) throws SQLException { return toDateTime(callableStatement.getTimestamp(i)); }
private static DateTime toDateTime(Timestamp timestamp) { if (timestamp != null) { return new DateTime(timestamp.getTime()); } else { return null; } } }
|
然后在MyBtis的配置文件(我的mybatis-config.xml)中加入typeHandler配置项,如下
1 2 3
| <typeHandlers> <typeHandler javaType="org.joda.time.DateTime" jdbcType="TIMESTAMP" handler="com.qunar.echarts.util.DateTimeTypeHandler"/> </typeHandlers>
|
注意在配置项中指定javaType类型,或在自定义DateTImeTypeHandler类顶部加入注解@MappedTypes(DateTime.class),此外不要在配置项中指定jdbcType类型。如果不如此配置会报错。
接下来,在mybatis的XXXMapper.xml的<resultMap>中的日期字段加入typeHandler,如下配置(下面的datetime字段):
1 2 3 4 5
| <resultMap id="BaseResultMap" type="com.qunar.echarts.model.FlightMinuteModel"> <id column="id" property="id"/> <result column="datetime" property="datetime" typeHandler="com.qunar.echarts.util.DateTimeTypeHandler"/> <result column="order_num" property="orderNum"/> </resultMap>
|
这样持久层与数据库的日期映射就完成了。