java - 如何在 MyBatis 中使用 UUID 类型处理程序和 @Many 注释?

标签 java mybatis spring-mybatis

我正在使用 mybatis-spring-boot-starter 2.1.0 版本。我需要处理 UUID 类型来获取嵌套集合。

 @Select("SELECT id, name FROM t_service s")
    @Results(value = {
            @Result(column = "id", property = "id", jdbcType = JdbcType.OTHER, typeHandler = UuidTypeHandler.class),
            @Result(column = "name", property = "name"),
            @Result(property = "rates", column = "id", javaType = List.class, many = @Many(select = "getAllRates"))
    })
    List<Service> findAll();

 @Select("SELECT date_from, date_to, currency FROM t_rate where t_rate.service_id = #{serviceId, javaType=java.util.UUID, jdbcType=OTHER, typeHandler=my.package.UuidTypeHandler}")
    @Results(value = {
            @Result(property = "dateFrom", column = "date_from"),
            @Result(property = "dateTo", column = "date_to"),
            @Result(property = "currency", column = "currency")
 })
    List<Rate> getAllRates(@Param("serviceId") UUID serviceId);

UuidTypeHandler:

@MappedJdbcTypes(JdbcType.OTHER)
@MappedTypes(UUID.class)
public class UuidTypeHandler extends BaseTypeHandler<UUID> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, UUID parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, parameter, jdbcType.TYPE_CODE);
    }

    @Override
    public UUID getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getObject(columnName, UUID.class);
    }

    @Override
    public UUID getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getObject(columnIndex, UUID.class);
    }

    @Override
    public UUID getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getObject(columnIndex, UUID.class);
    }
}

但我遇到以下异常:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'serviceId' in 'class java.util.UUID'

在其他情况下(直接调用方法时)UuidTypeHandler 工作正常,我没有任何问题

PostgreSQL 的解决方法:

 @Select("SELECT date_from, date_to, currency FROM t_rate where t_rate.service_id = #{serviceId}::uuid")
    @Results(value = {
            @Result(property = "dateFrom", column = "date_from"),
            @Result(property = "dateTo", column = "date_to"),
            @Result(property = "currency", column = "currency")
 })
    List<Rate> getAllRates(@Param("serviceId") String serviceId);

最佳答案

要使其工作,您需要在配置中全局注册类型处理程序(这是一种限制)。
在您的情况下,将 mybatis.type-handlers-package=my.package 添加到 application.properties 就足够了。

一旦类型处理程序在全局注册,大多数情况下您可以在映射器中省略 typeHandler

@Select("SELECT id, name FROM t_service s")
@Results(value = {
  @Result(column = "id", property = "id"),
  @Result(column = "name", property = "name"),
  @Result(property = "rates", column = "id",
    javaType = List.class, many = @Many(select = "getAllRates"))
})
List<Service> findAll();

@Select("SELECT date_from, date_to, currency FROM t_rate where t_rate.service_id = #{serviceId}")
@Results(value = {
  @Result(property = "dateFrom", column = "date_from"),
  @Result(property = "dateTo", column = "date_to"),
  @Result(property = "currency", column = "currency")
})
List<Rate> getAllRates(@Param("serviceId") UUID serviceId);

类型处理程序也可以更简单一点。

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;

// no @MappedJdbcTypes
@MappedTypes(UUID.class)
public class UuidTypeHandler extends BaseTypeHandler<UUID> {
  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, UUID parameter, JdbcType jdbcType) throws SQLException {
    ps.setObject(i, parameter); // no 3rd arg
  }

  @Override
  public UUID getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return rs.getObject(columnName, UUID.class);
  }

  @Override
  public UUID getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return rs.getObject(columnIndex, UUID.class);
  }

  @Override
  public UUID getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return cs.getObject(columnIndex, UUID.class);
  }
}

关于java - 如何在 MyBatis 中使用 UUID 类型处理程序和 @Many 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60613619/

相关文章:

java - Jasmine 汇编器 : 'l2d' Instruction Giving "java.lang.VerifyError: ... Attempt to split long or double on the stack"

java - JSF 真的准备好迎接高性能社交网络项目了吗?

Java:访问相同的ArrayList,同时使用该ArrayList中的其余元素

mysql - 无限滚动的myBatis偏移位置设置问题

java - Mybatis执行存储过程时无法设置OUT参数

java - 提取 DatabaseMetaData 时出错;嵌套异常是 com.mysql.jdbc.exceptions.jdbc4。连接关闭后不允许进行任何操作

java - 谁能解释为什么 4 个日历中有 1 个显示 Time=?

java - Java中有没有办法将多个参数对传递给一个方法?

java - Mybatis - 未映射的继承属性

java - 获取删除触发器的当前用户 - Spring MyBatis - Liquibase