当前位置: 首页 > article >正文

springboot+mybatis对接使用postgresql中PostGIS地图坐标扩展类型字段

方案一(完全集成和自动解析):

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>

 使用 org.postgresql.geometric包下的 PGpoint 类来接收数据库中POINT类型,但是由于直接使用无法达到指定sql语句格式,需要重写一下getValue()方法

package com.ruoyi.protect.bean.control.countybound.po;
import org.postgresql.geometric.PGpoint;


public class MyPGPoint extends PGpoint {

    public MyPGPoint(double x, double y){
        super(x,y);
    }

    @Override
    public String getValue() {
        return isNull ? null : "ST_GeomFromText('POINT(" + x + " " + y + ")', 4326)";
    }

}

 mybatis原生类型中没有这个类型,需要自定义handler进行处理

package com.ruoyi.protect.handler;

import com.ruoyi.protect.bean.control.countybound.po.MyPGPoint;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBReader;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class PGpointTypeHandler extends BaseTypeHandler<MyPGPoint> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, MyPGPoint parameter, JdbcType jdbcType) throws SQLException {
//        String param = "ST_GeomFromText('POINT(" + parameter.x + " " + parameter.y + ")', 4326)";
        ps.setObject(i, parameter);
    }


// 走的这个方法,所以先只重写这个,如果其他方法需要 思路一样
    @Override
    public MyPGPoint getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String pointStr = rs.getString(columnName);
        // 解析从数据库中获取的字符串格式的point
        if (pointStr!= null) {
            pointStr = pointStr.replace("POINT", "");
            pointStr = pointStr.substring(1, pointStr.length() - 1);
            String[] coords = pointStr.split(" ");
            double x = Double.parseDouble(coords[0]);
            double y = Double.parseDouble(coords[1]);
            return new MyPGPoint(x, y);
        }
        return null;
    }

    @Override
    public MyPGPoint getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String pointStr = rs.getString(columnIndex);
        if (pointStr!= null) {
            pointStr = pointStr.substring(1, pointStr.length() - 1);
            String[] coords = pointStr.split(",");
            double x = Double.parseDouble(coords[0]);
            double y = Double.parseDouble(coords[1]);
            return new MyPGPoint(x, y);
        }
        return null;
    }

    @Override
    public MyPGPoint getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String pointStr = cs.getString(columnIndex);
        if (pointStr!= null) {
            pointStr = pointStr.substring(1, pointStr.length() - 1);
            String[] coords = pointStr.split(",");
            double x = Double.parseDouble(coords[0]);
            double y = Double.parseDouble(coords[1]);
            return new MyPGPoint(x, y);
        }
        return null;
    }


}

 然后将这个hanler启动时加载,一般配置文件都可以指定加载自定义handler路径,如果是mybatis也有类似的配置项,也可以在配置类或者mybatis-config.xml中配置,反正目的就是把这个handler加载进去:

 Mapper.xml中写法也有要求:

插入时要使用${} 否则#{}会带单引号;查询时要使用ST_AsText()包着,否则是一串二进制字符串;

    <insert id="addPoint">
        insert into gfa_point (
        point_name,point_addr,point_coor) values
        (#{gp.pointName},#{gp.pointAddr},
         ${gp.pointCoor} )
    </insert>
    <select id="selectPage" resultMap="BaseResultMap">
        select
            point_name,
            point_addr,
            ST_AsText(point_coor) pointCoor
        from
            gfa_point;
    </select>

 此时,启动项目就可以

方案二(更简便方式):

正常使用原生mybatis即可

1、创建实体类

@data
public class{
        /**
     * 经度
     */
    @TableField(exist = false)
    private double x;
    /**
     * 纬度
     */
    @TableField(exist = false)
    private double y;
}

2、数据库创建坐标类型

 

3、mapper.xml新增和查询写法

 

     <insert id="addPoint">
        insert into gfa_point (point_name,point_addr,point_coor) values
        (#{gp.pointName},#{gp.pointAddr},
         ST_GeomFromText('POINT(${gp.x} ${gp.y})', 4326))
    </insert>
    <select id="selectPage" resultMap="BaseResultMap">
        select
            point_name,
            point_addr,
            ST_X(point_coor) x,
            ST_Y(point_coor) y
        from
            gfa_point;
    </select>

设计表时对于坐标类型使用三个字段,double x ,double y, POINT p;在插入时Point需要特殊处理一下,sql语句使用x y 加上拼接就可以插入进去;查询时不需要查POINT类型,直接查x y就可以返回坐标值,计算时使用POINT类型字段:

INSERT INTO test1 (name, geom) VALUES ('Point A', ST_GeomFromText('POINT(116.40 39.90)', 4326));

INSERT INTO test1 (name, geom) VALUES ('Point bA',ST_SetSRID(ST_MakePoint(-122.3493, 47.6205), 4326));


http://www.kler.cn/a/421204.html

相关文章:

  • LeetCode 64. 最小路径和(HOT100)
  • MongoDB集群分片安装部署手册
  • 解决 Flutter Dio合并请求多个接口,如果一个接口500,那么导致其他请求不在执行
  • 华为HarmonyOS 让应用快速拥有账号能力 -- 2 获取用户头像昵称
  • 【人工智能-基础】SVM中的核函数到底是什么
  • C—操作符易错点
  • 认识Java数据类型和变量
  • Flutter:常见的页面布局:上边内容可滚动,底部固定一个按钮
  • 网工日记:VRRP-虚拟路由冗余协议
  • pyqt6简单应用
  • 健康养生生活
  • MagicAnimate 技术浅析(一)
  • 常用端口号总结
  • Python 网络爬虫的高级应用:反爬绕过与爬取多样化数据
  • python分析wireshark文件
  • QT:核心机制
  • 量化交易系统开发-实时行情自动化交易-8.3.开拓者TBQuant平台
  • 精通 Python 网络安全(二)
  • mysql数据库之三范式
  • week 10 - Database: Normalisation
  • win11 多任务 贴靠 bug:左右两窗口贴靠时拖动中间的对齐条后,资源管理器有概率卡死
  • 使用API管理Dynadot域名,设置默认域名服务器ip信息
  • Spring Boot Actuator未授权访问漏洞处理
  • 详解Vue设计模式
  • 基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
  • hadoop环境配置-创建hadoop用户+更新apt+安装SSH+配置Java环境