You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:BeanListHandler映射数据库Timestamp列获毫秒时间戳转存储格式

解决方案

首先明确:数据库的Timestamp类型本质存储的是毫秒级时间戳,并非字符串格式。你拿到的java.sql.Timestamp对象本身包含完整时间信息,只是默认输出为毫秒形式。要直接映射成yyyy-MM-dd HH:mm:ss.SSS格式的字符串,需要自定义Apache DbUtils的类型转换逻辑,具体实现如下:

方法1:自定义RowProcessor

将Bean中对应Timestamp列的字段类型改为String,通过自定义RowProcessor实现Timestamp到指定格式字符串的转换:

1. 实现自定义RowProcessor

import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.RowProcessor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class CustomRowProcessor extends BasicRowProcessor {
    // Java 8+线程安全的日期格式化器
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    @Override
    public Object processColumn(ResultSet rs, int index, Class<?> propType) throws SQLException {
        Object value = super.processColumn(rs, index, propType);
        // 当Bean字段为String,且数据库返回Timestamp时,格式化输出
        if (value instanceof Timestamp && propType == String.class) {
            return DATE_FORMATTER.format(((Timestamp) value).toLocalDateTime());
        }
        return value;
    }
}

2. 使用自定义处理器

// 初始化自定义处理器
RowProcessor customProcessor = new CustomRowProcessor();
// 创建携带自定义处理器的BeanListHandler
BeanListHandler<YourBean> handler = new BeanListHandler<>(YourBean.class, customProcessor);
// 执行查询获取结果
List<YourBean> beanList = queryRunner.query(yourSqlStatement, handler);

方法2:自定义BeanProcessor

通过自定义BeanProcessor注册类型映射规则,更灵活控制数据库类型到Bean字段的转换:

1. 实现自定义BeanProcessor

import org.apache.commons.dbutils.BeanProcessor;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

public class CustomBeanProcessor extends BeanProcessor {
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public CustomBeanProcessor() {
        // 注册数据库TIMESTAMP类型到String的映射(不同数据库类型名可能有差异)
        super(getTypeMapping());
    }

    private static Map<String, Class<?>> getTypeMapping() {
        Map<String, Class<?>> typeMap = new HashMap<>();
        // MySQL用"TIMESTAMP",Oracle可能用"TIMESTAMP(3)",需根据实际调整
        typeMap.put("TIMESTAMP", String.class);
        return typeMap;
    }

    @Override
    protected Object convert(Class<?> propType, Object value) throws SQLException {
        if (value instanceof Timestamp && propType == String.class) {
            return DATE_FORMATTER.format(((Timestamp) value).toLocalDateTime());
        }
        return super.convert(propType, value);
    }
}

2. 组合处理器并使用

// 初始化自定义BeanProcessor
BeanProcessor beanProcessor = new CustomBeanProcessor();
// 创建包含自定义BeanProcessor的RowProcessor
RowProcessor rowProcessor = new BasicRowProcessor(beanProcessor);
// 创建BeanListHandler并执行查询
BeanListHandler<YourBean> handler = new BeanListHandler<>(YourBean.class, rowProcessor);
List<YourBean> beanList = queryRunner.query(yourSqlStatement, handler);

注意事项

  • 不同数据库的Timestamp类型名称可能不同,比如Oracle毫秒级Timestamp为TIMESTAMP(3),需根据数据库类型调整getTypeMapping中的键值。
  • 若使用Java 8以下版本,可替换为SimpleDateFormat,但需注意它是非线程安全的,建议用ThreadLocal包裹避免并发问题。

内容的提问来源于stack exchange,提问作者Sijo Kurien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:07:43