jts+mybatis+mysql实现新增修改查询空间数据类型自动转换

配置mybatis自定义字段类型转换(TypeHandler)即可,可无mybatis plus,下面贴代码

引入包:

implementation "com.baomidou:mybatis-plus-boot-starter:3.3.1"
implementation "org.locationtech.jts:jts-core:1.16.1"

编写TypeHandler:

import cn.hutool.extra.spring.SpringUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.io.ByteOrderValues;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * mysql的geometry类型映射
 * Created by huangyifeng on 2020-02-17.
 */
public class MysqlGeoLineTypeHandler extends BaseTypeHandler<LineString> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LineString parameter, JdbcType jdbcType) throws SQLException {
        try {
            ps.setBytes(i, convertToBytes(parameter));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public LineString getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return convertToGeo(rs.getBytes(columnName));
    }

    @Override
    public LineString getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return convertToGeo(rs.getBytes(columnIndex));
    }

    @Override
    public LineString getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return convertToGeo(cs.getBytes(columnIndex));
    }

    /**
     * bytes转Geo对象
     * @param bytes
     * @return
     */
    private LineString convertToGeo(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            byte[] geomBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN)
                    .put(bytes, 4, bytes.length - 4).array();
            Geometry geometry = SpringUtil.getBean(WKBReader.class).read(geomBytes);
            return (LineString) geometry;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * geo转bytes
     * @param geometry
     * @return
     * @throws IOException
     */
    private byte[] convertToBytes(Geometry geometry) throws IOException {
        byte[] geometryBytes = SpringUtil.getBean(WKBWriter.class).write(geometry);
        byte[] wkb = new byte[geometryBytes.length + 4];
        //设置SRID为4326
        ByteOrderValues.putInt(4326, wkb, ByteOrderValues.LITTLE_ENDIAN);
        System.arraycopy(geometryBytes, 0, wkb, 4, geometryBytes.length);
        return wkb;
    }
}

entity实体类:

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants;
import org.locationtech.jts.geom.LineString;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 道路状态vo
 * Created by huangyifeng on 2020-02-13.
 */
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@EqualsAndHashCode(of = { "name", "direction", "angle", "lcodes", "polyline"})
@TableName(value = "t_traffic_status")
public class TrafficStatus implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    @TableId(type = IdType.AUTO)
    Long id;

    /**
     * 道路名称
     */
    String name;

    /**
     * 路况:0:未知 1:畅通 2:缓行 3:拥堵 4:严重拥堵
     */
    String status;

    /**
     * 方向描述
     */
    String direction;

    /**
     * 车行角度,判断道路正反向使用。以正东方向为0度,逆时针方向为正,取值范围:[0,360]
     */
    String angle;

    /**
     * 速度 单位:千米/小时
     */
    String speed;

    /**
     * 即locationcode的集合,是道路中某一段的id,一条路包括多个locationcode。angle在[0-180]之间取正值,[181-359]之间取负值。
     */
    String lcodes;

    /**
     * 道路坐标集,坐标集合
     */
    String polyline;

    /**
     * 道路空间字段
     */
    LineString linegeo;

    /**
     * 时间
     */
    LocalDateTime time;
}

添加字段类型转换支持(有多种方式配置):

mybatis-plus:
  ## 自定义字段类型转换
  type-handlers-package: com.yiring.bus.config.mybatis

有关jts的bean注入:

import cn.hutool.extra.spring.SpringUtil;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.io.ByteOrderValues;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;
import org.locationtech.jts.io.WKTReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

/**
 * 有关jts的bean注入
 * Created by huangyifeng on 2020-02-18.
 */
@Component
@ComponentScan(value = {"cn.hutool.extra.spring"})
@Import(SpringUtil.class)
public class JTSBean {

    private GeometryFactory geometryFactory;

    public JTSBean() {
        geometryFactory = new GeometryFactory(new PrecisionModel(), 4326);
    }

    @Bean
    public WKBWriter wkbWriter() {
        return new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN);
    }

    @Bean
    public WKBReader wkbReader() {
        return new WKBReader(geometryFactory);
    }

    @Bean
    public WKTReader wktReader() {
        return new WKTReader(geometryFactory);
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
MyBatis 中对于几何(Geometry)类型的转换,可以通过使用 TypeHandler 来实现。TypeHandler 是 MyBatis 提供的一个接口,用于将 Java 对象和数据库中的数据进行转换。 对于几何类型的转换,你可以自定义一个实现了 TypeHandler 接口的类,然后在 MyBatis 的配置文件中进行注册。 以下是一个示例的 TypeHandler 实现: ```java import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.io.WKTReader; public class GeometryTypeHandler extends BaseTypeHandler<Geometry> { @Override public void setNonNullParameter(PreparedStatement ps, int i, Geometry parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.toText()); } @Override public Geometry getNullableResult(ResultSet rs, String columnName) throws SQLException { String geometryString = rs.getString(columnName); return parseGeometry(geometryString); } @Override public Geometry getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String geometryString = rs.getString(columnIndex); return parseGeometry(geometryString); } @Override public Geometry getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String geometryString = cs.getString(columnIndex); return parseGeometry(geometryString); } private Geometry parseGeometry(String geometryString) { if (geometryString != null) { WKTReader reader = new WKTReader(); try { return reader.read(geometryString); } catch (Exception e) { // Handle exception } } return null; } } ``` 在以上的示例代码中,我们使用了 JTS Topology Suite(JTS)来处理几何类型。在 `setNonNullParameter` 方法中,我们将 Geometry 对象转换为 WKT(Well-Known Text)格式的字符串,并设置到 PreparedStatement 中。在 `getNullableResult` 方法中,我们从 ResultSet 或 CallableStatement 中取出字符串,并将其解析为 Geometry 对象。 接下来,在 MyBatis 的配置文件中注册这个 TypeHandler: ```xml <typeHandlers> <typeHandler handler="com.example.GeometryTypeHandler"/> </typeHandlers> ``` 需要注意的是,你需要根据你自己的数据库和几何类型库选择合适的依赖和实现方式。以上示例代码仅供参考,具体实现可能会有所差异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值