使用Mybatis向Mysql中的插入Point类型的数据全方位解析

news2024/11/20 0:52:06

1. 结果

希望每一个能够看到结果的人都能自己装载进去!加油!
输出 结果

2.代码

2.1TestMapper

import org.apache.ibatis.annotations.*;
import java.util.Date;
import java.util.List;

/**
 * @author Administrator
 */
@Mapper
public interface TestMapper {
    /**
     * 更新名字 测试更新数据库
     *
     * @param id
     * @param name
     */
    @Update("UPDATE test SET name = #{name} WHERE id = #{id}")
    void updateNameByid(long id, String name);
    /**
     * 插入数据2 用纯sql语句插入
     * MyBatis 在处理 ST_GeomFromText 函数时,会将 #{lng} 和 #{lat} 视为一个整体,导致参数索引超出范围
     *        正确的语法  CONCAT('POINT(', #{lng}, ' ', #{lat}, ')')
     *        错误的语法: POINT(#{lng} #{lat})
     * @param name
     * @param lat
     * @param lng
     * @param date2
     */
    @Insert("INSERT INTO Test (name, location, create_time) VALUES ( #{name}, ST_GeomFromText(CONCAT('POINT(', #{lng}, ' ', #{lat}, ')')), #{date2})")
    void insertTest2(@Param("name") String name, @Param("lng") double lng, @Param("lat") double lat, @Param("date2") String date2);
    /**
     * 用GeoPoint对象插入数据 需使用GeoPointHandler
     * @param name
     * @param location
     * @param date2
     */
    @Insert("INSERT INTO Test (name, location, create_time) VALUES (#{name}, ST_GeomFromText(#{location}), #{date2})")
    void insertTest3(@Param("name") String name, @Param("location") GeoPoint location, @Param("date2") String date2);


}

2.2 GeoPoint

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

import java.io.Serializable;
/**
 * @author Administrator
 */
@Builder
@AllArgsConstructor
@Data
public class GeoPoint implements Serializable {
    /**
     * 经度
     */
    private Double longitude;
    /**
     * 纬度
     */
    private Double latitude;

      @Override
    public String toString() {
    //重点,这个函数会影响输出到最终的sql语句,所以中间和mysql保持一致为空格。
        return "POINT(" + longitude + " " + latitude + ")";
    }
}

2.3处理坐标点转换 GeoPointTypeHandler

import com.zjs.fish.entity.GeoPoint;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;

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

/**
 * @author Administrator
 */
@MappedTypes(GeoPoint.class)
public class GeoPointTypeHandler extends BaseTypeHandler<GeoPoint> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, GeoPoint parameter, JdbcType jdbcType) throws SQLException {
//           System.out.println("执行了setNonNullParameter");
        ps.setString(i, parameter.toString());
    }

    @Override
    public GeoPoint getNullableResult(ResultSet rs, String columnName) throws SQLException {
        System.out.println("执行了getNullableResult");
        String wkt = rs.getString(columnName);
        if (wkt == null) {
            return null;
        }
        String[] parts = wkt.replace("POINT(", "").replace(")", "").split(" ");
        double longitude = Double.parseDouble(parts[0]);
        double latitude = Double.parseDouble(parts[1]);
        return new GeoPoint(longitude, latitude);
    }

    @Override
    public GeoPoint getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        System.out.println("执行了getNullableResult");
        String wkt = rs.getString(columnIndex);
        if (wkt == null) {
            return null;
        }
        String[] parts = wkt.replace("POINT(", "").replace(")", "").split(" ");
        double longitude = Double.parseDouble(parts[0]);
        double latitude = Double.parseDouble(parts[1]);
        return new GeoPoint(longitude, latitude);
    }

    @Override
    public GeoPoint getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
          System.out.println("执行了getNullableResult");
        String wkt = cs.getString(columnIndex);
        if (wkt == null) {
            return null;
        }
        String[] parts = wkt.replace("POINT(", "").replace(")", "").split(" ");
        double longitude = Double.parseDouble(parts[0]);
        double latitude = Double.parseDouble(parts[1]);
        return new GeoPoint(longitude, latitude);
    }
}

2.4 测试

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.io.InputStream;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

