从java.sql.Date到java.time.LocalDate的Hibernate本机SQL查询类型映射

时间:2018-11-06 06:06:17

标签: mysql hibernate spring-boot jpa

我正在使用Hibernate本机查询进行SELECT查询,如下所示:

public List<SomeDTO> findDTOs() {
    StringBuilder sql = new StringBuilder();
    sql.append(" SELECT id as id, localDateColumn as date, ");

    sql.append(" FROM t");
    Query query = entityManager.createNativeQuery(sql.toString());
    query.unwrap(SQLQuery.class)
        .addScalar("id", StandardBasicTypes.LONG)
        .addScalar("localDateColumn", DateType.INSTANCE)
        .setResultTransformer(Transformers.aliasToBean(SomeDTO.class));
    return query.getResultList();
  }

我尝试使用StandardBasicTypes.DATEDateType.INSTANCE无效。我知道映射java.sql.Types#DATEjava.util.Date很好。

我想知道如何将java.sql.Types#DATE映射到java.time.LocalDate

3 个答案:

答案 0 :(得分:1)

由于我没有使用Entity作为返回数据类型。 AttributeConverter在这种情况下没有用。 我通过在字段的设置器中将java.util.Date手动转换为java.time.LocalDate来解决此问题。

设置器将如下所示:

public void setLocalDateColumn(java.util.Date value){
    // convert into LocalDate
    // set
}

如果您在转换时得到UnsupportedOperationException。您可能仍将java.sql.Date包裹在java.util.Date中。这样做: Instant.ofEpochMilli(value.getTime()).atZone(DefaultZoneId).toLocalDate();

答案 1 :(得分:0)

您可以使用 AttributeConverter java.sql.Date映射到java.time.LocalDate

import java.sql.Date;
import java.time.LocalDate;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

    @Override
    public Date convertToDatabaseColumn(LocalDate localDate) {
        return (localDate == null ? null : Date.valueOf(localDate));
    }

    @Override
    public LocalDate convertToEntityAttribute(Date sqlDate) {
        return (sqlDate == null ? null : sqlDate.toLocalDate());
    }
}

详细信息:https://www.baeldung.com/jpa-attribute-converters

答案 2 :(得分:0)

您的方法有很多错误。

危险的SQL注入攻击

使用String串联构建SQL的方式非常冒险,并且可能会将您的应用程序暴露给SQL injection attacks

@Field("can_id")

更多,这甚至不正确,因为您在StringBuilder sql = new StringBuilder(); sql.append(" SELECT id as id, localDateColumn as date, "); sql.append(" FROM t"); Query query = entityManager.createNativeQuery(sql.toString()); 子句之前附加了,。如果要动态生成查询,则需要使用Criteria API

别名使用不正确

您将FROM列设置为localDateColumn别名,如下所示:

date

但是,当您使用sql.append(" SELECT id as id, localDateColumn as date, "); 设置休眠类型时,可以使用localDateColumn

addScalar

现在,根据您的问题标题,如果.addScalar("localDateColumn", DateType.INSTANCE) 是MySQL localDateColumn列类型,并且您想将其映射到DATE Java对象,则应这样做这个:

LocalDate