Mysql 5.7新增json類型對應的Mybatis TypeHandler

歡迎使用Markdown編輯器

Mysql 5.7中新增了Json類型,但是Mybatis中並沒有很好地支持,必須自己編寫TypeHandler進行處理。

TypeHandler

@MappedJdbcTypes(JdbcType.OTHER)
@MappedTypes(GeoPoint.class)
public class GeoPointTypeHandler extends BaseTypeHandler<GeoPoint> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, GeoPoint parameter, JdbcType jdbcType) throws SQLException {

    }

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

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

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

    private GeoPoint bytes2GeoPoint(byte[] bytes) {
        if (bytes != null && bytes.length == 25) {
            double lon = bytes2Double(bytes, 9);
            double lat = bytes2Double(bytes, 17);

            return new GeoPoint(lat, lon);
        } else {
            return null;
        }
    }

    private double bytes2Double(byte[] bytes, int start) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value |= ((long) (bytes[start + i] & 0xff)) << (8 * i);
        }
        return Double.longBitsToDouble(value);
    }
}

在getNullableResult中,我們對Mysql中取出的byte[]進行解析,取出經緯度數據,轉換爲GeoPoint類型。但是插入操作仍然需要在mapper.xml文件中手動修改,見下文。

mybstis-config.xml

<typeHandlers>
        <typeHandler handler="com.test.GeoPointTypeHandler"
                     javaType="org.elasticsearch.common.geo.GeoPoint" jdbcType="OTHER"/>
    </typeHandlers>

在Mybatis配置文件中配置該TypeHandler。

Mapper.xml

<mapper namespace="">
  <resultMap id="BaseResultMap" type="">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="location" jdbcType="OTHER" property="location" javaType="org.elasticsearch.common.geo.GeoPoint" typeHandler="com.test.GeoPointTypeHandler" />
  </resultMap>
  <insert id="insert" parameterType="com.test.DistrictDO">
    insert into district (id, location)
    values (#{id,jdbcType=INTEGER}, POINT(#{location.lon}, #{location.lat}))
  </insert>
</mapper>

mapper.xml中,該字段jdbcType=“OTHER”。注意在插入時,需要使用POINT(#{location.lon}, #{location.lat})。

##DO

public class DistrictDO {
    /**
     */
    private Integer id;

    /**
     *   經緯度
     */
    private Object location;
    // getter and setter
}

在DO中,該字段類型爲Object。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章