Data Access Framework
The Data Access Framework in GeoTools provides a unified API for accessing and manipulating geospatial data from various sources. This document focuses on the core architecture, abstractions, and implementations that enable consistent data access across different storage formats, with particular emphasis on the JDBC-based implementation for relational databases.
For information about specific geometry handling, see Spatial Data Model. For detailed information on supported data formats, see Format Support.
Architecture Overview
The Data Access Framework is built around several key interfaces and abstract classes that define a consistent API for accessing geospatial data.
Core Interfaces
The framework is built around these key interfaces:
- DataStore: The entry point for accessing geospatial data. Responsible for feature type (schema) management and creating feature sources.
- FeatureSource: Provides read-only access to features of a specific type, supports querying and filtering.
- FeatureStore: Extends FeatureSource to add write capabilities.
- FeatureReader: Iterates over features returned from a query.
- FeatureWriter: Enables modification of features.
- Query: Defines parameters for retrieving data (filtering, projection, sorting).
- Transaction: Enables ACID operations across multiple operations.
- Filter: Expression that determines which features to include in a result.
JDBC Implementation
The JDBC implementation provides access to relational databases. It uses a plugin architecture where database-specific code is encapsulated in "dialect" classes.
JDBCDataStore
JDBCDataStore is the central class of the JDBC implementation. It extends ContentDataStore and provides:
- Connection management through a
DataSource - Type mapping between SQL and Java types
- Schema and table management
- Feature access through
JDBCFeatureSourceandJDBCFeatureStore
Key properties of JDBCDataStore:
| Property | Description |
|---|---|
dataSource | The JDBC data source for database connections |
dialect | Database-specific implementation of SQLDialect |
databaseSchema | The database schema to use |
sqlTypeToClassMappings | Maps SQL types to Java classes |
classToSqlTypeMappings | Maps Java classes to SQL types |
fetchSize | Controls the number of records fetched in one batch |
batchInsertSize | Controls batch size for insert operations |
exposePrimaryKeyColumns | Whether to expose primary key columns as attributes |
SQLDialect
The SQLDialect abstract class encapsulates database-specific operations. It handles:
- Type mappings between SQL types and Java types
- Geometry encoding and decoding
- SQL generation for spatial operations
- Primary key and foreign key management
Each supported database has its own dialect implementation:
PostGISDialectfor PostgreSQL/PostGISOracleDialectfor Oracle Spatial- And others for MySQL, SQL Server, H2, etc.
Type Mapping
A key feature of the JDBC implementation is the mapping between SQL types and Java types. Each SQLDialect registers mappings for:
- SQL type codes to Java classes
- SQL type names to Java classes
- Java classes to SQL type codes
Default mappings include:
| SQL Type | Java Class |
|---|---|
| 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[] |
Database-specific dialects extend these mappings with additional types, especially for geometry.
Filter to SQL Translation
The framework includes a powerful mechanism to translate OGC Filter objects to SQL WHERE clauses:
The FilterToSQL class and its subclasses handle this translation:
FilterToSQL: Base class for translating filters to SQLPreparedFilterToSQL: Uses prepared statements for better performance and securityPostgisFilterToSQL,OracleFilterToSQL: Database-specific implementations
Key capabilities include:
- Translation of property comparisons to column comparisons
- Conversion of spatial operations to database-specific functions
- Support for complex expressions and functions
- Handling of NULL values and type conversions
- Security through prepared statements to prevent SQL injection
Feature Access Flow
The process of accessing features through the JDBC implementation follows this general flow:
Database-Specific Dialects
The framework includes specialized dialects for different databases:
PostGIS Dialect
The PostGISDialect provides support for PostgreSQL with the PostGIS extension:
- Maps PostGIS geometry types to JTS geometry classes
- Encodes JTS geometries to PostGIS format
- Translates spatial filters to PostGIS functions (ST_Intersects, ST_Contains, etc.)
- Handles PostgreSQL-specific features like array types and JSON
// Example of PostGIS geometry type mapping
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),
// ...additional mappings
);Oracle Dialect
The OracleDialect provides support for Oracle Spatial:
- Maps Oracle SDO_GEOMETRY types to JTS geometry classes
- Encodes JTS geometries to Oracle SDO_GEOMETRY format
- Translates spatial filters to Oracle functions (SDO_RELATE, SDO_WITHIN_DISTANCE, etc.)
- Handles Oracle-specific features like MDSYS schema and database hints
// Example of Oracle spatial operator mapping
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");Aggregation Functions and Visitors
The framework supports database-optimized aggregation functions through the visitor pattern:
The framework maps feature visitors to SQL aggregate functions:
| Visitor | SQL Function |
|---|---|
| CountVisitor | COUNT() |
| MinVisitor | MIN() |
| MaxVisitor | MAX() |
| SumVisitor | SUM() |
| AverageVisitor | AVG() |
| UniqueVisitor | DISTINCT |
| StandardDeviationVisitor | STDDEV_POP() |
This enables efficient processing of aggregate operations directly in the database rather than client-side computation.
Extension Points
The framework is designed to be extended for new databases or data sources:
New Database Support:
- Implement
SQLDialectfor your database - Create database-specific
FilterToSQLclass - Register type mappings
- Implement
Custom Feature Sources:
- Extend
ContentFeatureSourcefor read-only access - Extend
ContentFeatureStorefor read-write access
- Extend
Custom Type Mappings:
- Register Java to SQL type mappings
- Register SQL to Java type mappings
- Override type mapping methods in your dialect
Conclusion
The Data Access Framework provides a powerful and flexible system for working with geospatial data stored in various sources. The JDBC implementation offers a robust solution for relational databases, with specialized support for different database systems.
The key strengths of the framework include:
- Consistent API across different data sources
- Extensible architecture for supporting new databases
- Efficient SQL generation and execution
- Powerful filtering and query capabilities
- Support for transactions and locking
- Optimized handling of geometric data
By understanding the architecture and components described in this document, developers can effectively use and extend the framework to meet their geospatial data access needs.