Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@
<module>onion-architecture</module>
<module>microservices-bulkhead</module>
<module>microservices-load-shedding</module>
<module>table-data-gateway</module>
</modules>
<repositories>
<repository>
Expand Down Expand Up @@ -323,6 +324,12 @@
<version>${system-lambda.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
Expand Down
54 changes: 54 additions & 0 deletions table-data-gateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: "Table Data Gateway Pattern in Java: Encapsulating Table Operations"
shortTitle: Table Data Gateway
description: "Learn how the Table Data Gateway pattern centralizes SQL operations for a database table behind a single gateway class."
category: Data access
language: en
tag:
- Data access
- Persistence
- Encapsulation
---

## Also known as

* Table Gateway

## Intent

The Table Data Gateway pattern provides one object that acts as the gateway to all rows in a database table. It encapsulates SQL operations so callers can work with domain objects instead of issuing SQL directly.

## Detailed Explanation

CustomerTableGateway encapsulates create, read, update, and delete operations for the CUSTOMERS table. It accepts a DataSource, uses prepared statements, and maps query results to immutable Customer values.

Unlike a Row Data Gateway, a Table Data Gateway instance handles operations across the table rather than representing one specific row.

## Programmatic Example

The example uses an in-memory H2 database:

```java
var gateway = new CustomerTableGateway(dataSource);
gateway.insert(new Customer(1, "Alice", "Smith"));

var customer = gateway.findById(1).orElseThrow();
gateway.update(new Customer(customer.id(), customer.firstName(), "Jones"));
gateway.delete(customer.id());
```

## Known Uses

* Fowler's Patterns of Enterprise Application Architecture, Table Data Gateway: https://martinfowler.com/eaaCatalog/tableDataGateway.html

## Consequences

* SQL for a table is centralized in one class.
* Domain objects remain independent of database access code.
* The gateway can grow large when a table has many operations or complex query behavior.

## Related Patterns

* Row Data Gateway represents one row per gateway instance.
* Table Module combines table-wide data and domain logic in one class.
* Data Access Object provides an abstraction over a data access mechanism.
27 changes: 27 additions & 0 deletions table-data-gateway/etc/table-data-gateway.urm.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@startuml
package com.iluwatar.tabledatagateway {
class App {
- DB_URL : String {static}
- LOGGER : Logger {static}
+ main(args : String[]) {static}
}
class Customer <<record>> {
+ id : int
+ firstName : String
+ lastName : String
}
class CustomerTableGateway {
+ CREATE_SCHEMA_SQL : String {static}
+ DELETE_SCHEMA_SQL : String {static}
- dataSource : DataSource
+ CustomerTableGateway(dataSource : DataSource)
+ insert(customer : Customer) : int
+ findById(id : int) : Optional<Customer>
+ findAll() : List<Customer>
+ update(customer : Customer) : int
+ delete(id : int) : int
}
}
App --> CustomerTableGateway
CustomerTableGateway --> Customer
@enduml
84 changes: 84 additions & 0 deletions table-data-gateway/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

This project is licensed under the MIT license. Module table-data-gateway uses H2 database licensed under EPL (see epl-1.0.txt).

The MIT License
Copyright © 2014-2022 Ilkka Seppälä

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>java-design-patterns</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.26.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>table-data-gateway</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<configuration>
<archive>
<manifest>
<mainClass>com.iluwatar.tabledatagateway.App</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* This project is licensed under the MIT license. Module table-data-gateway uses H2 database licensed under EPL (see epl-1.0.txt).
*
* The MIT License
* Copyright © 2014-2022 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.tabledatagateway;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.h2.jdbcx.JdbcDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Table Data Gateway pattern demonstration. */
public class App {

private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

private static final String DB_URL = "jdbc:h2:mem:tabledatagateway;DB_CLOSE_DELAY=-1";

/**
* Program entry point.
*
* @param args command line args
* @throws SQLException if a database operation fails
*/
public static void main(final String[] args) throws SQLException {
var dataSource = createDataSource();
execute(dataSource, CustomerTableGateway.CREATE_SCHEMA_SQL);

var gateway = new CustomerTableGateway(dataSource);
gateway.insert(new Customer(1, "Alice", "Smith"));

var found = gateway.findById(1);
LOGGER.info("Found customer: {}", found.orElse(null));

gateway.update(new Customer(1, "Alice", "Jones"));
LOGGER.info("Customers: {}", gateway.findAll());

gateway.delete(1);
LOGGER.info("Customers after delete: {}", gateway.findAll());

execute(dataSource, CustomerTableGateway.DELETE_SCHEMA_SQL);
}

private static DataSource createDataSource() {
var dataSource = new JdbcDataSource();
dataSource.setURL(DB_URL);
return dataSource;
}

private static void execute(final DataSource dataSource, final String sql) throws SQLException {
try (var connection = dataSource.getConnection();
var statement = connection.createStatement()) {
statement.execute(sql);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* This project is licensed under the MIT license. Module table-data-gateway uses H2 database licensed under EPL (see epl-1.0.txt).
*
* The MIT License
* Copyright © 2014-2022 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.tabledatagateway;

/** Immutable representation of a row in the CUSTOMERS table. */
public record Customer(int id, String firstName, String lastName) {}
Loading
Loading