目录
问题描述:
原码:
实体类:
接口:
解决方法:
1、创建Handle
2、配置handle让mybatis-plus能够识别
相关代码:
问题描述:
在 MyBatis Plus 中,查询的 geometry
字段在数据库中确实有值,但是查询结果显示为 null。
原码:
实体类:
import com.bedatadriven.jackson.datatype.jts.serialization.GeometrySerializer;
import com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer;
import org.locationtech.jts.geom.Geometry;
@JsonSerialize(using = GeometrySerializer.class)
@JsonDeserialize(contentUsing = GeometryDeserializer.class)
@ApiModelProperty(value = "地理信息",hidden = true)
private Geometry geom;
接口:
解决方法:
指定TypeHandler
1、创建Handle
2、配置handle让mybatis-plus能够识别
相关代码:
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.io.ByteOrderValues;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Project: demo
* @Package: com.example.demo.jts
* @ClassName: AbstractGeometryTypeHandler
* @Author: Jason<genyong.yang @ gmail.com>
* @Date: 2022/6/24 21:37
* @Version: V1.0
* @Description:
*/
//@MappedTypes(Geometry.class)
public abstract class AbstractGeometryTypeHandler<T extends Geometry> extends BaseTypeHandler<T> {
/**
* 把Java类型参数转换为对应的数据库类型
* @param ps 当前的PreparedStatement对象
* @param i 当前参数位置
* @param parameter 当前参数的Java对象
* @param jdbcType 当前参数的数据库类型
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
try {
ps.setBytes(i,convertGeoToBytes(parameter));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取数据结果集时把数据库类型转换为对应的Java类型
* @param rs 当前的结果集
* @param columnName 当前的字段名称
* @return 转换后的Java对象
* @throws SQLException
*/
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 参考https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html#gis-internal-format
return convertBytesToGeo(rs.getBytes(columnName));
}
/**
* 通过字段位置获取字段数据时把数据库类型转换为对应的Java类型
* @param rs 当前的结果集
* @param columnIndex 当前字段的位置
* @return 转换后的Java对象
* @throws SQLException
*/
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return convertBytesToGeo(rs.getBytes(columnIndex));
}
/**
* 调用存储过程后把数据库类型的数据转换为对应的Java类型
* @param cs 当前的CallableStatement执行后的CallableStatement
* @param columnIndex 当前输出参数的位置
* @return 转换后的Java对象
* @throws SQLException
*/
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return convertBytesToGeo(cs.getBytes(columnIndex));
}
/**
* bytes转Geo对象
* @param bytes
* @return
*/
private T convertBytesToGeo(byte[] bytes) {
if (bytes == null) {
return null;
}
try {
GeometryFactory geometryFactory= new GeometryFactory(new PrecisionModel(), 4326);
// MySQL 支持 1-Point、 2-LineString、 3-Polygon、 4-MultiPoint、 5-MultiLineString、
// 6-MultiPolygon 和 7-GeometryCollection 的几何类型。不支持其他几何类型。
byte[] geomBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN)
.put(bytes, 4, bytes.length - 4).array();
Geometry geometry = new WKBReader(geometryFactory).read(geomBytes);
return (T) geometry;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* geo转bytes
* @param geometry
* @return
* @throws IOException
*/
private byte[] convertGeoToBytes(Geometry geometry) throws IOException {
byte[] geometryBytes = new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN).write(geometry);
byte[] wkb = new byte[geometryBytes.length + 4];
//设置 SRID 为 4326
ByteOrderValues.putInt(4326, wkb, ByteOrderValues.LITTLE_ENDIAN);
System.arraycopy(geometryBytes, 0, wkb, 4, geometryBytes.length);
return wkb;
}
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.GeometryCollection;
@MappedTypes(GeometryCollection.class)
public class GeometryCollectionTypeHandler extends AbstractGeometryTypeHandler<GeometryCollection>{
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Geometry;
@MappedTypes(Geometry.class)
public class GeometryTypeHandler extends AbstractGeometryTypeHandler<Geometry> {
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.LinearRing;
@MappedTypes(LinearRing.class)
public class LinearRingTypeHandler extends AbstractGeometryTypeHandler<LinearRing>{
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.LineString;
@MappedTypes(LineString.class)
public class LineStringTypeHandler extends AbstractGeometryTypeHandler<LineString>{
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.MultiLineString;
@MappedTypes(MultiLineString.class)
public class MultiLineStringTypeHandler extends AbstractGeometryTypeHandler<MultiLineString> {
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.MultiPoint;
@MappedTypes(MultiPoint.class)
public class MultiPointTypeHandler extends AbstractGeometryTypeHandler<MultiPoint> {
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.MultiPolygon;
@MappedTypes(MultiPolygon.class)
public class MultiPolygonTypeHandler extends AbstractGeometryTypeHandler<MultiPolygon> {
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Point;
@MappedTypes( Point.class)
public class PointTypeHandler extends AbstractGeometryTypeHandler<Point> {
}
package com.dh.agrisubs.jts;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Polygon;
@MappedTypes(Polygon.class)
public class PolygonTypeHandler extends AbstractGeometryTypeHandler<Polygon> {
}