java - 无法解析 serviceImpl 类中的 'ST_GeomFromText'

标签 java mysql spring jpa geojson

我正在尝试通过 JPA 将几何数据保存到 MySQL 表。

georepository.save("id", ST_GeomFromText('POLYGON((0 1, 2 5, 2 7, 0 7, 0 1))') ); 

但我得到:

Can not resolve 'ST_GeomFromText' in serviceImpl class.

这是我的模型

public class Mygeo {

   @Id
   @Column(name = "id")
   private String id;

   @Column(name = "geodata", nullable = false)
   private Geometry geodata;
}

这就是我在数据库中手动保存的方式。 JPA 的替代方法是什么来保存这个。

INSERT INTO mygeo (id, geodata)VALUES ("ID",ST_GeomFromText('POLYGON((0 1, 2 5, 2 7, 0 7, 0 1))'));

注意:我确实可以访问这样的几何字符串

System.out.println(geometryObject.toString());
{"coordinates":[[[0,1],[2,5],[2,7],[0,7],[0,1]]],"type":"Polygon"}

最佳答案

下面详细介绍了使用 Spring Data JPA 将几何数据保存到数据库的方法(逐步):


我将借助一个项目进行解释。

项目结构:

enter image description here

MyGeo 实体:

package com.solve.problemssolve;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

import org.locationtech.jts.geom.Geometry;

import lombok.Data;

@Data
@Entity
public class MyGeo {

    @Id
    @Column(name = "id")
    private String id;

    @Column(name = "geodata", nullable = false)
    private Geometry geodata;
}

MyGeoRepository 类

package com.solve.problemssolve;

import org.springframework.data.jpa.repository.JpaRepository;

public interface MyGeoRepository extends JpaRepository<MyGeo, String> {

}

应用程序属性:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=Anish@123
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.mysql.MySQL5SpatialDialect

注意:您必须在 Spring Boot 应用程序中启用 org.hibernate.spatial.dialect.mysql.MySQL5SpatialDialect 才能支持空间功能。

根据MySQL5SpatialDialect Hibernate docs :

It is a dialect for MySQL 5 using InnoDB engine, with support for its spatial features.

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.4</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.solve</groupId>
    <artifactId>problems-solve</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>problems-solve</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-spatial</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

在 MySQL DB(表结构)中:

enter image description here

注意:该表是由 Hibernate 自动生成的,因为我保留了 ddl-auto=update,但您也可以手动创建表。

资源类别:

@RestController
public class Resource {

    @Autowired
    private MyGeoRepository myGeoRepository;
    
    @GetMapping("/save")
    public void save() throws ParseException {
        WKTReader wktReader = new WKTReader();
        Geometry geometry = wktReader.read("POLYGON((0 1, 2 5, 2 7, 0 7, 0 1))");
        System.out.println(geometry);
        MyGeo geo = new MyGeo();
        geo.setGeodata(geometry);
        geo.setId("ID");
        myGeoRepository.save(geo); 
        System.out.println(myGeoRepository.findById("ID"));
    }
        
}

您必须使用WKTReader通过JPA保存数据。

根据WKTReader文档:

Converts a geometry in Well-Known Text format to a Geometry.

WKTReader supports extracting Geometry objects from either Readers or Strings. This allows it to function as a parser to read Geometry objects from text blocks embedded in other data formats (e.g. XML).

A WKTReader is parameterized by a GeometryFactory, to allow it to create Geometry objects of the appropriate implementation. In particular, the GeometryFactory determines the PrecisionModel and SRID that is used.

The WKTReader converts all input numbers to the precise internal representation.

根据WKTReader.read(String wellKnownText)文档:

It reads a Well-Known Text representation of a Geometry from a String.

此 SQL 语句 ST_GeomFromText('POLYGON((0 1, 2 5, 2 7, 0 7, 0 1))') 相当于此行 Geometry Geometry = wktReader.读取(“多边形((0 1, 2 5, 2 7, 0 7, 0 1))”);

一旦我运行了该示例,它就成功保存了,没有任何问题。

服务器日志截图:

enter image description here

数据库行截图:

enter image description here

关于java - 无法解析 serviceImpl 类中的 'ST_GeomFromText',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73798390/

相关文章:

java - 延迟后在 EDT 上运行

mysql - 根据空日期字段更新mysql中的日期格式

mysql - 编写如何删除扩展名并放入单独列的脚本

mysql - 从 MySQL 中的自动递增索引更改

java - 在测试和生产中具有不同模式的 JPA 实体

java - eclipse spring 中正确的文件路径是什么

java - Desktop.isDesktopSupported() 在 jar 中崩溃

java - Hadoop 2.6.0 的 Eclipse 插件

java - 如何设置 tanuki 包装器的 java 转储文件位置

java - Quartz & Spring - 集群但不持久?