public class MyBatisDemo {
    private SqlSession sqlSession;
    private TestMapper testMapper;
    @Before
    public void setUp() throws Exception {
        try {
            //1.配置
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //2. 获取sqlSession对象,用它来时执行sql
            sqlSession = sqlSessionFactory.openSession();
            testMapper = sqlSession.getMapper(TestMapper.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @After
    public void tearDown() throws Exception {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

    @org.junit.Test
    public void updateNameTest() {
        System.out.println("updateNameTest");
        testMapper.updateNameByid(1, "小王八");
        sqlSession.commit();
    }

    @org.junit.Test
    public void insertTest2() {
        System.out.println("insertTest2");
        String name = "赵9";
        double lng = 121.7128;
        double lat = 32.6895;
        //插入时间类型
        Date date = new Date();
        //这个是日期的常量,我写在GlobalConst,自己根据情况配置 public DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String date2 = GlobalConst.formatter.format(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        testMapper.insertTest2(name, lng, lat, date2);
        sqlSession.commit();
    }

    @org.junit.Test
    public void insertTest3() {
        System.out.println("insertTest3");
        String name = "赵9";
        double lng = 121.7128;
        double lat = 32.6895;
        Date date = new Date();
//同上
        String date2 = GlobalConst.formatter.format(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());

        GeoPoint location = new GeoPoint(lng, lat);
//        System.out.println(location.toString());
        testMapper.insertTest3(name, location, date2);
        sqlSession.commit();
    }
}

3. 解析

3.1 mybatis配置

<configuration>
    <settings>
    <!--        打开日志-->
         <setting name="logImpl" value="SLF4J"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="useGeneratedKeys" value="true"/>
<!--        <setting name="useLegacyDatetimeCode" value="false"/>-->
    </settings>
<!-- 根据自己的路径进行调整-->
    <typeHandlers>
        <typeHandler javaType="com.xxx.xxx.entity.GeoPoint" jdbcType="VARCHAR"
                     handler="com.xxx.xxx.typehandlers.GeoPointTypeHandler"/>
    </typeHandlers>
    <!--   环境变量 -->
    <environments default="development">
     .......//这个就不做说明了。
    </environments>
<!--对应自己的mapper文件,这里使用的事注解的mapper所以没有xml文件,也不用对应找xml -->
    <mappers>
        <package name="com.xxx.xxx.mapper"/>
    </mappers>
</configuration>

3.2 pom引入

缺什么自己找吧,环境是Springboot2.7.15 java1.8 maven 3.6

<dependencies>

        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

          <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.6</version>
        </dependency>
        <!-- Spring Boot Starter Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!-- 测试插件 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!-- Gson 插件 -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.1</version>
        </dependency>

        <!-- 数据库连接插件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--        数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <!-- 添加 JUnit Jupiter 和 Spring Boot Test 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- lombok   -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version> <!-- 请使用最新版本 -->
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>6.3.4</version>
        </dependency>

<!--     几何信息   -->
        <dependency>
            <groupId>org.locationtech.jts</groupId>
            <artifactId>jts-core</artifactId>
            <version>1.19.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.14</version>
        </dependency>
            <!-- MyBatis Plus Starter for Spring Boot -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
    </dependencies>

3.3流程解析

| 所有的转移最终都还是要通过sql语句到Mysql数据库的过程,只是因为不同的平台之间显示的GPS数据的写法不同会造成需要不同的接口来进行适配。所以一开始就不要把问题想想的很复杂。
如果环境报错,就尽量用一致的环境,这里适配到java1.8也是希望能够最大程度的兼容.
最后这个Mapper+sql语句的方式简化了编写的逻辑,但增减了新手的理解能力。作为前端Android开发的我也花了三天才适应,不知道你们能否适应。

4. 填坑

4.1 插件问题,

所有的pom插件都能够在阿里云找到,如果不能找到最好不要使用,

阿里云仓库地址:

https://developer.aliyun.com/mvn/search  

如果粘贴进pom报错,可以clean一下project.

<!-- 镜像配置-->
<mirrors>
    <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>https://maven.aliyun.com/repository/public</url>
        <mirrorOf>*</mirrorOf>
    </mirror>
</mirrors>

4.2 Mysql几何类型

ST_GeomFromText 做sql的标配,他其实是在数据库层面转写的一个函数,用于将坐标点转换成一个集合对象,存储在数据库中。因为这个几何数据作为数学基础的大类,被分割出来就是为了更好的去为相关的应用做配套,所以一定要对这写做一个了结。
他的参数就一个,字符串,但是又一定的标准 前面Point就是点类型,后面接着就是点坐标,当然还有面,线,集合等等类型,注意括号的层次即可。
@Override
public String toString() {
return “POINT(” + longitude + " " + latitude + “)”;
}
重写GeoPoint中的点坐标结构,已达到插入数据库的标准,这是我遇到的重点问题。网上真的是搜索了一大圈,AI也问了1天多。真的是不出个所以然来。如果对项目结构没有自己的认知,很容易被整的头晕脑胀。

4.3 写在最后

如果有不能解决的欢迎提问,收到信息后回及时回复。
希望每个人都能从中走出来!

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

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

相关文章

web——sqliabs靶场——第六关——报错注入和布尔盲注

这一关还是使用报错注入和布尔盲注 一. 判断是否有sql注入 二. 判断注入的类型 是双引号的注入类型。 3.报错注入的检测 可以使用sql报错注入 4.查看库名 5. 查看表名 6.查看字段名 7. 查具体字段的内容 结束 布尔盲注 结束

鸿蒙实战:页面跳转传参

文章目录 1. 实战概述2. 实现步骤2.1 创建鸿蒙项目2.2 编写首页代码2.3 新建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 本次实战&#xff0c;学习如何在HarmonyOS应用中实现页面间参数传递。首先创建项目&#xff0c;编写首页代码&#xff0c;实现按钮跳转至第二个页面并…

数据结构(基本概念及顺序表——c语言实现)

基本概念&#xff1a; 1、引入 程序数据结构算法 数据&#xff1a; 数值数据&#xff1a;能够直接参加运算的数据&#xff08;数值&#xff0c;字符&#xff09; 非数值数据&#xff1a;不能够直接参加运算的数据&#xff08;字符串、图片等&#xff09; 数据即是信息的载…

一.安装版本为19c的Oracle数据库管理系统(Oracle系列)

1.数据库版本信息&#xff1a; 版本信息&#xff1a; 或者直接由命令查出来&#xff1a; 2.操作系统的版本信息 3.安装包下载与上传 可以去oracle官网下载也可以从其他人的百度网盘链接中下载&#xff1a; 使用xftp工具或者其他的工具&#xff08;mobaxterm&#xff09;上传到l…

从 IDC 到云原生:稳定性提升 100%,成本下降 50%,热联集团的数字化转型与未来展望

作者&#xff1a;金峰&#xff08;项良&#xff09;、朱永林、赵世振&#xff08;寰奕&#xff09; 公司简介 杭州热联集团股份有限公司成立于 1997 年 10 月&#xff0c;是隶属杭州市实业投资集团的国有控股公司。公司专业从事国际、国内钢铁贸易黑色大宗商品及产业服务&…

说说软件工程中的“协程”

在软件工程中&#xff0c;协程&#xff08;coroutine&#xff09;是一种程序运行的方式&#xff0c;可以理解成“协作的线程”或“协作的函数”。以下是对协程的详细解释&#xff1a; 一、协程的基本概念 定义&#xff1a;协程是一组序列化的子过程&#xff0c;用户能像指挥家…

MinIO 的 S3 over RDMA 计划: 为高速人工智能数据基础设施设定对象存储新标准

随着 AI 和机器学习的需求不断加速&#xff0c;数据中心网络正在迅速发展以跟上步伐。对于许多企业来说&#xff0c;400GbE 甚至 800GbE 正在成为标准选择&#xff0c;因为数据密集型和时间敏感型 AI 工作负载需要高速、低延迟的数据传输。用于大型语言处理、实时分析和计算机视…

怀旧游戏打卡清单(TODO)

感觉忙碌了好久好久&#xff0c;真的好想休息一下。。 整理一下将来休息时候的打卡清单&#xff0c;不工作了去个海边狂打游戏&#xff0c;想想就惬意啊。当然&#xff0c;最好找个work from home&#xff0c;去海边找个酒店上班。挣钱休息两不误。。。 能不能实现另说&#xf…

《Python制作动态爱心粒子特效》

一、实现思路 粒子效果&#xff1a; – 使用Pygame模拟粒子运动&#xff0c;粒子会以爱心的轨迹分布并运动。爱心公式&#xff1a; 爱心的数学公式&#xff1a; x16sin 3 (t),y13cos(t)−5cos(2t)−2cos(3t)−cos(4t) 参数 t t 的范围决定爱心形状。 动态效果&#xff1a; 粒子…

使⽤MATLAB进⾏⽬标检测

目录 数据准备定义模型并训练用测试集评估性能推理过程⼀⾏代码查看⽹络结构⼀⾏代码转onnx结语 ⼈⽣苦短&#xff0c;我⽤MATLAB。 Pytorch在深度学习领域占据了半壁江⼭&#xff0c;最主要的原因是⽣态完善&#xff0c;⽽且api直观易⽤。但谁能想到现在MATLAB⽤起来⽐Pytorch…

word-毕业论文的每一章节的页眉单独设置为该章的题目怎么设置

在Microsoft Word中&#xff0c;为毕业论文的每个章节设置不同的页眉&#xff0c;通常需要使用“分节符”来分隔各个章节&#xff0c;然后在每个章节中单独设置页眉。以下是详细步骤&#xff1a; 使用分节符 插入分节符&#xff1a; 将光标放在每个章节的末尾&#xff08;注意…

【简历】25届江苏二本JAVA简历:本末倒置,重点部分格式错误,不重要的写了一堆

简历总体说明 校招的第一法则就是必须要确定校招层次。 开发岗分为大中小厂&#xff0c;不同的层次对学校背景、时间点、项目和考点的要求都不太一样&#xff0c;所以必须要确定就业的层次。 这是一个25届二本同学的JAVA简历。 最近不知道怎么回事&#xff0c;看两份简历都…

字母异位词分组(java)

题目描述 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单shilie 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "n…

fpga spi回环

SPI设备间的数据传输之所以又被称为数据交换,是因为 SPI协议规定一个 SPI设备 不能在数据通信过程中仅仅只充当一个"发送者(Transmitter)“或者"接收者 (Receiver)”.在每个 Clock 周期内,SPI 设备都会发送并接收一个 bit 大小的数据(不管主 设备好还是从设备),相当于…

计算机网络-理论部分(二):应用层

网络应用体系结构 Client-Server客户-服务器体系结构&#xff1a;如Web&#xff0c;FTP&#xff0c;Telnet等Peer-Peer&#xff1a;点对点P2P结构&#xff0c;如BitTorrent 应用层协议定义了&#xff1a; 交换的报文类型&#xff0c;请求or响应报文类型的语法字段的含义如何…

路由器基本原理与配置

一 &#xff0c; 路由是什么&#xff1f; 从源主机到目标主机的转发过程&#xff1b; 二 &#xff0c; 路由器 &#xff08;1&#xff09;路由器的工作原理 路由器是一种三层设备&#xff0c;是使用IP地址寻址&#xff0c;实现从源IP到达目标IP地址的端到端的服务&#xff0c…

windows的WSL Ubuntu子系统重置root或其他用户的密码

思路&#xff1a;以管理员身份运行PowerShell&#xff0c;在命令行窗口重置密码 &#xff0c;不需要删除或重新安装Linux子系统。 1、以管理员身份运行PowerShell 2、用root用户启动Ubuntu&#xff0c;执行 wsl.exe --user root 3、重置密码&#xff0c;执行passwd username&…

autoDL微调训练qwen2vl大模型

autodl是一家GPU服务厂商&#xff0c;提供专业的GPU租用服务&#xff0c;秒级计费、稳定好用 先去autodl把官方的帮助文档看懂先 AutoDL帮助文档 autodl注册并登陆&#xff0c;充钱&#xff0c;根据自己的情况租用新实例 创建新实例后马上关机&#xff0c;因为有个省钱的办法…

9.2 使用haarcascade_frontalface_default.xml分类器检测视频中的人脸,并框出人脸位置。

1&#xff09;程序代码&#xff1a; # 2.使用haarcascade_frontalface_default.xml分类器检测视频中的人脸&#xff0c;并框出人脸位置 import cv2# 加载人脸检测的 Haar 级联分类器 face_cascade cv2.CascadeClassifier(./data/haarcascades/haarcascade_frontalface_defaul…

K8S containerd拉取harbor镜像

前言 接前面的环境 K8S 1.24以后开始启用docker作为CRI&#xff0c;这里用containerd拉取 参考文档 正文 vim /etc/containerd/config.toml #修改内容如下 #sandbox_image "registry.aliyuncs.com/google_containers/pause:3.10" systemd_cgroup true [plugins.…