【JAVA】使用mybatis plus查询数据库中的geometry字段为null

news2024/11/20 10:22:16

目录

问题描述:

原码:

实体类:

接口:

 解决方法:

1、创建Handle

2、配置handle让mybatis-plus能够识别

相关代码:


问题描述:

在 MyBatis Plus 中,查询的 geometry 字段在数据库中确实有值,但是查询结果显示为 null。

原码:

实体类:
import com.bedatadriven.jackson.datatype.jts.serialization.GeometrySerializer;
import com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer;
import org.locationtech.jts.geom.Geometry;
@JsonSerialize(using = GeometrySerializer.class)
@JsonDeserialize(contentUsing = GeometryDeserializer.class)
@ApiModelProperty(value = "地理信息",hidden = true)
private Geometry geom;
接口:

 解决方法:

指定TypeHandler

1、创建Handle

2、配置handle让mybatis-plus能够识别

相关代码:

package com.dh.agrisubs.jts;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
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 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;

/**
 * @Project: demo
 * @Package: com.example.demo.jts
 * @ClassName: AbstractGeometryTypeHandler
 * @Author: Jason<genyong.yang @ gmail.com>
 * @Date: 2022/6/24 21:37
 * @Version: V1.0
 * @Description:
 */

//@MappedTypes(Geometry.class)
public abstract class AbstractGeometryTypeHandler<T extends Geometry> extends BaseTypeHandler<T> {

    /**
     * 把Java类型参数转换为对应的数据库类型
     * @param ps        当前的PreparedStatement对象
     * @param i         当前参数位置
     * @param parameter 当前参数的Java对象
     * @param jdbcType  当前参数的数据库类型
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        try {
            ps.setBytes(i,convertGeoToBytes(parameter));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据结果集时把数据库类型转换为对应的Java类型
     * @param rs          当前的结果集
     * @param columnName  当前的字段名称
     * @return            转换后的Java对象
     * @throws SQLException
     */
    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 参考https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html#gis-internal-format
        return convertBytesToGeo(rs.getBytes(columnName));
    }

    /**
     * 通过字段位置获取字段数据时把数据库类型转换为对应的Java类型
     * @param rs            当前的结果集
     * @param columnIndex   当前字段的位置
     * @return              转换后的Java对象
     * @throws SQLException
     */
    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return convertBytesToGeo(rs.getBytes(columnIndex));
    }

    /**
     * 调用存储过程后把数据库类型的数据转换为对应的Java类型
     * @param cs            当前的CallableStatement执行后的CallableStatement
     * @param columnIndex   当前输出参数的位置
     * @return              转换后的Java对象
     * @throws SQLException
     */
    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return convertBytesToGeo(cs.getBytes(columnIndex));
    }

    /**
     * bytes转Geo对象
     * @param bytes
     * @return
     */
    private T convertBytesToGeo(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            GeometryFactory geometryFactory= new GeometryFactory(new PrecisionModel(), 4326);
            // MySQL 支持 1-Point、 2-LineString、 3-Polygon、 4-MultiPoint、 5-MultiLineString、
            // 6-MultiPolygon 和 7-GeometryCollection 的几何类型。不支持其他几何类型。
            byte[] geomBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN)
                    .put(bytes, 4, bytes.length - 4).array();
            Geometry geometry = new WKBReader(geometryFactory).read(geomBytes);
            return (T) geometry;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * geo转bytes
     * @param geometry
     * @return
     * @throws IOException
     */
    private byte[] convertGeoToBytes(Geometry geometry) throws IOException {
        byte[] geometryBytes = new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN).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;
    }


}

package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.GeometryCollection;


@MappedTypes(GeometryCollection.class)
public class GeometryCollectionTypeHandler extends AbstractGeometryTypeHandler<GeometryCollection>{
}

package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Geometry;


