MyBatisPlus+PostGIS实现Geometry数据的通用读写

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: MyBatisPlus+PostGIS实现Geometry数据的通用读写


  1. 引入依赖
<!--连接Postgresql数据库-->
 <dependency>
       <groupId>org.postgresql</groupId>
       <artifactId>postgresql</artifactId>
 </dependency>
  <!--编(解)码postgresql写入(或读取)的Geometry-->
 <dependency>
      <groupId>net.postgis</groupId>
      <artifactId>postgis-jdbc</artifactId>
      <version>2.5.0</version>
 </dependency>
  <!--Geometry工具库-->
 <dependency>
        <groupId>org.locationtech.jts</groupId>
        <artifactId>jts-core</artifactId>
        <version>1.17.0</version>
  </dependency>
  1. Entity编写
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jd.risk.screen.demo.entity.handler.PointTypeHandler;
import lombok.Data;
import org.locationtech.jts.geom.Point;
/**
 * 基站PO
 *
 * @author wangrubin
 * @date 2022-08-16
 */
@Data
@TableName(value = "t_base_station", autoResultMap = true)
public class StationPO {
    /**
     * 基站ID
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 基站位置
     */
    @JsonIgnore
    @TableField(typeHandler = PointTypeHandler.class)
    private Point location;
}
  1. 实现几何(Geometry)类型转换器
  • 父类转换器逻辑
import lombok.SneakyThrows;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.postgis.PGgeometry;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * Geometry字段和MyBatis类型转换器
 *
 * @param <T> 具体的几何类型
 * @author wangrubin
 * @date 2022-08-06
 */
public abstract class AbstractGeometryTypeHandler<T extends Geometry> extends BaseTypeHandler<T> {
    /**
     * WKTReader非线程安全
     */
    private static final ThreadLocal<WKTReader> READER_POOL = ThreadLocal.withInitial(WKTReader::new);
    /**
     * WKTWriter非线程安全
     */
    private static final ThreadLocal<WKTWriter> WRITER_POOL = ThreadLocal.withInitial(WKTWriter::new);
    /**
     * 与数据库中几何列的空间坐标系保持一致,要不然写入会报错
     */
    private static final int SRID_IN_DB = 4326;
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        PGgeometry pGgeometry = new PGgeometry(WRITER_POOL.get().write(parameter));
        org.postgis.Geometry geometry = pGgeometry.getGeometry();
        geometry.setSrid(SRID_IN_DB);
        ps.setObject(i, pGgeometry);
    }
    @SneakyThrows
    @Override
    public T getNullableResult(ResultSet rs, String columnName) {
        String string = rs.getString(columnName);
        return getResult(string);
    }
    @SneakyThrows
    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) {
        String string = rs.getString(columnIndex);
        return getResult(string);
    }
    @SneakyThrows
    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) {
        String string = cs.getString(columnIndex);
        return getResult(string);
    }
    private T getResult(String string) throws SQLException {
        if(string == null){  
            return null;
        }
        PGgeometry pGgeometry = new PGgeometry(string);
        String s = pGgeometry.toString();
        String target = String.format("SRID=%s;", SRID_IN_DB);
        String wkt = s.replace(target, "");
        try {
            return (T) READER_POOL.get().read(wkt);
        } catch (Exception e) {
            throw new RuntimeException("解析wkt失败:" + wkt, e);
        }
    }
}
  • 子类转换器逻辑
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Point;
/**
 * Point的类型转换器
 *
 * @author wangrubin1
 * @date 2022-08-19
 */
@MappedTypes({Point.class})
public class PointTypeHandler extends AbstractGeometryTypeHandler<Point> {
}
  1. 建表语句
