JDBC 数据存储
相关源文件:
介绍
JDBC 数据存储提供了一个框架,用于通过 JDBC API 访问存储在关系数据库中的地理空间数据。这些数据存储在 GeoTools Feature API 和各种数据库系统之间架起了桥梁,允许应用程序使用空间数据而无需理解每个数据库的特定 SQL 方言或空间扩展。
本页涵盖了 GeoTools 中 JDBC 数据存储的架构和功能,重点介绍了它们如何连接到数据库、处理空间数据类型以及提供对数据库表的 feature 级访问。有关特定文件格式的信息,请参阅 格式支持。
架构
JDBC 数据存储架构遵循模块化设计,通过通用 API 实现连接到不同数据库系统。核心组件包括:
中心类 JDBCDataStore 为 JDBC 源实现了 DataStore 接口。它将数据库特定操作委托给适当的 SQLDialect 实现。feature 访问通过 JDBCFeatureSource(只读)和 JDBCFeatureStore(读写)类提供。
SQL 方言
SQL 方言系统是一个关键抽象,允许 JDBC 数据存储与不同数据库系统一起工作。每个方言实现处理其目标数据库的特定 SQL 语法和功能,尤其是对于空间操作。
每个方言负责:
- 在数据库和 JTS 之间转换几何对象
- 将 SQL 类型映射到 Java 类型
- 将 GeoTools filters 转换为 SQL WHERE 子句
- 处理数据库特定的空间函数
类型映射
JDBC 数据存储提供了在 SQL 数据类型和 Java 对象之间转换的类型映射系统。SQL 方言确定如何处理这些映射,定义标准映射和任何数据库特定类型。
基本 SQLDialect 类中定义的标准类型映射包括:
| SQL 类型 | Java 类型 |
|---|---|
| VARCHAR、CHAR、LONGVARCHAR | String |
| BIT、BOOLEAN | Boolean |
| SMALLINT、TINYINT | Short |
| INTEGER | Integer |
| BIGINT | Long |
| REAL | Float |
| DOUBLE、FLOAT | Double |
| DECIMAL、NUMERIC | BigDecimal |
| DATE | java.sql.Date |
| TIME | java.sql.Time |
| TIMESTAMP | java.sql.Timestamp |
| BLOB、BINARY | byte[] |
每个方言可以使用数据库特定类型扩展这些映射:
- PostGIS 将
geometry和geography列映射到 JTS 几何类型 - Oracle 将
SDO_GEOMETRY列映射到 JTS 几何类型 - PostgreSQL/PostGIS 支持 JSON 和 JSONB 列类型
Feature 访问
JDBC 数据存储提供基于 Feature 的 API,用于访问关系数据库中的数据。读取 features 的典型过程流程包括:
写入 features 时,过程使用 JDBCFeatureStore 方法,如 addFeatures()、modifyFeatures() 和 removeFeatures()。
feature 类型(模式)从数据库元数据构建,检测几何列并从数据库配置适当的坐标参考系统信息。
Filter 转换
JDBC 数据存储的关键功能之一是将 GeoTools filters 转换为 SQL WHERE 子句。这允许应用程序使用标准的 GeoTools Filter API,同时利用数据库特定的索引和优化。
filter 转换过程由 FilterToSQL 类及其数据库特定子类处理。这些类实现访问者模式,将不同的 filter 类型转换为适当的 SQL 语法。
支持的 filter 类型包括:
- 比较 filters(等于、大于等)
- 逻辑 filters(AND、OR、NOT)
- 空间 filters(BBOX、Intersects、Contains 等)
- 属性存在 filters(PropertyIsNull)
- 字符串匹配 filters(PropertyIsLike)
- 时间 filters(Before、After、During)
对于空间 filters,每个方言转换为适当的数据库特定函数:
- PostGIS:
ST_Intersects、ST_Contains等 - Oracle: 带有适当掩码的
SDO_RELATE
高级功能
主键和外键
JDBC 数据存储处理主键以启用 feature 识别和编辑。主键从数据库元数据自动检测,或可以手动配置。PrimaryKeyFinder 接口提供识别主键的策略,具有基于元数据和启发式方法的实现。
默认情况下,主键列不在 feature 类型中公开,但可以使用 setExposePrimaryKeyColumns(true) 方法更改此设置。
虚拟表
JDBC 数据存储支持虚拟表,这是在数据存储内而不是在数据库中定义的 SQL 视图。虚拟表允许将复杂查询或连接封装为单个 feature 类型。
VirtualTable vt = new VirtualTable("view_name", "SELECT * FROM base_table WHERE condition");
dataStore.createVirtualTable(vt);批操作
为了在插入多个 features 时获得更好的性能,JDBC 数据存储支持批操作。批量大小可以使用 setBatchInsertSize(int) 方法配置。
事务
事务通过 GeoTools Transaction API 处理,其中 JDBC 事务管理数据库连接。这允许原子操作和不同事务上下文之间的隔离。
聚合函数
通过访问者模式支持数据库端聚合。SumVisitor、CountVisitor、MaxVisitor 等访问者在可能时转换为 SQL 聚合函数:
| 访问者 | SQL 函数 |
|---|---|
| CountVisitor | COUNT |
| SumVisitor | SUM |
| MinVisitor | MIN |
| MaxVisitor | MAX |
| AverageVisitor | AVG |
| StandardDeviationVisitor | STDDEV_POP |
| UniqueVisitor | DISTINCT |
数据库特定实现
PostGIS
PostGIS JDBC 数据存储提供对带有 PostGIS 扩展的 PostgreSQL 数据库中空间数据的访问。它支持:
- 所有标准 PostGIS 几何类型
- 曲线几何形状(CircularString、CompoundCurve)
- Geography 类型(大地测量坐标)
- 使用 PostgreSQL/PostGIS && 操作符的空间索引
- JSON 和 JSONB 列类型
- 高级 PostGIS 特定函数
Oracle Spatial
Oracle JDBC 数据存储提供对使用 Oracle Spatial 的 Oracle 数据库中空间数据的访问。它支持:
- Oracle SDO_GEOMETRY 类型
- 大地测量几何形状(大地测量坐标系统)
- 使用 SDO_FILTER 和 SDO_RELATE 的空间索引
- SDO_NN(最近邻)查询
- JSON 列类型
配置
JDBC 数据存储通常配置为到数据库的连接和适当的方言。基本配置参数包括:
| 参数 | 描述 |
|---|---|
| dataSource | 用于数据库连接的 JDBC DataSource |
| dialect | 数据库的 SQLDialect 实现 |
| databaseSchema | 限制表的架构名称 |
| fetchSize | 每个数据库查询获取的行数 |
| exposePrimaryKeyColumns | 是否在 feature 类型中包含主键列 |
配置示例:
DataSource dataSource = DataSourceUtil.setupDataSource(
"jdbc:postgresql://localhost/database", "org.postgresql.Driver",
"username", "password");
JDBCDataStore dataStore = new JDBCDataStore();
dataStore.setDataSource(dataSource);
dataStore.setSQLDialect(new PostGISDialect(dataStore));
dataStore.setDatabaseSchema("public");
dataStore.setFetchSize(1000);性能考虑
几个配置选项影响 JDBC 数据存储性能:
Fetch 大小: 控制每次数据库往返检索的行数。默认为 1000。
dataStore.setFetchSize(2000);批插入大小: 控制在单个批操作中插入多少 features。默认为 1。
dataStore.setBatchInsertSize(100);连接池: JDBC 数据存储受益于连接池,通常由 DataSource 实现。
空间索引: 确保数据库表具有适当的空间索引,以获得空间查询的最佳性能。
松散 BBOX: 某些方言支持"松散 BBOX"模式,该模式仅使用 BBOX 查询的空间索引,提高性能。
((PostGISDialect)dataStore.getSQLDialect()).setLooseBBOXEnabled(true);
创建自定义方言
为了支持新的数据库系统,开发者可以通过扩展 BasicSQLDialect 或 PreparedStatementSQLDialect 创建自定义 SQL 方言。要实现的关键方法包括:
encodeGeometryColumn()- 在 SQL 中编码几何列decodeGeometryValue()- 将数据库几何转换为 JTSencodeGeometryValue()- 将 JTS 几何转换为数据库格式registerSqlTypeToClassMappings()- 定义 SQL 到 Java 类型映射createFilterToSQL()- 创建自定义 filter-to-SQL 转换器
方言还必须处理主键检测和任何数据库特定的空间操作。
测试 JDBC 实现
GeoTools 为测试 JDBC 数据存储实现提供了框架,包括离线单元测试和连接到实际数据库的在线集成测试。
在线测试使用用户 ~/.geotools 目录中的夹具文件指定连接参数。这些测试在正常构建期间跳过,但可以针对特定数据库执行以进行集成测试。
测试框架包括:
JDBCTestSetup用于配置测试数据库JDBCTestSupport作为测试用例的基类OnlineTestCase用于在测试中管理数据库连接
总结
JDBC 数据存储为访问关系数据库中的空间数据提供了强大且灵活的方式。通过在通用 API 后面抽象数据库特定细节,它们允许 GeoTools 应用程序使用相同代码与不同数据库系统一起工作。方言系统实现了对数据库特定空间操作的支持,而类型映射系统处理 SQL 和 Java 类型之间的转换。
此架构使 JDBC 数据存储成为需要访问存储在企业数据库系统(如 PostgreSQL/PostGIS、Oracle Spatial 等)中的地理空间数据的 GeoTools 应用程序的基本组件。