【GIS】Springboot JPA操作Greenplum/postgresql的空间数据

瞎摸了3+0.5天,终于解决了

应届生新入职,负责Greenplum数据库。之前没有听说过这个,而且需要使用Hibernate-spatial处理Geometry类型,Hibernate与Springboot data JPA我也是没有用过,之前学的是Springboot+Mybatis(plus)已经熟练了,这次JPA对我来说都是全新的东西,而且JPA操作greenplum的空间数据的网上资料很少,没有找到一个好的例子,只能自己走一步看一步。

正确解决方案:application.properties配置换成postgresql的jdbc的driver,url。不能使用Greenplum的jdbc与url

application.properties

#spring.datasource.driver-class-name=com.pivotal.jdbc.GreenplumDriver
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:pivotal:greenplum://xxx.xxx.x.xx:????;DatabaseName=bigdata
spring.datasource.url=jdbc:postgresql://xxx.xxx.x.xx:????/bigdata

数据库表

在这里插入图片描述
表信息

CREATE TABLE "public"."Untitled" (
  "the_geom" "public"."geometry",
  "name" varchar(255) COLLATE "pg_catalog"."default",
  "id" int4 DEFAULT nextval('city_test_one_id_seq'::regclass)
)
;

参考网上例子写的程序一直报错,看了各种错误解决方案,然后一直尝试不同的解决办法,解决错误,最后正确方案来袭!

1.导入依赖

需要使用最新的版本

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>5.4.18.Final</version>
</dependency>

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-spatial</artifactId>
	<version>5.4.18.Final</version>
</dependency>

最新版本已弃用com.vividsolutions.jts.geom.Geometry,网上多数博客都是使用的此类型。

需要换成org.geolatte.geom.Geometry类型

我也不知道要导什么依赖,导了一堆带geolatte的

<dependency>
	<groupId>org.geolatte</groupId>
	<artifactId>geolatte-geom</artifactId>
	<version>1.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-geojson -->
<dependency>
	<groupId>org.geolatte</groupId>
	<artifactId>geolatte-geojson</artifactId>
	<version>1.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-common-hibernate -->
<dependency>
	<groupId>org.geolatte</groupId>
	<artifactId>geolatte-common-hibernate</artifactId>
	<version>0.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-common -->
<dependency>
	<groupId>org.geolatte</groupId>
	<artifactId>geolatte-common</artifactId>
	<version>0.8</version>
</dependency>

配置

application.properties

#通用数据源配置
#spring.datasource.driver-class-name=com.pivotal.jdbc.GreenplumDriver
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:pivotal:greenplum://xxx.xxx.x.xx:????;DatabaseName=bigdata
spring.datasource.url=jdbc:postgresql://xxx.xxx.x.xx:????/bigdata
spring.datasource.username=gpadmin
spring.datasource.password=gpadmin

# Hikari 数据源专用配置
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
# JPA 相关配置
spring.jpa.database=postgresql
spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisPG9Dialect
#spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect
spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=true

application.yml
Entity里面@Table(“pulic.city_test_one”),如果不配置这个,JPA默认SQL里面是public_city_test_one,.被转换了,就找不到表格了。所以需要配置naming.PhysicalNamingStrategyStandardImpl

spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

2.Entity

自定义的@Convert(converter = WkbConvertToGeometry.class)解决了不能反序列化错误。使用@Convert就不能使用@Type了,报错会提示你这两个只能写其中一个。经里对我说不能使用自定义转换器!此方式不行了,又摸了一上午,解决了

正确解决方案:换postgresql的jdbc的driver,url。不能使用Greenplum的jdbc与url

application.properties

#spring.datasource.driver-class-name=com.pivotal.jdbc.GreenplumDriver
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:pivotal:greenplum://xxx.xxx.x.xx:????;DatabaseName=bigdata
spring.datasource.url=jdbc:postgresql://xxx.xxx.x.xx:????/bigdata
在这里插入代码片
import com.kqgeo.greenplum_two.utils.WkbConvertToGeometry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.geolatte.geom.Point;


import javax.persistence.*;
import java.io.Serializable;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Table(name = "public.city_test_one")
public class CityTest implements Serializable {
    
    

    private static final long serialVersionUID = 1L;

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

    @Column(name = "the_geom",columnDefinition = "geometry(Point,4326)")
    @Convert(converter = WkbConvertToGeometry.class)
    private Point the_geom;

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

}

3.Repository

@Repository
public interface CityDao extends JpaRepository<CityTest,Integer> {
    
    

}

4.Converter转换器(此方案被丢弃

public class WkbConvertToGeometry implements AttributeConverter<Point, String> {
    
    

    @Override
    public String convertToDatabaseColumn(Point geometry) {
    
    
        ByteBuffer byteBuffer = Wkb.toWkb(geometry);
        String s = String.valueOf(byteBuffer);
        return s;
    }

    @Override
    public Point convertToEntityAttribute(String wkb) {
    
    
        ByteBuffer byteBuffer=ByteBuffer.from(wkb);
        return (Point)Wkb.fromWkb(byteBuffer);
    }
}

5.测试

save()测试  //insert update成功
		CityTest c=new CityTest();
        c.setId(4);
        String pointStr1  =  "SRID=4326;POINT(115 35)";
        Point decode =(Point) Wkt.newDecoder().decode(pointStr1);
        System.out.println(decode.getSRID());
        System.out.println(Wkt.toWkt(decode));
        if (decode != null) {
    
    
            c.setThe_geom(decode);
        }
        c.setName("test");
        System.out.println(c.toString());
        cityDao.save(c);
		
查询测试   //selectById成功
		/*Optional<CityTest> byId = cityDao.findById(1);
        System.out.println(byId.get().toString());*/

猜你喜欢

转载自blog.csdn.net/qq_42158942/article/details/107225494