You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JDBI绑定JTS Geometry类型适配PostgreSQL几何类型

解决方案

报错原因

JDBI默认没有内置com.vividsolutions.jts.geom.Geometry类型的参数绑定逻辑,你通过bindBean()绑定该类型字段时,找不到对应的参数工厂完成Java类型到PostgreSQL几何类型的转换,因此抛出该异常。

最优实现方案

采用「自定义ArgumentFactory + ColumnMapper」的方案,一次注册全局生效,适配bindBean()自动绑定逻辑,无需额外修改现有业务代码。

步骤1:引入必要依赖

确保项目中已引入PostGIS JDBC适配器与JTS依赖(Maven示例):

<dependency>
    <groupId>org.postgis</groupId>
    <artifactId>postgis-jdbc</artifactId>
    <version>2.5.1</version> <!-- 适配你的PostgreSQL服务版本 -->
</dependency>
<dependency>
    <groupId>com.vividsolutions</groupId>
    <artifactId>jts-core</artifactId>
    <version>1.14.0</version> <!-- 和你现有使用的版本保持一致 -->
</dependency>

步骤2:实现Geometry参数工厂

自定义ArgumentFactory,完成JTS Geometry到PostGIS数据库类型的转换:

import com.vividsolutions.jts.geom.Geometry;
import org.jdbi.v3.core.argument.AbstractArgumentFactory;
import org.jdbi.v3.core.argument.Argument;
import org.jdbi.v3.core.config.ConfigRegistry;
import org.postgis.PGgeometry;
import org.postgis.jts.JtsGeometry;

import java.sql.Types;

public class GeometryArgumentFactory extends AbstractArgumentFactory<Geometry> {
    public GeometryArgumentFactory() {
        super(Types.OTHER);
    }

    @Override
    protected Argument build(Geometry value, ConfigRegistry config) {
        return (position, statement, ctx) -> {
            PGgeometry pgGeometry = new JtsGeometry(value);
            statement.setObject(position, pgGeometry);
        };
    }
}

步骤3:实现Geometry结果映射器

如果需要将查询返回的几何字段自动映射为JTS Geometry类型,同步实现ColumnMapper:

import com.vividsolutions.jts.geom.Geometry;
import org.jdbi.v3.core.mapper.ColumnMapper;
import org.jdbi.v3.core.statement.StatementContext;
import org.postgis.PGgeometry;
import org.postgis.jts.JtsGeometry;

import java.sql.ResultSet;
import java.sql.SQLException;

public class GeometryColumnMapper implements ColumnMapper<Geometry> {
    @Override
    public Geometry map(ResultSet r, int columnNumber, StatementContext ctx) throws SQLException {
        PGgeometry pgGeom = (PGgeometry) r.getObject(columnNumber);
        if (pgGeom instanceof JtsGeometry) {
            return ((JtsGeometry) pgGeom).getGeometry();
        }
        return null;
    }
}

步骤4:全局注册到JDBI实例

初始化JDBI时注册上述组件,后续所有bindBean()操作都会自动适配Geometry类型字段:

Jdbi jdbi = Jdbi.create(dataSource);
jdbi.registerArgument(new GeometryArgumentFactory());
jdbi.registerColumnMapper(Geometry.class, new GeometryColumnMapper());

验证使用

你的业务代码无需做任何修改,正常使用bindBean()绑定包含Geometry字段的Bean即可:

// 示例Bean定义
public class GeoEntity {
    private Long id;
    private Geometry point;
    // 省略getter/setter
}

// 插入示例
jdbi.useHandle(handle -> {
    handle.createUpdate("INSERT INTO geo_table (id, point) VALUES (:id, :point)")
          .bindBean(new GeoEntity(1L, yourGeometryObject))
          .execute();
});

内容的提问来源于stack exchange,提问作者oshai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 07:51:02