mybatis-plus icon indicating copy to clipboard operation
mybatis-plus copied to clipboard

TypeHandler 映射LocalDateTime 到BIGINT时,,使用lambda表达式,时间范围查询不生效

Open woqumaigejuzi opened this issue 3 years ago • 4 comments

当前使用版本(必填,否则不予处理)

   <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.3.3</version>
    </dependency>

该问题是如何引起的?(确定最新版也有问题再提!!!)

 LocalDateTime localDateTime = LocalDateTime.now().plusMinutes(-50);
 Long milliSecond = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();

普通查询时,时间范围条件生效,能得到规定时间内的数据: select * FROM ru_alarm_info WHERE (create_time >= '1634884156779')

  QueryWrapper<AlarmInfo> queryWrapper = new QueryWrapper<AlarmInfo>() .ge("create_time", milliSecond);

但是使用lambda表达式查询时,时间条件不生效!!!!!!!!!,会返回所有数据 打印出的sql是:select * FROM ru_alarm_info WHERE (create_time >= '2022-10-22T14:29:16.779')

 LambdaQueryWrapper<AlarmInfo> ge = new QueryWrapper<AlarmInfo>().lambda().ge(AlarmInfo::getCreateTime, localDateTime );      

自定义TypeHandler对象

@MappedJdbcTypes(JdbcType.BIGINT)
@MappedTypes(LocalDateTime.class)
public class DateToIntegerTypeHandler extends BaseTypeHandler<LocalDateTime> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime localDateTime, JdbcType jdbcType) throws SQLException {
        Long milliSecond = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        ps.setObject(i, milliSecond);
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet resultSet, String s) throws SQLException {
        Object object = resultSet.getObject(s);
        if (null == object) {
            return null;
        } else {
            return LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) object), ZoneId.systemDefault());
        }
    }
}

entity 对象:

public class AlarmInfo{

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
    @TableField(typeHandler = DateToIntegerTypeHandler.class)
    private LocalDateTime createTime;

}

重现步骤(如果有就写完整)

100 % 重现

报错信息

使用lambda 表达式时,打印出的sql未做时间转换,还是: select * FROM ru_alarm_info WHERE (create_time >= '2022-10-22T14:29:16.779')

理论上应该是: select * FROM ru_alarm_info WHERE (create_time >= '1634884156779')

woqumaigejuzi avatar Oct 22 '21 07:10 woqumaigejuzi

你那么写就和你注解无关了

miemieYaho avatar Oct 22 '21 08:10 miemieYaho

我也发现了这个问题嘛,查询时候typehandler不生效

ghost avatar Dec 20 '21 07:12 ghost

TypeHandler只用于存储或结果映射,目前不用于where条件

VampireAchao avatar Apr 20 '22 15:04 VampireAchao

TypeHandler只用于存储或结果映射,目前不用于where条件

TypeHandler失效的情况很多,更新也不生效,即使你配置了application.yml 即使你在TableName注解和TableField上加了TypeHandler,例如:

LambdaUpdateWrapper<NodeDO> updateWrapper = Wrappers.<NodeDO>lambdaUpdate();
        updateWrapper.eq(NodeDO::getId, nodeDO.getId())
                .set(NodeDO::getTagChain, tagChain);
        boolean result = this.update(nodeDO, updateWrapper);

应该是能存储映射的,实际不能

Jovons avatar Aug 31 '22 06:08 Jovons

wrapper 不能继承实体的注解,希望注意

qmdx avatar Dec 16 '22 04:12 qmdx