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

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 写在最后

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云轻量应用服务器可以用在哪些场景呢

在数字化转型的浪潮中&#xff0c;中小企业面临着如何快速、高效地上云的挑战。阿里云轻量应用服务器&#xff08;SWAS&#xff09;作为一款专为中小企业设计的云服务产品&#xff0c;提供了简单易用、经济实惠的解决方案&#xff0c;助力企业轻松实现云端部署&#xff0c;赋能…

【桌面应用程序】Vue-Electron 环境构建、打包与测试(Windows)

前言 Vue 与 Electron 环境构建、打包与测试。 目录 前言 一、基本环境准备 二、配置npm源 三、创建Vue项目 四、添加Electron支持 五、应用启动 ​六、添加UI框架 ElementUI ​七、打包 一、基本环境准备 npm版本&#xff1a;8.6.0node版本&#xff1a;v18.0.0Vue/…

【SQL】E-R模型(实体-联系模型)

目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型&#xff08;E-R数据模型&#xff09;被开发来方便数据库的设计&#xff0c;它是通过允许定义代表数据库全局逻辑结构的企业模式&#xf…

Linux下安装NVIDIA显卡驱动(全流程通俗教程)

1、确认显卡型号 查明你的NVIDIA显卡型号&#xff0c;以确保下载驱动程序的版本&#xff1a; lspci | grep -i vga 2、下载NVIDIA驱动 前往官方网站&#xff1a;NVIDIA官网 选择显卡信息&#xff1a;使用下拉菜单选择正确的显卡型号、Linux操作系统和系统架构。 下载驱动…

视频里的音频怎么提取出来成单独文件?音频提取照着这些方法做

在数字时代&#xff0c;视频与音频的分离与重组已成为日常需求之一。无论是出于制作背景音乐、保存讲座内容&#xff0c;还是编辑播客素材&#xff0c;提取视频中的音频并将其保存为单独文件都显得尤为重要。视频里的音频怎么提取出来成单独文件&#xff1f;本文将详细介绍几种…

【Vue笔记】基于vue3 + element-plus + el-dialog封装一个自定义的dialog弹出窗口组件

这篇文章,介绍一下如何使用vue3+element-plus中的el-dialog组件,自己封装一个通用的弹出窗口组件。运行效果如下所示: 目录 1.1、父子组件通信 1.2、自定义VDialog组件(【v-model】模式) 1.2.1、编写VDialog组件代码 1.2.2、使用VDialog组件 1.2.3、运行效果 1.3、自…

python: generator IDAL and DAL using sql server 2019

其它数据库也是一样的思维方式 create IDAL # encoding: utf-8 # 版权所有 2024 ©涂聚文有限公司 # 许可信息查看&#xff1a;言語成了邀功盡責的功臣&#xff0c;還需要行爲每日來值班嗎 # 描述&#xff1a; # Author : geovindu,Geovin Du 涂聚文. # IDE : P…

【澜舟科技-注册/登录安全分析报告】

前言 由于网站注册入口容易被机器执行自动化程序攻击&#xff0c;存在如下风险&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露&#xff0c;不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 &#xff0c;造成用户无法登陆、注册&#xff0c;大量收到垃圾短信的…

基于Java Springboot出租车管理网站

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)

元服务是什么&#xff1f;和App的关系&#xff1f; 元服务是是一种HarmonyOS轻量应用形态&#xff0c;用户无需安装即可使用&#xff0c;具备随处可及、服务直达、自由流转的特征。 元服务是可以独立部署和运行的程序实体&#xff0c;独立于应用&#xff0c;不依赖应用可独立…

uniapp 自定义加载组件,全屏加载,局部加载 (微信小程序)

效果图 全屏加载 页面加载使用 局部加载 列表加载里面使用 使用gif html <template><view><view class"" v-if"typeFullScreen"><view class"loading" v-if"show"><view class""><i…

QQ 小程序已发布,但无法被搜索的解决方案

前言 我的 QQ 小程序在 2024 年 8 月就已经审核通过&#xff0c;上架后却一直无法被搜索到。打开后&#xff0c;再在 QQ 上下拉查看 “最近使用”&#xff0c;发现他出现一下又马上消失。 上线是按正常流程走的&#xff0c;开发、备案、审核&#xff0c;没有任何违规&#xf…

Java中日志采集框架-JUL、Slf4j、Log4j、Logstash

1. 日志采集 日志采集是指在软件系统、网络设备、服务器或其他IT基础设施中自动收集日志文件和事件信息的过程。这些日志通常包含了时间戳、事件类型、源和目标信息、错误代码、用户操作记录等关键数据。日志采集的目的是为了监控系统运行状态、分析系统性能、审计用户行为、故…

CSS遮罩:mask

CSS属性 mask 允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。 // 一般用位图图片做遮罩 mask: url(~/assets/images/mask.png); mask-size: 100% 100%;// 使用 SVG 图形中的形状来做遮罩 mask: url(~/assets/images/mask.svg#star);…

【python笔记01】python基础笔记汇总

文章目录 python概述计算机资源Why Pythonpython解释器解释器的种类python版本python解释器 开发工具PyCharmvscodecursor 程序的三种结构 python中的变量python中的输入输出python中的标准输入python中的格式化输出❗转义字符 运算符&#xff08;基本运算符不写&#xff09;短…

Postman之安装及汉化基本使用介绍

Postman之安装及汉化 1.安装及汉化postman2.基本使用介绍2.1.基本功能&#xff1a;2.2.编辑、查看、设置环境、全局、集合变量2.3.复制代码片段2.4.运行集合中的所有请求及引用外部文件进行参数化 1.安装及汉化postman 下载安装包 首先可以到官网下载安装包&#xff0c;需要注…

Excel如何把两列数据合并成一列,4种方法

Excel如何把两列数据合并成一列,4种方法 参考链接:https://baijiahao.baidu.com/s?id=1786337572531105925&wfr=spider&for=pc 在Excel中,有时候需要把两列或者多列数据合并到一列中,下面介绍4种常见方法,并且提示一些使用注意事项,总有一种方法符合你的要求:…

Android WMS概览

WMS&#xff08;WindowManagerService&#xff09;是 Android 系统的核心服务&#xff0c;负责管理应用和系统的窗口&#xff0c;包括窗口的创建、销毁、布局、层级管理、输入事件分发以及动画显示等。它通过协调 InputManager 和 SurfaceFlinger 实现触摸事件处理和窗口渲染&a…

Python | Leetcode Python题解之第564题寻找最近的回文数

题目&#xff1a; 题解&#xff1a; class Solution:def nearestPalindromic(self, n: str) -> str:m len(n)candidates [10 ** (m - 1) - 1, 10 ** m 1]selfPrefix int(n[:(m 1) // 2])for x in range(selfPrefix - 1, selfPrefix 2):y x if m % 2 0 else x // 10…

十六.SpringCloudAlibaba极简入门-整合Grpc代替OpenFeign

前言 他来了他来了&#xff0c;停了快2个月了终于又开始更新文章啦&#xff0c;这次带来的绝对是干货&#xff01;&#xff01;&#xff01;。由于公司项目进行重构的时候考虑到&#xff0c;OpenFeign做为服务通信组件在高并发情况下有一定的性能瓶颈&#xff0c;所以将其替换…