CREATE TABLE public.t_base_station
(
    id bigserial primary key,
    location geometry(Point,4326)  -- 坐标系是4326
)
  1. 测试
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jd.risk.screen.demo.entity.StationPO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StationMapper extends BaseMapper<StationPO> {
}
@SpringBootTest(classes = DemoApplication.class)
@ExtendWith(SpringExtension.class)
@WebAppConfiguration
class GeometryTests {
    @Autowired
    private StationMapper stationMapper;
    @Test
    public void insert() {
        GeometryFactory factory = new GeometryFactory();
        StationPO stationPo = new StationPO();
        stationPo.setLocation(factory.createPoint(new Coordinate(115.3, 24.7)));
        stationMapper.insert(stationPo);
    }
    @Test
    public void select() {
        StationPO stationPo = stationMapper.selectById(1L);
        System.out.println(stationPo);
    }
}

控制台输出:StationPO(id=1, location=POINT (115.3 24.7))


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
8月前
|
Java 数据库连接 mybatis
Mybatis Plus保存数据返回主键id
Mybatis Plus保存数据返回主键id
313 1
|
4月前
|
Java 数据库连接 数据库
mybatis查询数据,返回的对象少了一个字段
mybatis查询数据,返回的对象少了一个字段
300 8
|
3月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
94 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
5月前
|
Java 数据库连接 测试技术
SpringBoot 3.3.2 + ShardingSphere 5.5 + Mybatis-plus:轻松搞定数据加解密,支持字段级!
【8月更文挑战第30天】在数据驱动的时代,数据的安全性显得尤为重要。特别是在涉及用户隐私或敏感信息的应用中,如何确保数据在存储和传输过程中的安全性成为了开发者必须面对的问题。今天,我们将围绕SpringBoot 3.3.2、ShardingSphere 5.5以及Mybatis-plus的组合,探讨如何轻松实现数据的字段级加解密,为数据安全保驾护航。
393 1
|
5月前
|
SQL 关系型数据库 MySQL
解决:Mybatis-plus向数据库插入数据的时候 报You have an error in your SQL syntax
该博客文章讨论了在使用Mybatis-Plus向数据库插入数据时遇到的一个常见问题:SQL语法错误。作者发现错误是由于数据库字段中使用了MySQL的关键字,导致SQL语句执行失败。解决方法是将这些关键字替换为其他字段名称,以避免语法错误。文章通过截图展示了具体的操作步骤。
|
5月前
|
SQL Java 关系型数据库
MyBatis-Plus 分页魅力绽放!紧跟技术热点,带你领略数据分页的高效与便捷
【8月更文挑战第29天】在 Java 开发中,数据处理至关重要,尤其在大量数据查询与展示时,分页功能尤为重要。MyBatis-Plus 作为一款强大的持久层框架,提供了便捷高效的分页解决方案。通过封装数据库分页查询语句,开发者能轻松实现分页功能。在实际应用中,只需创建 `Page` 对象并设置页码和每页条数,再通过 `QueryWrapper` 构建查询条件,调用 `selectPage` 方法即可完成分页查询。MyBatis-Plus 不仅生成分页 SQL 语句,还自动处理参数合法性检查,并支持条件查询和排序等功能,极大地提升了系统性能和稳定性。
75 0
|
5月前
|
存储 SQL Java
MyBatis batchInsert 批量插入数据
MyBatis batchInsert 批量插入数据
122 0
|
5月前
|
前端开发 JavaScript Java
解决springboot+vue+mybatis中,将后台数据分页显示在前台,并且根据页码自动跳转对应页码信息
该博客文章讲述了如何在Spring Boot + Vue + MyBatis的项目中实现后台数据的分页查询,并在前端进行显示和页码跳转,包括后端的分页查询实现、前端与后端的交互以及使用Element UI进行分页展示的方法。
|
6月前
|
Java 数据库连接 Maven
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
|
7月前
|
Java 关系型数据库 MySQL
Mybatis入门之在基于Springboot的框架下拿到MySQL中数据
Mybatis入门之在基于Springboot的框架下拿到MySQL中数据
60 4