没腿的鸟 发表于 2024-5-19 11:38:30

GeometryCollection 的类型映射器(TypeHandler)

by emanjusaka fromhttps://www.emanjusaka.top/2024/05/mybatis-typeHandler-geometryCollection 彼岸花开可奈何
本文欢迎分享与聚合,全文转载请留下原文地址。
GeometryCollection 是 GeoJSON 数据模型中的一个类型,用于表示一个几何对象的聚集。MySQL8 中支持了 GeometryCollection 类型,在对数据库和实体类举行对象映射时需要我们自己编写类型映射器来完成映射。java 本身不支持 GeometryCollection 类型,我们需要引入第三方包来获得支持。
引入geotools工具包

该依赖在 maven 中心堆栈中没有,需要另外配置下堆栈
geotools库支持 jdk8 的最高版本是 28.2。
<dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson-core</artifactId>
            <version>28.2</version>
      </dependency>

<repositories>
      
      <repository>
            <id>osgeo</id>
            <name>OSGeo Release Repository</name>
            <url>https://repo.osgeo.org/repository/release/</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <releases>
                <enabled>true</enabled>
            </releases>
      </repository>
      <repository>
            <id>osgeo-snapshot</id>
            <name>OSGeo Snapshot Repository</name>
            <url>https://repo.osgeo.org/repository/snapshot/</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <releases>
                <enabled>false</enabled>
            </releases>
      </repository>
      
    </repositories>实体类

本示例的 mybatis 增加框架利用的是 tkmapper,如果是利用的 MyBatisPlus 注解切换成对应的注解,大同小异。为了演示方便我去除了无关字段,重点关注 GeometryCollection 类型的 areaGeom 字段即可。
package top.emanjusaka.test;

import com.iles.handler.GeometryCollectionTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.locationtech.jts.geom.GeometryCollection;
import tk.mybatis.mapper.annotation.ColumnType;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Data
@EqualsAndHashCode(callSuper = false)
@Table(name = "car_work_area")
public class CarWorkAreaDO {
    private static final long serialVersionUID = 1L;

    /**
   * 自增 ID
   */
    @Id
    @GeneratedValue(generator = "JDBC")
    private Long id;

    @Column(name = "area_geom")
    @ColumnType(typeHandler = GeometryCollectionTypeHandler.class)
    private GeometryCollection areaGeom;


}TypeHandler 映射器

大多数支持地理空间数据的数据库系统(如 PostgreSQL/PostGIS、MySQL、SQL Server 等)都支持以 WKT 或 WKB 格式存储和检索 GeometryCollection 类型的数据。具体利用哪种格式取决于应用场景的需求,好比对存储空间的敏感度、数据交换的便捷性以及性能要求等。本文存储的是 WKT 格式。
package top.emanjusaka.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;

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

/**
* @Author emanjusaka
*/
public class GeometryCollectionTypeHandler extends BaseTypeHandler<GeometryCollection> {
    private static final WKTReader wktReader = new WKTReader();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, GeometryCollection parameter, JdbcType jdbcType) throws SQLException {
      ps.setString(i, parameter.toText());
    }

    @Override
    public GeometryCollection getNullableResult(ResultSet rs, String columnName) throws SQLException {
      String wkt = rs.getString(columnName);
      try {
            return wkt != null ? (GeometryCollection) wktReader.read(wkt) : null;
      } catch (ParseException e) {
            throw new RuntimeException(e);
      }
    }

    @Override
    public GeometryCollection getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
      String wkt = rs.getString(columnIndex);
      try {
            return wkt != null ? (GeometryCollection) wktReader.read(wkt) : null;
      } catch (ParseException e) {
            throw new RuntimeException(e);
      }
    }

    @Override
    public GeometryCollection getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
      String wkt = cs.getString(columnIndex);
      try {
            return wkt != null ? (GeometryCollection) wktReader.read(wkt) : null;
      } catch (ParseException e) {
            throw new RuntimeException(e);
      }
    }
}mapper 文件

package top.emanjusaka.mapper;

import top.emanjusaka.test.CarWorkAreaDO;
import org.apache.ibatis.annotations.Param;
import tk.mybatis.mapper.common.Mapper;

import java.util.List;


public interface CarWorkAreaMapper extends Mapper<CarWorkAreaDO> {
    /**
   * 插入数据
   *
   * @param carWorkArea
   * @return:
   */
    int insertCustom(CarWorkAreaDO carWorkArea);
}注意事项:

[*]resultMap 中 area_geom 字段注意配置 TypeHandler,否则无法举行映射导致报错
[*]插入的 sql 语句中,area_geom 字段也需要指定 typeHandler,并且需要调用 ST_GeomCollFrom()函数读取数据。
[*]查询时可以调用函数 AsTex()
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="top.emanjusaka.mapper.CarWorkAreaMapper">
    <resultMap type="com.iles.models.car.CarWorkAreaDO" id="carWorkAreaResult">
      <result property="id" column="id"/>
      <result property="areaGeom" column="area_geom" javaType="org.locationtech.jts.geom.GeometryCollection"
                jdbcType="OTHER"
                typeHandler="top.emanjusaka.handler.GeometryCollectionTypeHandler"/>
    </resultMap>


    <insert id="insertCustom" parameterType="com.iles.models.car.CarWorkAreaDO">
      insert into
      car_work_area(id,area_geom)
      values
      (#{id},ST_GeomCollFromText(#{areaGeom,typeHandler=top.emanjusaka.handler.GeometryCollectionTypeHandler}))
    </insert>
</mapper>在技能的星河中遨游,我们互为引路星辰,共同追逐发展的光芒。愿本文的洞见能触动您的思绪,如有所共鸣,请以点赞之手,轻抚赞同的弦。
原文地址: https://www.emanjusaka.top/2024/05/mybatis-typeHandler-geometryCollection
微信公众号:emanjusaka的编程栈

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: GeometryCollection 的类型映射器(TypeHandler)