数据访问框架
GeoTools 中的数据访问框架提供了统一的 API,用于从各种来源访问和操作地理空间数据。本文档专注于核心架构、抽象和实现,这些实现了跨不同存储格式的一致数据访问,特别强调用于关系数据库的基于 JDBC 的实现。
有关特定几何形状处理的信息,请参阅 空间数据模型。有关支持的数据格式的详细信息,请参阅 格式支持。
架构概述
数据访问框架围绕几个关键接口和抽象类构建,这些类定义了访问地理空间数据的一致 API。
核心接口
该框架围绕这些关键接口构建:
- DataStore: 访问地理空间数据的入口点。负责 feature 类型(模式)管理和创建 feature sources。
- FeatureSource: 提供对特定类型 features 的只读访问,支持查询和过滤。
- FeatureStore: 扩展 FeatureSource 以添加写入功能。
- FeatureReader: 迭代从查询返回的 features。
- FeatureWriter: 启用 features 的修改。
- Query: 定义检索数据的参数(过滤、投影、排序)。
- Transaction: 在多个操作中启用 ACID 操作。
- Filter: 确定哪些 features 包含在结果中的表达式。
JDBC 实现
JDBC 实现提供对关系数据库的访问。它使用插件架构,其中数据库特定代码封装在"dialect"类中。
JDBCDataStore
JDBCDataStore 是 JDBC 实现的中心类。它扩展了 ContentDataStore 并提供:
- 通过
DataSource进行连接管理 - SQL 和 Java 类型之间的类型映射
- 模式和表管理
- 通过
JDBCFeatureSource和JDBCFeatureStore进行 feature 访问
JDBCDataStore 的主要属性:
| 属性 | 描述 |
|---|---|
dataSource | 用于数据库连接的 JDBC 数据源 |
dialect | 数据库特定的 SQLDialect 实现 |
databaseSchema | 要使用的数据库模式 |
sqlTypeToClassMappings | 将 SQL 类型映射到 Java 类 |
classToSqlTypeMappings | 将 Java 类映射到 SQL 类型 |
fetchSize | 控制一次批量获取的记录数 |
batchInsertSize | 控制插入操作的批量大小 |
exposePrimaryKeyColumns | 是否将主键列作为属性公开 |
SQLDialect
SQLDialect 抽象类封装了数据库特定操作。它处理:
- SQL 类型和 Java 类型之间的类型映射
- 几何编码和解码
- 用于空间操作的 SQL 生成
- 主键和外键管理
每个支持的数据库都有自己的方言实现:
- 用于 PostgreSQL/PostGIS 的
PostGISDialect - 用于 Oracle Spatial 的
OracleDialect - 以及其他用于 MySQL、SQL Server、H2 等的方言
类型映射
JDBC 实现的一个关键特性是 SQL 类型和 Java 类型之间的映射。每个 SQLDialect 注册以下内容的映射:
- SQL 类型代码到 Java 类
- SQL 类型名称到 Java 类
- Java 类到 SQL 类型代码
默认映射包括:
| 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[] |
数据库特定方言通过额外类型扩展这些映射,尤其是几何形状。
Filter 到 SQL 的转换
该框架包括强大的机制,用于将 OGC Filter 对象转换为 SQL WHERE 子句:
FilterToSQL 类及其子类处理此转换:
FilterToSQL: 将 filters 转换为 SQL 的基类PreparedFilterToSQL: 使用 prepared statements 以获得更好的性能和安全性PostgisFilterToSQL、OracleFilterToSQL: 数据库特定实现
主要功能包括:
- 将属性比较转换为列比较
- 将空间操作转换为数据库特定函数
- 支持复杂表达式和函数
- 处理 NULL 值和类型转换
- 通过 prepared statements 提供安全性以防止 SQL 注入
Feature 访问流程
通过 JDBC 实现访问 features 的过程遵循以下一般流程:
数据库特定方言
该框架包括针对不同数据库的专门方言:
PostGIS 方言
PostGISDialect 提供对带有 PostGIS 扩展的 PostgreSQL 的支持:
- 将 PostGIS 几何类型映射到 JTS 几何类
- 将 JTS 几何编码为 PostGIS 格式
- 将空间 filters 转换为 PostGIS 函数(ST_Intersects、ST_Contains 等)
- 处理 PostgreSQL 特定功能,如数组类型和 JSON
// PostGIS 几何类型映射示例
static final Map<String, Class> TYPE_TO_CLASS_MAP = Map.ofEntries(
entry("GEOMETRY", Geometry.class),
entry("POINT", Point.class),
entry("LINESTRING", LineString.class),
entry("POLYGON", Polygon.class),
entry("MULTIPOINT", MultiPoint.class),
entry("MULTILINESTRING", MultiLineString.class),
entry("MULTIPOLYGON", MultiPolygon.class),
entry("GEOMETRYCOLLECTION", GeometryCollection.class),
// ...额外映射
);Oracle 方言
OracleDialect 提供对 Oracle Spatial 的支持:
- 将 Oracle SDO_GEOMETRY 类型映射到 JTS 几何类
- 将 JTS 几何编码为 Oracle SDO_GEOMETRY 格式
- 将空间 filters 转换为 Oracle 函数(SDO_RELATE、SDO_WITHIN_DISTANCE 等)
- 处理 Oracle 特定功能,如 MDSYS 模式和数据库提示
// Oracle 空间操作符映射示例
private static final Map<Class<?>, String> SDO_RELATE_MASK_MAP = Map.of(
Contains.class, "contains",
Crosses.class, "overlapbdydisjoint",
Equals.class, "equal",
Overlaps.class, "overlapbdyintersect",
Touches.class, "touch",
Within.class, "inside",
Disjoint.class, "disjoint",
BBOX.class, "anyinteract",
Intersects.class, "anyinteract");聚合函数和访问者
该框架通过访问者模式支持数据库优化的聚合函数:
该框架将 feature 访问者映射到 SQL 聚合函数:
| 访问者 | SQL 函数 |
|---|---|
| CountVisitor | COUNT() |
| MinVisitor | MIN() |
| MaxVisitor | MAX() |
| SumVisitor | SUM() |
| AverageVisitor | AVG() |
| UniqueVisitor | DISTINCT |
| StandardDeviationVisitor | STDDEV_POP() |
这直接在数据库中高效处理聚合操作,而不是客户端计算。
扩展点
该框架设计为可扩展以支持新数据库或数据源:
新数据库支持:
- 为数据库实现
SQLDialect - 创建数据库特定的
FilterToSQL类 - 注册类型映射
- 为数据库实现
自定义 Feature Sources:
- 扩展
ContentFeatureSource进行只读访问 - 扩展
ContentFeatureStore进行读写访问
- 扩展
自定义类型映射:
- 注册 Java 到 SQL 类型映射
- 注册 SQL 到 Java 类型映射
- 在方言中覆盖类型映射方法
结论
数据访问框架为处理存储在各种来源中的地理空间数据提供了强大且灵活的系统。JDBC 实现为关系数据库提供了强大的解决方案,并对不同数据库系统提供专门支持。
该框架的主要优势包括:
- 跨不同数据源的一致 API
- 支持新数据库的可扩展架构
- 高效的 SQL 生成和执行
- 强大的过滤和查询功能
- 支持事务和锁定
- 优化的几何数据处理
通过理解本文档中描述的架构和组件,开发者可以有效地使用和扩展框架以满足其地理空间数据访问需求。