지도 API에 사용할 좌표 데이터를 DB에 관리하려고 하는 중 지원하는 기능이 없나 찾아보니 MySQL에서 Point 자료형과 JPA에서 Hibernate Spatial을 사용하여 좌표 데이터를 편리하게 다룰 수 있다.
위에 문서를 보면 Hibernate Spatial은 지리 데이터 저장 및 쿼리 기능에 대한 표준화된 교차 데이터베이스 인터페이스를 제공하며 Oracle 10g/11g, PostgreSQL/PostGIS, MySQL 등의 데이터베이스에서 지원 가능하다고 한다. Hibernate Spatial은 JTS와 geolatte-geom이라는 두 라이브러리를 지원하는데 JTS는 사실상의 표준, Geolatte-geom은 JTS에서는 사용할 수 없는 많은 기능을 지원하는 최신 라이브러리다.
Jts, GeoLatte
build.gradle
build.gradle 설정은 간단하다. (원래는 build.gradle에 hibernate 버전을 맞춰서 적어줘야 되는데 Hibernate 5.2.x 이후부터는 org.hibernate:hibernate-spatial만 추가하면 된다고 한다)
implementation group: 'org.hibernate', name: 'hibernate-spatial'
Hibernate Spatial은 데이터베이스의 공간 기능을 HQL 및 JPQL 내에서 사용할 수 있도록 Hibernate ORM 방언을 확장할 수 있는데 5.6.1 이전의 MySQL 버전은 공간 연산자에 대한 지원이 제한적이었지만 5.6.1 버전 이후 공간 연산자가 도입되면서 방언MySQLSpatial56Dialect를 통해 새롭고 정확한 연산자를 지원한다.
(MySQLSpatialDialect -> MySQL5SpatialDialect -> MySQLSpatial56Dialect)
그래서 applicaiton 설정에 MySQL56InnoDBSpatialDialect를 추가해주었다.
apllication yml
jpa:
database-platform: org.hibernate.spatial.dialect.mysql.MySQL56InnoDBSpatialDialect
지도의 좌표 데이터 정도만 사용을 하려고 하기 때문에 사용하는 부분은 간단하다.
import org.locationtech.jts.geom.Point;
Point를 그대로 반환하면 Json이 변환을 못해서 추가 처리를 해야 되는데 간단하게 X, Y값을 빼내서 Dto로 만들었다.
마지막으로 MySQL에서 공간 자료형인 POINT 컬럼을 추가하면 깔끔하게 해결 된다.
'JPA' 카테고리의 다른 글
[JPA] fetch join 주의점 (0) | 2022.12.20 |
---|---|
[JPA] 변경 감지와 병합(merge) (0) | 2022.07.08 |
[JPA] 엔티티(Entity)에 기본 생성자를 선언해야 하는 이유 (Builder 패턴, static factory method) (0) | 2022.07.07 |
[JPA] JPQL (0) | 2022.07.05 |
[JPA] 프록시를 이용한 지연 로딩(FetchType.LAZY)과 연관관계 옵션(영속성 전이, 고아 객체) (0) | 2022.06.30 |