【MyBatis】MyBatis使用TypeHandle对Geometry进行操作

0.项目环境

0.1 build.gradle.kts文件重点如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
repositories {
// 第一步的,需要加入下面两个仓库,且需要放在最前面,因为有个依赖aliyun下载不下来
maven { url = uri("https://repo.osgeo.org/repository/release/") }
maven { url = uri("https://repo.osgeo.org/repository/snapshot/") }
maven { url = uri("https://maven.aliyun.com/repository/public/") }
mavenCentral()
}

dependencies {
// 数据库相关用到的依赖如下
implementation("com.baomidou:mybatis-plus-boot-starter:3.5.4")
implementation("org.jetbrains:annotations:24.0.0")
runtimeOnly("org.postgresql:postgresql")
// geom工具类
implementation("net.postgis:postgis-jdbc:2021.1.0")
implementation("org.geotools:gt-geometry:24.7")
implementation("org.geotools:gt-geojson:24.7")
}

1.实现一个自己的BaseTypeHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

package com.kmlpkj.smart.village.api.configuration.mybatis.handler

import cn.hutool.extra.spring.SpringUtil
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.ibatis.type.BaseTypeHandler
import org.apache.ibatis.type.JdbcType
import org.geotools.geojson.geom.GeometryJSON
import org.locationtech.jts.io.ByteOrderValues
import org.locationtech.jts.io.WKBReader
import org.locationtech.jts.io.WKBWriter
import org.postgresql.util.PGobject
import org.slf4j.LoggerFactory
import java.sql.CallableStatement
import java.sql.PreparedStatement
import java.sql.ResultSet


/**
* Geom字段格式化处理
*/
class GeomTypeHandler : BaseTypeHandler<Any>() {

companion object {
private val log = LoggerFactory.getLogger(this::class.java)
}

override fun getNullableResult(rs: ResultSet?, columnName: String?): Any? {
rs?.getString(columnName)?.let {
return convert(it)
}
return null
}

override fun getNullableResult(rs: ResultSet?, columnIndex: Int): Any? {
rs?.getString(columnIndex)?.let {
return convert(it)
}
return null
}

override fun getNullableResult(cs: CallableStatement?, columnIndex: Int): Any? {
cs?.getString(columnIndex)?.let {
return convert(it)
}
return null
}

override fun setNonNullParameter(ps: PreparedStatement?, i: Int, parameter: Any?, jdbcType: JdbcType?) {
val om = SpringUtil.getBean(ObjectMapper::class.java)
try {
val geom = GeometryJSON(10).read(om.readTree(parameter.toString()).toPrettyString())
geom.srid = 4490
val writer = WKBWriter(2, ByteOrderValues.BIG_ENDIAN, true)
val bytes = writer.write(geom)
val s1 = WKBWriter.toHex(bytes)
ps?.setObject(i, PGobject().also {
it.type = "geometry"
it.value = s1
})
} catch (e: Exception) {
e.printStackTrace()
throw RuntimeException("转换geom字段失败")
}
}

private fun convert(wkb: String): Any {
try {
val geom = WKBReader().read(WKBReader.hexToBytes(wkb))
val str = GeometryJSON(10).toString(geom)
return SpringUtil.getBean(ObjectMapper::class.java).readTree(str)
} catch (e: Exception) {
e.printStackTrace()
throw RuntimeException("转换geom字段失败")
}
}
}

2.在对应的实体上加入TypeHandler

1
2
3
4
5
6
7
8
9
10

// 第一 需要在@TableName注解中启用autoResultMap = true
// 第二 需要在@TableField注解中指定typeHandler

@TableName(value = "xx", autoResultMap = true)
class Grid {
@TableField(value = "geom", typeHandler = GeomTypeHandler::class)
var geom: Any? = null
}

3.在对于Mapper中指定TypeHandler

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kmlpkj.smart.village.api.mapper.GridMapper">
<resultMap id="BaseResultMap" type="xxx">
<!-- 在typeHandler中指定我们的文件,这里是不是必须得我没尝试,但是我都加上了 -->
<result column="geom" jdbcType="OTHER" property="geom" typeHandler="xxx.GeomTypeHandler"/>
</resultMap>
</mapper>

4.对应的格式说明

4.1 入参格式

入参格式如下,只需要传GeoJSON格式中的具体的geometry字段的内容即可

格式内容支持:Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon和GeometryCollection

1
2
3
4
5
6
7
8
9
10
11
{
"type": "Polygon",
"coordinates": [
[
[
104.03273502416919,
23.810639861962807
]
]
]
}

4.2 应用后查询格式说明

查询后的格式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"geom": {
"type": "Polygon",
"coordinates": [
[
[
105.3362898252,
23.8315432677
]
]
]
}
}

【MyBatis】MyBatis使用TypeHandle对Geometry进行操作
https://www.yangxj96.com/MyBatis/MyBatisTypeHandlerPostGIS/
作者
道一
发布于
2023年11月2日
许可协议