@MappedTypes(Geometry.class)
public class GeometryTypeHandler extends AbstractGeometryTypeHandler<Geometry> {
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.LinearRing;


@MappedTypes(LinearRing.class)
public class LinearRingTypeHandler extends AbstractGeometryTypeHandler<LinearRing>{
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.LineString;

@MappedTypes(LineString.class)
public class LineStringTypeHandler extends AbstractGeometryTypeHandler<LineString>{
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.MultiLineString;

@MappedTypes(MultiLineString.class)
public class MultiLineStringTypeHandler extends AbstractGeometryTypeHandler<MultiLineString> {
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.MultiPoint;

@MappedTypes(MultiPoint.class)
public class MultiPointTypeHandler extends AbstractGeometryTypeHandler<MultiPoint> {
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.MultiPolygon;

@MappedTypes(MultiPolygon.class)
public class MultiPolygonTypeHandler extends AbstractGeometryTypeHandler<MultiPolygon> {
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Point;


@MappedTypes( Point.class)
public class PointTypeHandler extends AbstractGeometryTypeHandler<Point> {
}
package com.dh.agrisubs.jts;

import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Polygon;

@MappedTypes(Polygon.class)
public class PolygonTypeHandler extends AbstractGeometryTypeHandler<Polygon> {
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2243983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51c自动驾驶~合集28

我自己的原文哦~ https://blog.51cto.com/whaosoft/12030824 #自动驾驶建图的统一矢量先验地图编码 高德地图&西交 | 先验驾驶 论文链接&#xff1a;https://arxiv.org/pdf/2409.05352 写在前面&笔者的个人理解 最近出现了很多先验地图的论文&#xff0c;高德地图…

【全面解读】Apache SeaTunnel常见问题全攻略

使用SeaTunnel需要安装Spark或者Flink这样的引擎么&#xff1f; 不需要&#xff0c;SeaTunnel 支持 Zeta、Spark 和 Flink 作为同步引擎的选择&#xff0c;您可以选择之一就行&#xff0c;社区尤其推荐使用 Zeta 这种专为同步场景打造的新一代超高性能同步引擎。Zeta 被社区用…

Spring Boot3.x自动配置不生效的排查与解决:IDEA 文件夹命名导致的问题

在使用Spring Boot搭建多模块项目时&#xff0c;需要使用到自动配置功能&#xff0c;把一些通用功能封装成模块后通过 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件注册配置类。然而&#xff0c;最近遇到一个奇怪的问题&#xff1a…

JavaSE(十四)——文件操作和IO

文章目录 文件操作和IO文件相关概念Java操作文件文件系统操作文件内容操作字节流FileOutputStreamFileInputStream代码演示 字符流FileWriterFileReader代码演示 缓冲流转换流 案例练习 文件操作和IO 文件相关概念 文件 通常指的是包含用户数据的文件&#xff0c;如文本文件、…

Qt桌面应用开发 第五天(常用控件)

目录 1.QPushButton和ToolButton 1.1QPushButton 1.2ToolButton 2.RadioButton和CheckBox 2.1RadioButton单选按钮 2.2CheckBox多选按钮 3.ListWidget 4.TreeWidget控件 5.TableWidget控件 6.Containers控件 6.1QScrollArea 6.2QToolBox 6.3QTabWidget 6.4QStacke…

Vue.js 插槽 Slots 实际应用 最近重构项目的时候遇到的...

前端开发中 插槽 Slots 是一个重要的概念 我们可以查看一下vue.js的官方文档 https://cn.vuejs.org/guide/components/slots 类似于连接通道一样 可以把核心代码逻辑搬到另外的地方 做一个引用 而原先的地方可能并不能这样书写 对于这个概念我在vue的官方文档里面找到了…

ubuntu pytorch容器内安装gpu版本的ffmpeg

一、基础镜像和生成容器 pytorch/pytorch &#xff1a;1.13.1-cuda11.6-cudnn8-devel 生成容器&#xff0c;一定要加NVIDIA_DRIVER_CAPABILITIEScompute,utility,video,graphics&#xff0c;否则侯建无法推流&#xff0c;报错缺少编码之类的。 docker run -it --gpus all -e …

VSCode+ESP-IDF开发ESP32-S3-DevKitC-1(2)第一个工程 LED心跳灯

VSCodeESP-IDF开发ESP32-S3-DevKitC-1&#xff08;2&#xff09;第一个工程 LED心跳灯 前言1.新建工程2.编写控制LED代码3.LED控制独立成.c和.h文件 前言 实际开发中很多时候我们需要有一个类似心跳灯或运行指示灯的灯以不同的状态闪烁以表示程序的运行状态&#xff0c;所以第…

在ubunto18.04安装node 14.16.0

这里演示安装node 14.16.0&#xff0c;其他版本也一样的安装步骤&#xff0c;需要注意1 1.检查本机服务器类型&#xff0c;有的是x64&#xff0c;有的是ARM&#xff0c;先查清楚是什么类型再进行下载&#xff0c;否则会存在编译出错的问题 bash: /opt/node-v14.16.0-linux-x6…

基于YOLOv8深度学习的智慧农业猪行为检测系统研究与实现(PyQt5界面+数据集+训练代码)

随着智慧农业的快速发展&#xff0c;畜牧业的智能化管理已逐渐成为提高生产效率、提升动物福利、降低运营成本的关键手段之一。在此背景下&#xff0c;畜牧场对动物行为的自动化监测需求日益增长&#xff0c;尤其是在大型养猪场&#xff0c;猪群的日常行为检测对于疾病预防、饲…

独立资源池与共享资源池在云计算中各自的优势

在云计算领域&#xff0c;独立资源池和共享资源池是两种关键的资源管理策略&#xff0c;它们各自具有独特的优势&#xff0c;以适应不同的业务需求和场景。 独立资源池的优势 资源独占性&#xff1a;独立资源池为特定应用或用户提供专属的资源&#xff0c;这意味着资源不会被其…

异或和之和

//暴力做法 枚举每个子区间 O(n^3) //优化1 利用前缀异或和快速求出区间异或和 O(n^2) //优化2 处理位运算的常用方法&#xff1a;拆位法 常用的思想&#xff1a;贡献法思想 下面详见优化2&#xff1a; 1.拆位贡献法 2.实战真题1 题目链接&#xff1a;1.异或和之和 - 蓝桥…

【金融风控项目-07】:业务规则挖掘案例

文章目录 1.规则挖掘简介2 规则挖掘案例2.1 案例背景2.2 规则挖掘流程2.3 特征衍生2.4 训练决策树模型2.5 利用结果划分分组 1.规则挖掘简介 两种常见的风险规避手段&#xff1a; AI模型规则 如何使用规则进行风控 **使用一系列逻辑判断(以往从职人员的经验)**对客户群体进行区…

第8章硬件维护-8.2 可维护性和可靠性验收

8.2 可维护性和可靠性验收 可维护性和可靠性验收非常重要&#xff0c;硬件维护工程师在后端发现问题后&#xff0c;总结成可维护性和可靠性需求&#xff0c;在产品立项的时候与新特性一起进行需求分析&#xff0c;然后经过设计、开发和测试环节&#xff0c;在产品中落地。这些需…

在k8s上部署minio

一、 环境 已部署k8s&#xff0c;支持helm部署 二、添加Minio Helm Chart仓库 helm repo add bitnami https://charts.bitnami.com/bitnami -n your_namespace helm repo update -n your_namespace部署带tls的minio helm install minio-s3 bitnami/minio -n your_namespace…

gtest 框架

基本了解 google提供的一个C测试框架&#xff0c;主要就是简化测试单元的书写&#xff0c;具有高效、灵活可拓展的特点 主要特点 简单易用&#xff1a;gtest 提供了清晰且易于使用的 API&#xff0c;便于开发者快速编写单元测试。丰富的断言支持&#xff1a;gtest 提供了多种断…

机器学习—误差分析

帮助运行诊断的最重要的方法是选择下一步要尝试的内容&#xff0c;提高你的学习算法性能&#xff0c;偏差和方差可能是最重要的想法&#xff0c;然后是错误分析。 假设Mcv500&#xff0c;即有500个交叉验证示例&#xff0c;你的算法错误的分类了100个&#xff0c;错误分析过程…

微知-如何查看BlueField DPU上的内存信息,包括内存主频和位宽?(dmidecode -t memory)

背景 在定位DPU上网卡性能的时候&#xff0c;可能涉及到查看内存的主频、位宽、电压等信息&#xff0c;如何快速查看&#xff1f; 命令 dmidecode -t memory实操 可以看到主频是 3200MT/s&#xff0c;另外还能看到位宽&#xff0c;大小&#xff0c;电压等信息。

【AI系统】AI系统架构的组成

AI 系统组成 如图所示&#xff0c;大致可以将 AI 系统分为以下几个具体的方向&#xff1a; AI 训练与推理框架 AI 框架不仅仅是指如 PyTorch 等训练框架&#xff0c;还包括推理框架。其负责提供用户前端的 AI 编程语言&#xff0c;接口和工具链。负责静态程序分析与计算图构建…

竞赛思享会 | 2024年第十届数维杯国际数学建模挑战赛D题【代码+演示】

Hello&#xff0c;这里是Easy数模&#xff01;以下idea仅供参考&#xff0c;无偿分享&#xff01; 题目背景 本题旨在通过对中国特定城市的房产、人口、经济、服务设施等数据进行分析&#xff0c;评估其在应对人口老龄化、负增长趋势和极端气候事件中的韧性与可持续发展能力。…