joda time使用中遇到的问题

本文主要介绍在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>

这样持久层与数据库的日期映射就完成了。

坚持原创技术分享,您的支持将鼓励我继续创作!
分享到: