栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis-plus使用BaseTypeHandler,完成Pgsql中geometry二进制与坐标点互相转换

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis-plus使用BaseTypeHandler,完成Pgsql中geometry二进制与坐标点互相转换

一、通过BaseTypeHandler将数据库中二进制与坐标点转换

你还在使用xml中写st_geomfromewkt(#{geom})进行坐标点导入么?
你还在使用xml中写st_astext(geom)进行二进制查询坐标点?
如果觉得复杂了,请看下放。

首先直接说方法,后面有说明用到的类

1.1 maven导入pgsql驱动与postgis



    org.postgresql
    postgresql



    net.postgis
    postgis-jdbc
    2.5.0

1.2 继承BaseTypeHandler,创建MyGeometryTypeHandler类
因为用到了srid,如果没有用到可以删除,用到了但不是4326,可以自行替换

@MappedTypes({String.class})
public class MyGeometryTypeHandler extends BaseTypeHandler {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        PGgeometry pGgeometry = new PGgeometry(parameter);
        Geometry geometry = pGgeometry.getGeometry();
        geometry.setSrid(4326);
        ps.setObject(i, pGgeometry);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String string = rs.getString(columnName);
        return getResult(string);
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String string = rs.getString(columnIndex);
        return getResult(string);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String string = cs.getString(columnIndex);
        return getResult(string);
    }


    private String getResult(String string) throws SQLException {
        PGgeometry pGgeometry = new PGgeometry(string);
        if (pGgeometry == null) {
            return null;
        }
        String s = pGgeometry.toString();
        return s.replace("SRID=4326;", "");
    }
}

1.3 实体类添加标签

@Data
@TableName(value = "tland", autoResultMap = true)
public class Tland extends BaseEntity {

    private static final long serialVersionUID = 1L;

    
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @TableField(typeHandler = MyGeometryTypeHandler.class)
    private String geom;
    
    private String landcode;

}

核心在于
1、@TableField(typeHandler = MyGeometryTypeHandler.class)
通过拦截的方法拦截转换字段
2、@TableName(value = “tland”, autoResultMap = true)
如果不加autoResultMap =rue,
进不去MyGeometryTypeHandler中getNullableResult()这个方法,就会导致无法将二进制转回到坐标点。

1.4 保存与查询数据

通过Mybatis-plus,insert(),或updateById()等方法导入。会将坐标点转换成二进制入库。
通过Mybatis-plus,selectOne()等查询方法,可以将二进制数据转换为坐标点。

保存时请求入参为

{
  "id": 75446,
  "geom": "POLYGON((77.97868543333607 39.43378804933673,77.978492314287 39.4337826849187,77.97842794127064 39.434056270238216,77.9780417031725 39.43412064325457,77.97858887381153 39.43414746534472,77.97868543333607 39.43378804933673))",
  "landcode": "653130204000008069"
}

保存后数据为

二、说明

2.1 BaseTypeHandler说明

BaseTypeHandler 是个抽象类,需要子类去实现其定义的 4 个抽象方法,而它本身实现了 typeHandler 接口的 4
个方法。

可以对数据保存与查询时做出相应处理,类似操作数据库之间的一个拦截器

可以通过该类做密码加密解密操作
上文中坐标点与二进制转换可以看成是一个操作
首先自定义handler 继承BaseTypeHandler重写他里边的四个方法

public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;
 
public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException;
 
public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException;
 
public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException;

setNonNullParameter()
可以理解为加密操作,将带有标签的字段,在inster,update操作时进行拦截,执行实现setNonNullParameter()方法体中的逻辑。

getNullableResult()
可以理解为解密操作,将带有标签的字段,在select操作时进行拦截,执行实现getNullableResult()方法体中的逻辑。

2.1 postgis说明
上文中用到的是postgis-jdbc,这样可以通过工具类,将坐标点与二进制进行转换。

坐标点转二进制

PGgeometry pGgeometry = new PGgeometry(parameter);
Geometry geometry = pGgeometry.getGeometry();
geometry.setSrid(4326);
ps.setObject(i, pGgeometry);

通过新建PGgeometry对象,传入坐标点或者二进制字符串都可以。具体可以查看PGgeometry的构造函数。点到最下面会发现有这段代码。判断你的入参是什么,就执行什么方法。

public static Geometry geomFromString(String value, BinaryParser bp, boolean haveM)
            throws SQLException {
        value = value.trim();

        int srid = Geometry.UNKNOWN_SRID;

        if (value.startsWith(SRIDPREFIX)) {
            // break up geometry into srid and wkt
            String[] parts = splitSRID(value);
            value = parts[1].trim();
            srid = Geometry.parseSRID(Integer.parseInt(parts[0].substring(5)));
        }
        
		//这里是核心,自己理解逻辑
        Geometry result;
        if (value.startsWith("00") || value.startsWith("01")) {
            result = bp.parse(value);
        } else if (value.endsWith("EMPTY")) {
            // We have a standard conforming representation for an empty
            // geometry which is to be parsed as an empty GeometryCollection.
            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")) {
            result = new GeometryCollection(value, haveM);
        } else {
            throw new SQLException("Unknown type: " + value);
        }

        if (srid != Geometry.UNKNOWN_SRID) {
            result.srid = srid;
        }

        return result;
    }

二进制转坐标点

PGgeometry pGgeometry = new PGgeometry(string);
if (pGgeometry == null) {
    return null;
}
String s = pGgeometry.toString();
return s.replace("SRID=4326;", "");

核心与坐标点转二进制一致,就不说明了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/978333.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号