简体   繁体   English

Mybatis中如何使用动态SQL比较MySQL二进制UUID

[英]How to compare MySQL binary UUID using dynamic SQL in Mybatis

We store one of the UUID values as binary(16) in mysql db.我们在 mysql db 中将其中一个 UUID 值存储为binary(16)

spec规格

 MyTable myTable = new MyTable();` //table
 SqlColumn<Long> id = column("id");` // id column
 SqlColumn<UUID> myUuidColumn = column("my_uuid");` //uuid column

Dynamic sql query for select.动态sql查询select。

            select(myTable.id)
                .from(myTable)
                .where(myTable.myUuidColumn, isEqualTo(UUID.fromString("e59bf2fd-e742-4314-ab02-db195e0168c8")))
                .build()
                .render(RenderingStrategies.MYBATIS3);

But this is not working, probably due to UUID is not being natively supported.但这不起作用,可能是因为 UUID 不受本机支持。 How to fix this other than changing the mapper to use plain sql query?除了将映射器更改为使用普通 sql 查询之外,如何解决此问题?

You need to write a custom type handler.您需要编写自定义类型处理程序。
The implementation depends on the driver and/or the column type.实现取决于驱动程序和/或列类型。
Here is the type handler implementation for your usage (ie BINARY(16) ).这是您使用的类型处理程序实现(即BINARY(16) )。

import java.nio.ByteBuffer;
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.MappedJdbcTypes;

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

  private static byte[] uuidToBytes(UUID uuid) {
    ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
    bb.putLong(uuid.getMostSignificantBits());
    bb.putLong(uuid.getLeastSignificantBits());
    return bb.array();
  }

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

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

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

  private static UUID bytesToUuid(byte[] bytes) {
    if (bytes == null) {
      return null;
    }
    ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
    Long high = byteBuffer.getLong();
    Long low = byteBuffer.getLong();
    return new UUID(high, low);
  }
}

To register the type handler globally...要全局注册类型处理程序...

  • if you are using mybatis-spring-boot , specify mybatis.type-handlers-package in your application.properties .如果您使用的是 mybatis mybatis-spring-boot ,请在您的application.properties中指定mybatis.type-handlers-package
  • if you are not using spring-boot, set typeHandlersPackage or typeHandlers property of SqlSessionFactoryBean .如果您不使用 spring-boot,请设置SqlSessionFactoryBeantypeHandlersPackagetypeHandlers属性。

If, for some reason, you cannot register the type handler globally, you may have to pass the fully-qualified-name of the type handler when initializing the SqlColumn<UUID> myUuidColumn .如果由于某种原因无法全局注册类型处理程序,则在初始化SqlColumn<UUID> myUuidColumn时可能必须传递类型处理程序的完全限定名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM