方案一(完全集成和自动解析):
<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);}@Overridepublic 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> {@Overridepublic 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);}// 走的这个方法,所以先只重写这个,如果其他方法需要 思路一样@Overridepublic MyPGPoint getNullableResult(ResultSet rs, String columnName) throws SQLException {String pointStr = rs.getString(columnName);// 解析从数据库中获取的字符串格式的pointif (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;}@Overridepublic 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;}@Overridepublic 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">selectpoint_name,point_addr,ST_AsText(point_coor) pointCoorfromgfa_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">selectpoint_name,point_addr,ST_X(point_coor) x,ST_Y(point_coor) yfromgfa_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));