程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Spring JDBC + Postgres SQL + Java 8-从/到LocalDate的转换大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Spring JDBC + POSTGRes SQL + Java 8-从/到LocalDate的转换?

开发过程中遇到Spring JDBC + POSTGRes SQL + Java 8-从/到LocalDate的转换的问题如何解决?下面主要结合日常开发的经验,给出你关于Spring JDBC + POSTGRes SQL + Java 8-从/到LocalDate的转换的解决方法建议,希望对你解决Spring JDBC + POSTGRes SQL + Java 8-从/到LocalDate的转换有所启发或帮助;

jeP 170:JDBC 4.2定义了对JDBC的新的Date&Date API支持。POSTGRes 下载页面与JDBC 4.2新功能的兼容性仅从POSTGRes 9.4版本开始,因此某些兼容性挑战将通过使用具有较旧驱动程序的新API弹出。

setobject(1, new java.util.Date());在Postgres中,Even 被相同的约束所拒绝(MysqL很高兴地接受了它),不仅是新的API,如LocalDate。有些行为将取决于实现,因此只能java.sql.*保证(大致而言)。

至于Spring JDBC框架,我认为重写其行为可以绕过它,而不必以后再后悔。对于您已经做过的事情,我建议采取一种稍微不同的方法:

  1. 扩展BeanPropertysqlParametersource行为以使用新的日期和时间API,以及在需要时与其他与参数输入相关联的类一起使用(我不熟悉该Spring API)。
  2. 将已经被覆盖的行为提取BeanPropertyRowMapper到另一个类中以进行提取操作。
  3. 用工厂模式或实用程序类将它们包装起来,因此您无需再次查看它。

这样,如果支持API,则可以增强将来的重构功能,并减少开发过程中所需的代码量。

您还可以查看一些DAO方法。

解决方法

我正在使用PostgreS SQL 9.2,带有4.0.5版本的Spring JDBC和Java8。Java8
引入了新的日期/时间API,我想使用它,但是遇到了一些困难。我已经创建了表TABLE_A:

create table "TABLE_A"
(
  new_date date,old_date date
)

我正在使用Spring JDBC与数据库进行通信。我创建了Java类,它对应于此表:

public class TableA
{
    private LocalDate newDate;
    private Date oldDate;
    //getters and setters

}

这是我的代码,负责插入新行:

public void create(TableA tableA)
{
    BeanPropertySqlParametersource parametersource = new BeanPropertySqlParametersource(tableA);
    final String sql = "INSERT INTO public.TABLE_A (new_date,old_datE) values(:newDate,:oldDatE)";
    namedJdbcTemplate.update(sql,parametersourcE);

}

当我执行此方法时,出现异常:

org.POSTGResql.util.PSQLException: Can't infer the SQL type to use for an instance of java.time.LocalDate. Use setObject() with an explicit Types value to specify the type to use.

所以我更新了BeanPropertySqlParametersource的创建:

BeanPropertySqlParametersource parametersource = new BeanPropertySqlParametersource(tableA);
parametersource.registerSqlType("newDate",Types.DATE);

更改之后,我可以插入行。但是接下来,我想从数据库中获取行。这是我的方法:

public List<TableA> getAll()
{
    final String sql = "SELEct * from public.TABLE_A";
    final BeanPropertyRowMapper<TableA> rowMapper = new BeanPropertyRowMapper<TableA>(TableA.class);
    return namedJdbcTemplate.query(sql,rowMapper);
}

当然我也有例外:

...
at org.springframework.beans.beanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:474)
at org.springframework.beans.beanWrapperImpl.convertForProperty(BeanWrapperImpl.java:511)
at org.springframework.beans.beanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1119)
at org.springframework.beans.beanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:902)
at org.springframework.jdbc.core.beanPropertyRowMapper.mapRow(BeanPropertyRowMapper.java:255)
...
Caused by: java.lang.IllegalStateException: CAnnot convert value of type [java.sql.Date] to required type [java.time.LocalDate] for property 'newDate': no matching editors or conversion strategy found.

所以我更新了我的代码,这次是BeanPropertyRowMapper,我已经将转换服务添加到了bean包装器中,该服务能够执行从java.sql.Date到java.time.LocalDate的转换。

public List<TableA> getAll()
{
    final String sql = "SELEct * from public.TABLE_A";
    final BeanPropertyRowMapper<TableA> rowMapper = new BeanPropertyRowMapper<TableA>(TableA.class)
    {
        @Override
        protected void initBeanWrapper(BeanWrapper bw) {
            super.initBeanWrapper(bw);
           bw.setConversionservice(new Conversionservice() {
               @Override
               public Boolean canConvert(Class<?> aClass,Class<?> aClass2) {
                   return aClass == java.sql.Date.class && aClass2 == LocalDate.class;
               }

               @Override
               public Boolean canConvert(TypeDescriptor typeDescriptor,TypeDescriptor typeDescriptor2) {
                   return canConvert(typeDescriptor.getType(),typeDescriptor2.getType());
               }

               @Override
               public <T> T convert(Object o,Class<T> tClass) {
                   if(o instanceof Date && tClass == LocalDate.class)
                   {
                       return (T)((DatE)o).toLocalDate();
                   }

                   return null;


       }

           @Override
           public Object convert(Object o,TypeDescriptor typeDescriptor,TypeDescriptor typeDescriptor2) {
               return convert(o,typeDescriptor2.getType());
           }
       });
    }
}   ;

return namedJdbcTemplate.query(sql,rowMapper);

现在一切正常,但是非常复杂。
实现这一目标是否更简单?一般来说, 我想在Java代码中对LocalDate进行操作,因为它更加方便,并且能够将其持久化到database
。我希望它应该默认启用。

大佬总结

以上是大佬教程为你收集整理的Spring JDBC + Postgres SQL + Java 8-从/到LocalDate的转换全部内容,希望文章能够帮你解决Spring JDBC + Postgres SQL + Java 8-从/到LocalDate的转换所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。