spring—在java中使用“dozer”将日期/时间字符串Map到java.sql.timestamp并保存在db中,这样写时间就是00:00:00.000000

jfewjypa  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(330)

我有一个spring批处理应用程序(https://spring.io/projects/spring-batch)从.csv文件中读取逗号分隔的数据,然后将每个列Map到特定的java类bean,然后将其保存到数据库(postgres)。我的问题是,其中一个日期/时间列(称为end \dt)正在使用日期/时间的不正确时间部分写入数据库。您可以看到日期部分被正确读取(2023-04-15),但时间只是写为00:00:00.000000

更深入一点的步骤是:
spring批处理应用程序读入有多列的.csv文件,这个问题的关键是end\u dt,
在\u dt列的末尾,输入一个字符串,格式为 dd-mmm-YYYY HH:mm:ss (即29-apr-2099 23:59:59)使用以下方法解析:

private String getDateTimeString(String dateString) {

        SimpleDateFormat sdfTo = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
        SimpleDateFormat sdfFrom = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
        String formattedDateTimeStr = null;

            if (StringUtils.isNotEmpty(dateString)) {
                formattedDateTimeStr = sdfTo.format(sdfFrom.parse(dateString));
          }

        return formattedDateTimeStr;
}

然后它接受这个解析日期/时间字符串并将其保存到我们将调用damasterrecord的数据类/javabean中,保存excel(.csv)文件中的所有列值
然后使用dozer,将数据类damasterrecord中的这些值Map到使用hibernate/jpa的实体类,该实体类将字符串date/time转换为java.sql.timestamp数据类型,即。

@Entity
@Table(name = "blah_blah_blah", schema = "some_schema", catalog = "some_catalog")
// code inbetween

public class MyRandomClassEntity {
  private Timestamp endDt;

// more stuff
}

我知道damasterrecord数据类中的日期/时间字符串解析正确,因为我可以在调试器中看到它。就在dozer框架中调用mapper接口方法“mapper”之后,我通过调试器在entity类中看到错误的日期/时间。所以我不太确定dozer是如何进行Map的,但我猜dozer何时将字符串“dd-mmm-yyyy hh:mm:ss”Map到java.sql.timestamp数据类型,因为某些原因,它没有正确Map日期/时间字符串的“time”部分(它只做00:00:00.000000)。有人知道怎么解决这个问题吗?有很多接口和重写的方法,所以我还没有确定这种Map发生在哪里。

disho6za

disho6za1#

我能够解决这个问题,并将张贴我的答案在这里。我还想声明这是一个遗留应用程序(实际上并不太旧),但它使用了“timestamp”和“simpledateformat”(java8api之前的更新)等类,因此我的目的是以最小的努力解决这个问题/bug/问题,而不必重新编写应用程序。希望这对有类似应用程序/业务问题的任何其他开发人员都有用。
所以我第一次尝试延长推土机的速度 DozerConverter<String, LocalDateTime> 类为这个字符串->localdatetime对象创建我自己的自定义转换器。但是,在尝试Map数据库列使用的localdatetime对象->java.sql.timestamp数据类型时,我遇到了dozer抛出异常的问题。我们还有一个包含所有数据库配置的repo,所以我也不想进入这个依赖关系并编辑代码(这可能会破坏更多依赖它的组件),所以我暂时放弃了这个想法。
当您使用这样的自定义转换文件时,dozer有一个.xml(在您的资源目录中)文件,您必须将此转换器附加到要Map的特定字段,例如:

<field custom-converter="com.mydomainname.my.namespace.MyCustomConverter">
     <a>theColumnNameIamMappingFrom</a>
     <b>theColumnNameIamMappingTo</b>
</field>

我还尝试将datetime字符串的格式保留为“yyyy-mm-dd hh:mm:ss”,这是时间戳的格式。但是,每次它Map到我的数据库/实体类时,它总是出于某种原因将时间部分“剪切”到00:00:00.000000。
最后一个解决方案是第1个方案的一个变体,我创建了一个自定义转换器,但这次将它转换为 java.sql.Timestamp 数据类型。我试图避免使用这些旧的遗留类,但代码的其他部分似乎与之紧密耦合,我不想破坏一切。不管怎样,它成功了,我终于可以看到db将时间戳保存为完整的日期和时间。

2020-08-31 23:59:59.123456

如果其他人有类似的问题,希望这能帮助他们。推土机有点奇怪,但你可以在这里了解更多:https://www.baeldung.com/dozer

相关问题