美文网首页Mybatis-plus
Mybatis-plus读取和保存Postgis geometr

Mybatis-plus读取和保存Postgis geometr

作者: 程序员阿远 | 来源:发表于2022-05-17 14:40 被阅读0次

原文链接:
https://blog.51cto.com/lovebetterworld/5296681

Mybatis-plus读取和保存Postgis geometry数据

SpringBoot项目,数据库为PostgreSQL,集成了PostGIS,需要实现Geometry数据的类型转换问题。

Maven依赖

<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.6</version>
</dependency>

创建类型转换类GeometryTypeHandler

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgis.PGgeometry;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedTypes({String.class})
public class MyGeometryTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
PGgeometry pGgeometry = new PGgeometry(parameter);
ps.setObject(i, pGgeometry);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
PGgeometry pGgeometry = new PGgeometry(rs.getString(columnName));
if (pGgeometry == null) {
return null;
}
return pGgeometry.toString();
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
PGgeometry pGgeometry = new PGgeometry(rs.getString(columnIndex));
if (pGgeometry == null) {
return null;
}
return pGgeometry.toString();
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
PGgeometry pGgeometry = new PGgeometry(cs.getString(columnIndex));
if (pGgeometry == null) {
return null;
}
return pGgeometry.toString();
}
}

在实体类配置typeHandler

@TableField(typeHandler = GeometryTypeHandler.class)
private String wkb;

踩坑
看到3部分的时候,相当于拦截器都已经实现好了,但是怎么验证呢?

自己试了半天,也没找到方法,一直抱怨类型转换错误,然后就开始断点一步一步向下走,最后发现了蹊跷。

在断点走到GeometryBuilder.class类中,才发现关键代码。

public static Geometry geomFromString(String value, BinaryParser bp, boolean haveM) throws SQLException {
value = value.trim();
int srid = 0;
if (value.startsWith("SRID=")) {
String[] parts = splitSRID(value);
value = parts[1].trim();
srid = Geometry.parseSRID(Integer.parseInt(parts[0].substring(5)));
}
//关键代码,解析传过来的数据类型
Object result;
if (!value.startsWith("00") && !value.startsWith("01")) {
if (value.endsWith("EMPTY")) {
result = new GeometryCollection();
} else if (value.startsWith("MULTIPOLYGON")) {
result = new MultiPolygon(value, haveM);
} else if (value.startsWith("MULTILINESTRING")) {
result = new MultiLineString(value, haveM);
} else if (value.startsWith("MULTIPOINT")) {
result = new MultiPoint(value, haveM);
} else if (value.startsWith("POLYGON")) {
result = new Polygon(value, haveM);
} else if (value.startsWith("LINESTRING")) {
result = new LineString(value, haveM);
} else if (value.startsWith("POINT")) {
result = new Point(value, haveM);
} else {
if (!value.startsWith("GEOMETRYCOLLECTION")) {
throw new SQLException("Unknown type: " + value);
}
result = new GeometryCollection(value, haveM);
}
} else {
result = bp.parse(value);
}
if (srid != 0) {
((Geometry)result).srid = srid;
}
return (Geometry)result;
}

4.1 示例封装数据

前端,可以封装一个专门的GIS组件,传数据。

本质上可以是数据构造成如下格式:

let Point = 'POINT(138.22 39.22)';

后端,为方便测试,直接拼接个字符串。

String gps = 'POINT(138.22 39.22)';
//然后正常Mybatis的持久化即可。

相关文章

网友评论

    本文标题:Mybatis-plus读取和保存Postgis geometr

    本文链接:https://www.haomeiwen.com/subject/hclnurtx.html