### Implement and register UUID ParamSetter Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Query-parameter-types Example implementation of a ParamSetter for UUID objects, converting them to strings for database storage. ```java ParamSetter uuidParamSetter = (param, preparedStatement, i) -> { preparedStatement.setString(i, param.toString()); } Map paramSetters = new HashMap<>(); paramSetters.put(UUID.class, uuidParamSetter); ... // add any other setters FluentJdbc fluentJdbc = new FluentJdbcBuilder() .paramSetters(paramSetters) ... // other configuration .build(); ``` -------------------------------- ### Example: Supporting UUID Custom Type Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Auto-POJO-mapping Demonstrates how to create and register an ObjectMapperRsExtractor for the UUID type, enabling its use in POJO fields. ```java ObjectMapperRsExtractor uuidExtractor = (resultSet, i) -> UUID.fromString(resultSet.getString(i)); Map extractors = new HashMap<>(); extractors.put(UUID.class, uuidExtractor); ... // more extractors ObjectMappers.builder() .converters(extractors) .build(); ``` -------------------------------- ### Get Single or First Result from Select Query Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Use singleResult when exactly one result is expected, as it throws an exception if no rows are found. Use firstResult for cases where zero or one result is acceptable, returning an Optional. ```java import org.codejargon.fluentjdbc.api.mapper.Mappers; import java.util.Optional; // Single result - throws FluentJdbcException if no result Long customerCount = query .select("SELECT COUNT(*) FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .singleResult(Mappers.singleLong()); // First result - returns Optional Optional customer = query .select("SELECT * FROM CUSTOMER WHERE ID = ?") .params(123L) .firstResult(customerMapper); customer.ifPresent(c -> System.out.println("Found: " + c.getName())); // Using built-in mappers for single column results String name = query .select("SELECT NAME FROM CUSTOMER WHERE ID = ?") .params(123L) .singleResult(Mappers.singleString()); ``` -------------------------------- ### Configure Query Parameters Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Demonstrates usage of built-in java.time types, Optional parameters, collection parameters, and custom ParamSetters. ```java import org.codejargon.fluentjdbc.api.ParamSetter; import java.time.*; import java.util.Optional; import java.util.Set; // java.time support (built-in) query .update("UPDATE CUSTOMER SET DEADLINE = ?, UPDATED = ?, BIRTH_DATE = ?") .params( LocalDate.of(2024, Month.MARCH, 15), Instant.now(), LocalDateTime.of(1990, 5, 20, 10, 30) ) .run(); // Optional parameter support - null if empty Optional deadline = Optional.of(LocalDate.now().plusDays(30)); query .update("UPDATE CUSTOMER SET DEADLINE = ?") .params(deadline) .run(); // Collection parameter support (named parameters only) Set customerIds = Set.of(1L, 2L, 3L, 4L, 5L); List customers = query .select("SELECT * FROM CUSTOMER WHERE ID IN (:ids)") .namedParam("ids", customerIds) .listResult(customerMapper); // Custom type support (e.g., UUID) ParamSetter uuidSetter = (param, preparedStatement, i) -> preparedStatement.setString(i, param.toString()); Map customSetters = new HashMap<>(); customSetters.put(UUID.class, uuidSetter); FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(dataSource) .paramSetters(customSetters) .build(); // Now UUID can be used as parameter query.update("UPDATE CUSTOMER SET CUSTOMER_KEY = ?") .params(UUID.randomUUID()) .run(); ``` -------------------------------- ### Initialize FluentJdbc Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Configure the FluentJdbc instance using a DataSource. ```java DataSource dataSource = ... FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(dataSource) .build(); Query query = fluentJdbc.query(); // ... use the Query interface for queries (thread-safe, reentrant) ``` -------------------------------- ### Instantiate Query interface Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Query-API Create a Query instance using the default ConnectionProvider or a specific Connection instance for session-based operations. ```java Query query = fluentJdbc.query(); ``` ```java Connection connection = ... Query query = fluentJdbc.queryOn(connection); ``` -------------------------------- ### Parameterize Select Queries Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Select Demonstrates using positional and named parameters in select queries. ```java query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") ... ``` ```java Map params = ... query .select("SELECT * FROM CUSTOMER WHERE NAME = :name") .namedParams(params) ... ``` -------------------------------- ### FluentJdbc Builder Configuration Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Configuration Demonstrates the basic structure of configuring FluentJdbc using the FluentJdbcBuilder. ```APIDOC ## FluentJdbc Builder Configuration ### Description This section outlines how to configure FluentJdbc using its builder pattern, allowing for customization of its behavior. ### Method Builder Pattern ### Endpoint N/A (Configuration) ### Parameters #### Query Parameters N/A #### Request Body N/A ### Request Example ```java FluentJdbc fluentJdbc = new FluentJdbcBuilder() // configuration options here .build(); ``` ### Response N/A ``` -------------------------------- ### Configure Standalone FluentJdbc Module Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Guice-Persist Initialize the StandaloneFluentJdbcModule with a DataSource and FluentJdbcBuilder. ```java DataSource dataSource = ... FluentJdbcBuilder builder = new FluentJdbcBuilder()... StandaloneFluentJdbcModule fluentJdbcModule = new StandaloneFluentJdbcModule(builder, dataSource); install(fluentJdbcModule); ``` -------------------------------- ### Initialize Select Query Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Select Basic initialization of a select query. ```java query.select(sqlQuery)... ``` -------------------------------- ### Execute update with java.time parameters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Query-parameter-types Demonstrates passing LocalDate and Instant objects directly into a query update. ```java query .update("UPDATE CUSTOMER SET DEADLINE = ?, UPDATED = ?") .params(LocalDate.of(2015, Month.MARCH, 5), Instant.now()) .run(); ``` -------------------------------- ### Fetching Generated Keys Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Insert---Update Demonstrates how to retrieve database-generated keys after an insert or update operation. ```APIDOC ## POST /api/query/update/fetch-keys ### Description Executes an insert or update query and fetches any database-generated keys. ### Method POST ### Endpoint /api/query/update/fetch-keys ### Parameters #### Query Parameters - **sqlQuery** (string) - Required - The SQL query to execute. #### Request Body - **params** (array) - Optional - Positional parameters for the query. - **namedParams** (object) - Optional - Named parameters for the query. ### Request Example ```java Map namedParams = new HashMap<>(); namedParams.put("name", "John Doe"); UpdateResultGenKeys result = query .update("INSERT INTO CUSTOMER(NAME) VALUES(:name)") namedParams(namedParams) runFetchGenKeys(Mappers.singleLong()); Long id = result.generatedKeys().get(0); ``` ### Response #### Success Response (200) - **generatedKeys** (array) - A list of generated keys. #### Response Example ```java // Assuming the generated key is of type Long List generatedKeys = result.generatedKeys(); ``` ``` -------------------------------- ### Create DataSourceConnectionProvider Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/DataSource Instantiate DataSourceConnectionProvider by passing an existing DataSource. This allows Fluent JDBC to obtain connections from your configured DataSource. ```java DataSource dataSource = ... ConnectionProvider cp = new DataSourceConnectionProvider(dataSource); ``` -------------------------------- ### Executing Batch Insert and Update Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Shows how to perform batch operations using positional or named parameters with support for Iterators, Iterables, or Streams. ```java import java.util.Arrays; import java.util.List; import java.util.stream.Stream; // Batch insert with positional parameters List> batchParams = Arrays.asList( Arrays.asList("John Doe", "Dallas"), Arrays.asList("Jane Smith", "Austin"), Arrays.asList("Bob Wilson", "Houston") ); List results = query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)") .params(batchParams) .run(); // Batch with Stream (memory-efficient for large data) Stream> streamParams = customers.stream() .map(c -> Arrays.asList(c.getName(), c.getAddress())); query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)") .params(streamParams) .batchSize(1000) // Execute in batches of 1000 .run(); // Batch with named parameters Stream> namedParamsStream = customers.stream() .map(c -> { Map params = new HashMap<>(); params.put("name", c.getName()); params.put("address", c.getAddress()); return params; }); query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)") .namedParams(namedParamsStream) .batchSize(500) .run(); ``` -------------------------------- ### Initialize Database Inspection Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Inspection Obtain a DatabaseInspection interface instance from a query object. ```java DatabaseInspection databaseInspection = query.databaseInspection(); ``` -------------------------------- ### Configure AfterQueryListener for Logging Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Query-listener Implement an AfterQueryListener to log successful SQL queries and their execution times. This listener is called after each query execution. ```java AfterQueryListener listener = execution -> { if(execution.success()) { log.debug( String.format( "Query took %s ms to execute: %s", execution.executionTimeMs(), execution.sql() ) ) } }; FluentJdbc fluentJdbc = new FluentJdbcBuilder() // other configuration .afterQueryListener(listener) .build(); // run queries ``` -------------------------------- ### Execute select queries Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Retrieve data using various result mapping strategies including lists, single results, and iterators. ```java List customer = query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .listResult(resultSet -> new Customer(resultSet.getString("NAME"))); ``` ```java Optional firstCustomer = query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .firstResult(customerMapper); ``` ```java Map namedParams = ... Long count = query .select("SELECT COUNT(*) FROM CUSTOMER WHERE NAME = :name") .namedParams(namedParams) .singleResult(Mappers.singleLong()); ``` ```java query .select("SELECT * FROM CUSTOMER") .iterateResult(rs -> { // do something with the customer }); ``` -------------------------------- ### Selecting Results into POJOs Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Auto-POJO-mapping Execute a query and map the results directly into a list of Customer objects using the pre-configured mapper. ```java List customers = query.select("SELECT * FROM CUSTOMER").listResult(customerMapper); ``` -------------------------------- ### Query with Specific Connection Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Execute queries using a manually provided connection object. ```java Connection connection = ... Query query = fluentJdbc.queryOn(connection); // do some querying... ``` -------------------------------- ### Insert and Update Queries Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Insert---Update This section covers how to create and execute parameterized insert or update queries using the `update` method in Fluent JDBC. ```APIDOC ## POST /api/query/update ### Description Creates an insert or update query that can be parameterized and executed. ### Method POST ### Endpoint /api/query/update ### Parameters #### Query Parameters - **sqlQuery** (string) - Required - The SQL query to execute. #### Request Body - **params** (array) - Optional - Positional parameters for the query. - **namedParams** (object) - Optional - Named parameters for the query. ### Request Example (Positional Parameters) ```java query.update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); ``` ### Request Example (Named Parameters) ```java Map namedParams = new HashMap<>(); namedParams.put("name", "John Doe"); namedParams.put("address", "Dallas"); query.update("UPDATE CUSTOMER SET NAME = :name, ADDRESS = :address") namedParams(namedParams) .run(); ``` ### Response #### Success Response (200) - **affectedRows** (long) - The number of rows affected by the update query. #### Response Example ```java UpdateResult result = query.update(...).run(); Long affectedRows = result.affectedRows(); ``` ``` -------------------------------- ### Initialize a batch query Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Batch Creates a batch insert or update query object for further customization and execution. ```java query.batch(sqlQuery)... ``` -------------------------------- ### connectionProvider(cp) Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Configuration Configures the ConnectionProvider for FluentJdbc to manage database connections. ```APIDOC ## connectionProvider(cp) ### Description Sets a `ConnectionProvider` for FluentJdbc. This provider is responsible for supplying `Connection` objects to the Query API. Refer to the [ConnectionProvider](https://github.com/zsoltherpai/fluent-jdbc/wiki/ConnectionProvider) wiki page for detailed information and available implementations. ### Method Builder Method ### Endpoint N/A (Configuration) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```java FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(myConnectionProvider) .build(); ``` ### Response N/A ``` -------------------------------- ### Setting Up FluentJdbc Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Configure FluentJdbc using a builder pattern with a DataSource. The resulting instance is thread-safe. A Query instance can be created for general use or on a specific Connection. ```java import org.codejargon.fluentjdbc.api.FluentJdbc; import org.codejargon.fluentjdbc.api.FluentJdbcBuilder; import org.codejargon.fluentjdbc.api.query.Query; import javax.sql.DataSource; // Set up FluentJdbc with a DataSource DataSource dataSource = ... // Your DataSource (HikariCP, etc.) FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(dataSource) .build(); // Create a Query instance (thread-safe, reusable) Query query = fluentJdbc.query(); // Alternatively, create a Query for a specific Connection Connection connection = dataSource.getConnection(); Query queryOnConnection = fluentJdbc.queryOn(connection); ``` -------------------------------- ### Use Named Parameters Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Bind parameters by name instead of position. ```java query.update("UPDATE CUSTOMER SET NAME = :name, ADDRESS = :address") .namedParam("name", "John Doe") .namedParam("address", "Dallas") .run(); ``` -------------------------------- ### Implement Result Mappers Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Select Shows manual mapper implementation and automatic POJO mapping. ```java Mapper manualCustomerMapper = resultSet -> { return new Customer(resultSet.getString("NAME")); } ``` ```java ObjectMappers objectMappers = ObjectMappers.builder().build(); ... Mapper generatedCustomerMapper = objectMappers.forClass(Customer.class); ``` -------------------------------- ### Using Built-in Result Mappers Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Demonstrates mapping single-column results to Java types and retrieving rows as Map objects. ```java import org.codejargon.fluentjdbc.api.mapper.Mappers; import java.math.BigDecimal; import java.util.Map; // Single column mappers Long count = query .select("SELECT COUNT(*) FROM CUSTOMER") .singleResult(Mappers.singleLong()); Integer age = query .select("SELECT AGE FROM CUSTOMER WHERE ID = ?") .params(1L) .singleResult(Mappers.singleInteger()); String name = query .select("SELECT NAME FROM CUSTOMER WHERE ID = ?") .params(1L) .singleResult(Mappers.singleString()); BigDecimal balance = query .select("SELECT BALANCE FROM ACCOUNT WHERE ID = ?") .params(1L) .singleResult(Mappers.singleBigDecimal()); Boolean active = query .select("SELECT ACTIVE FROM CUSTOMER WHERE ID = ?") .params(1L) .singleResult(Mappers.singleBoolean()); byte[] data = query .select("SELECT PHOTO FROM CUSTOMER WHERE ID = ?") .params(1L) .singleResult(Mappers.singleByteArray()); // Map result - returns Map with column names as keys Map row = query .select("SELECT * FROM CUSTOMER WHERE ID = ?") .params(1L) .singleResult(Mappers.map()); ``` -------------------------------- ### Select Queries - List Results Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Execute select queries and retrieve all matching rows as a List using a provided Mapper. Supports both positional and named parameters. ```java import org.codejargon.fluentjdbc.api.query.Mapper; import java.util.List; // Define a manual mapper Mapper customerMapper = resultSet -> new Customer( resultSet.getLong("ID"), resultSet.getString("NAME"), resultSet.getString("ADDRESS") ); // Select with positional parameters List customers = query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .listResult(customerMapper); // Select with named parameters Map params = new HashMap<>(); params.put("name", "John%"); List matchingCustomers = query .select("SELECT * FROM CUSTOMER WHERE NAME LIKE :name") .namedParams(params) .listResult(customerMapper); ``` -------------------------------- ### Support for java.util.Optional Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Optional values can be passed directly as parameters. ```java Optional deadline = ... query.update("UPDATE CUSTOMER SET DEADLINE = ?") .params(deadline) .run(); ``` -------------------------------- ### Configure FluentJdbc with Custom Options Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Use FluentJdbcBuilder to set up connection providers, custom parameter setters for types like UUID and Money, default fetch size, and query listeners for monitoring. ```java import org.codejargon.fluentjdbc.api.integration.providers.DataSourceConnectionProvider; import org.codejargon.fluentjdbc.api.integration.ConnectionProvider; // Full configuration example DataSource dataSource = ... // Your connection pool FluentJdbc fluentJdbc = new FluentJdbcBuilder() // Connection provider (required) .connectionProvider(dataSource) // Or use explicit DataSourceConnectionProvider // .connectionProvider(new DataSourceConnectionProvider(dataSource)) // Custom parameter setters for additional types .paramSetters(Map.of( UUID.class, (param, ps, i) -> ps.setString(i, param.toString()), Money.class, (param, ps, i) -> ps.setBigDecimal(i, param.amount()) )) // Default fetch size (overrides vendor defaults) .defaultFetchSize(100) // Query listener for logging/monitoring .afterQueryListener(execution -> { log.debug("Executed: {} in {} ms", execution.sql(), execution.executionTimeMs()); }) .build(); // Custom ConnectionProvider implementation ConnectionProvider customProvider = queryReceiver -> { Connection connection = acquireConnectionFromPool(); try { queryReceiver.receive(connection); } finally { releaseConnectionToPool(connection); } }; ``` -------------------------------- ### Initialize FluentJdbc instance Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Configure a FluentJdbc instance using a JDBC DataSource. The instance is thread-safe and typically shared across the application. ```java DataSource dataSource = ... FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(dataSource) // optionally other configuration .build(); ``` -------------------------------- ### Implement a custom ConnectionProvider Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/ConnectionProvider Defines the standard pattern for acquiring, providing, and releasing JDBC connections within FluentJdbc. ```java ConnectionProvider cp = query -> { Connection connection = ... // acquire a connection query.receive(connection) // make the connection available to FluentJdbc queries connection.close() // release connection - may not be needed if connection is already managed } ``` -------------------------------- ### Execute Insert or Update Query Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Insert---Update Use the `update` method to create an insert or update query. This method supports parameterization for safe execution. ```java query.update(sqlQuery)... ``` -------------------------------- ### POJO Definition and Mapper Instantiation Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Auto-POJO-mapping Define a POJO for result mapping and instantiate a mapper for it. The mapper should ideally be cached for performance. ```java class Customer { private Long id; private Instant created; private String name; } ... ObjectMappers objectMappers = ObjectMappers.builder().build(); ... // should be typically cached - eg as static - since it has some cost to instantiate private static Mapper customerMapper = objectMappers.forClass(Customer.class); ``` -------------------------------- ### Query First Result Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Retrieve the first result as an Optional. ```java Optional customer = query.select("SELECT FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .firstResult(customerMapper); ``` -------------------------------- ### Implement Query Listeners Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Registers callbacks for logging and performance monitoring after query execution. ```java import org.codejargon.fluentjdbc.api.query.listen.AfterQueryListener; // Create a logging listener AfterQueryListener loggingListener = execution -> { if (execution.success()) { log.debug("Query executed in {} ms: {}", execution.executionTimeMs(), execution.sql()); } else { log.error("Query failed after {} ms: {} - Error: {}", execution.executionTimeMs(), execution.sql(), execution.sqlException().map(Throwable::getMessage).orElse("unknown")); } }; // Performance monitoring listener AfterQueryListener performanceListener = execution -> { if (execution.executionTimeMs() > 1000) { log.warn("Slow query detected ({} ms): {}", execution.executionTimeMs(), execution.sql()); } metrics.recordQueryTime(execution.executionTimeMs()); }; FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(dataSource) .afterQueryListener(loggingListener) .build(); ``` -------------------------------- ### Add Maven Dependency Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Include the FluentJdbc library in your project via Maven. ```xml org.codejargon fluentjdbc 1.8.3 ``` -------------------------------- ### Configure FluentJdbc with Builder Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Configuration Use the FluentJdbcBuilder to customize settings like connection providers, parameter setters, and fetch sizes before building the FluentJdbc instance. ```java FluentJdbc fluentJdbc = new FluentJdbcBuilder() // configuration .build(); ``` -------------------------------- ### Include FluentJdbc dependency Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Add the FluentJdbc library to your project using Maven. ```xml org.codejargon fluentjdbc 1.7 ``` -------------------------------- ### Execute batch with positional parameters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Batch Uses an Iterator or Stream of parameter lists to execute a batch query with positional placeholders. ```java Stream> params = ...; // or Iterable/Iterator query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)") .params(params) .run(); ``` -------------------------------- ### Accessing DatabaseMetaData Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Inspection Provides a callback for full access to DatabaseMetaData methods. ```APIDOC ## Access to JDBC DatabaseMetaData ### Description Callback providing full access to `DatabaseMetaData`, eg: ### Method ```java Integer dbVersion = inspection.accessMetaData( DatabaseMetaData::getDatabaseMajorVersion ) ``` ``` -------------------------------- ### Implement ConnectionProvider with Spring JdbcTemplate Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Connection-callbacks Use this pattern when integrating with frameworks that manage connections, like Spring. It allows providing access to managed Connection objects via callbacks. ```java JdbcTemplate jdbcTemplate = ... ConnectionProvider provider = query -> { jdbcTemplate.execute(connection -> { query.receive(connection); }); } ``` -------------------------------- ### Execute update or insert queries Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Perform updates or inserts using either positional or named parameters. ```java UpdateResult result = query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); ``` ```java query .update("UPDATE CUSTOMER SET NAME = :name, ADDRESS = :address") .namedParam("name", "John Doe") .namedParam("address", "Dallas") .run(); ``` -------------------------------- ### Inject and Use Query in Guice Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Guice-Persist Inject the Query instance and use the @Transactional annotation to manage transactions. ```java @Inject private Query query; @Transactional public void updateSomething() { query.update(someSqlQuery)..... } ``` -------------------------------- ### Execute batch with named parameters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Batch Uses an Iterator of maps to execute a batch query with named placeholders. ```java Iterator> params = ...; query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)") .namedParams(params) .run(); ``` -------------------------------- ### Execute batch inserts or updates Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Perform batch operations using streams of parameters. ```java Stream> params = ...; query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)") .params(params) .run(); ``` ```java Stream> params = ...; query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)") .namedParams(params) .run(); ``` -------------------------------- ### Customize Select Query Execution Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Select Configures fetch size and maximum row limits for query execution. ```java query .select("SELECT * FROM CUSTOMER WHERE NAME = :name") .namedParams(params) .fetchSize(50) .maxRows(200) ... ``` -------------------------------- ### Add FluentJdbc Guice Persist Dependency Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Guice-Persist Include this Maven dependency to enable Guice Persist support. Ensure the version matches your FluentJdbc version. ```xml org.codejargon fluentjdbc-guice-persist 0.9.2 ``` -------------------------------- ### Support Java Time Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Pass java.time types directly as query parameters. ```java query.update("UPDATE CUSTOMER SET DEADLINE = ?, UPDATED = ?") .params(LocalDate.of(2015, Month.MARCH, 5), Instant.now()) .run(); ``` -------------------------------- ### Batch Insert and Update Operations Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Batch Methods for executing batch SQL queries with support for large datasets via Iterators and configurable batch sizes. ```APIDOC ## Batch Query Execution ### Description Creates and executes a batch insert or update query. Supports both positional and named parameters provided as Iterators or Streams to handle large datasets efficiently. ### Parameters - **sqlQuery** (String) - Required - The SQL statement to execute. - **params** (Iterator/Stream/Iterable) - Required - The data to be inserted or updated. - **batchSize** (Integer) - Optional - The number of records to process per batch. If not specified, all records are executed in a single batch. ### Request Example (Positional) query.batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)").params(params).run(); ### Request Example (Named) query.batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)").namedParams(params).run(); ### Request Example (With Batch Size) query.batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)").namedParams(params).batchSize(1000).run(); ``` -------------------------------- ### Create DataSourceConnectionProvider with JEE EJB Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/JEE-EJB Obtain a transaction-aware DataSource from a JEE EJB container and use it to create a FluentJdbc ConnectionProvider. ```java @Resource DataSource dataSource; ... void createConnectionProvider() { ConnectionProvider cp = new DataSourceConnectionProvider(dataSource); } ``` -------------------------------- ### Configure custom ParamSetters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Query-parameter-types Registers custom type handlers using a map of classes to ParamSetter implementations during FluentJdbc initialization. ```java Map paramSetters = ... FluentJdbc fluentJdbc = new FluentJdbcBuilder() .paramSetters(paramSetters) ... // other configuration .build(); ``` -------------------------------- ### Spring Integration with JdbcTemplate Callback Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Alternatively, use JdbcTemplate's connection callback to create a ConnectionProvider for FluentJdbc. This allows FluentJdbc to leverage Spring's JdbcTemplate for connection management. ```java import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import org.springframework.jdbc.core.JdbcTemplate; // Option 2: Using JdbcTemplate connection callback JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); ConnectionProvider springProvider = queryReceiver -> jdbcTemplate.execute((Connection conn) -> { queryReceiver.receive(conn); return null; }); FluentJdbc fluentJdbc = new FluentJdbcBuilder() .connectionProvider(springProvider) .build(); ``` -------------------------------- ### Retrieve Query Results as Collections Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Select Fetches query results into List or Set collections. ```java List customers = query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .listResult(customerMapper); ``` ```java Set customers = query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .setResult(customerMapper); ``` -------------------------------- ### Configure batch size Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Batch Sets a specific batch size per query to prevent high memory consumption with large datasets. ```java query .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)") .namedParams(params) .batchSize(1000) .run(); ``` -------------------------------- ### Wrap DataSource for Transaction Management Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Spring-Jdbc Wrap an existing DataSource with TransactionAwareDataSourceProxy to participate in Spring transactions. Then, create a ConnectionProvider using DataSourceConnectionProvider. ```java // wrap a DataSource for transaction management DataSource dataSource = ... DataSource transactionalDataSource = new TransactionAwareDataSourceProxy(dataSource); // create a FluentJdbc ConnectionProvider based on it ConnectionProvider cp = new DataSourceConnectionProvider(transactionalDataSource); ``` -------------------------------- ### Support Collections Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Pass collections as named parameters for IN clauses. ```java Set ids = ... List customers = query.select("SELECT * FROM CUSTOMER WHERE ID IN (:ids)") .namedParam("ids", ids) .listResult(customerMapper);; ``` -------------------------------- ### Update with Positional Parameters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Insert---Update Execute an UPDATE statement using positional parameters. Ensure the order of parameters matches the placeholders in the SQL query. ```java UpdateResult result = query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); ``` -------------------------------- ### Iterating ResultSets from DatabaseMetaData Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Inspection Conveniently iterate and map ResultSets returned by DatabaseMetaData methods, avoiding resource leaks. ```APIDOC ## Iterating/mapping ResultSets returned by DatabaseMetaData ### Description A number of methods of `DatabaseMetaData` return `ResultSets`. For convenience, and avoid resource leaks FluentJdbc can iterate through these `ResultSets` and map the results as POJOs. ### Method ```java List tableNames = inspection .selectFromMetaData(meta -> meta.getTables(null, null, null, null)) .listResult(rs -> rs.getString(3)); ``` ``` -------------------------------- ### Batch Insert or Update Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Execute batch operations using a stream or iterable of parameters. ```java Stream> params = ...; // or Iterator/Iterable query.batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)") .params(params) .run(); ``` -------------------------------- ### Fetch generated keys Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Retrieve auto-generated keys after an insert operation. ```java UpdateResultGenKeys result = query .update("INSERT INTO CUSTOMER(NAME) VALUES(:name)") .namedParams(namedParams) .runFetchGenKeys(Mappers.singleLong()); Long id = result.generatedKeys().get(0); ``` -------------------------------- ### Execute Update or Insert Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Perform data modification queries using positional parameters. ```java query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); ``` -------------------------------- ### Access JDBC DatabaseMetaData Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Inspection Use a callback to execute methods directly on the underlying DatabaseMetaData object. ```java Integer dbVersion = inspection.accessMetaData( DatabaseMetaData::getDatabaseMajorVersion ) ``` -------------------------------- ### Customize Fetch Size and Max Rows for Select Queries Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Control the number of rows fetched per database round-trip using fetchSize and limit the total number of rows returned with maxRows. ```java // Customize fetch size and max rows List customers = query .select("SELECT * FROM CUSTOMER WHERE CITY = :city") .namedParam("city", "Dallas") .fetchSize(100) // Fetch 100 rows per round-trip .maxRows(500L) // Return max 500 rows .listResult(customerMapper); ``` -------------------------------- ### Fetching Generated Keys Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Retrieve auto-generated keys after an insert operation using runFetchGenKeys. This method supports various key types, multiple rows, and multiple generated keys per row. ```java import org.codejargon.fluentjdbc.api.query.UpdateResultGenKeys; import org.codejargon.fluentjdbc.api.mapper.Mappers; // Insert and fetch the generated Long key UpdateResultGenKeys result = query .update("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)") .namedParam("name", "John Doe") .namedParam("address", "Dallas") .runFetchGenKeys(Mappers.singleLong()); Long generatedId = result.generatedKeys().get(0); Long affectedRows = result.affectedRows(); // For Oracle or when column names must be specified UpdateResultGenKeys oracleResult = query .update("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)") .params("John Doe", "Dallas") .runFetchGenKeys(Mappers.singleLong(), new String[]{"ID"}); ``` -------------------------------- ### paramSetters(setters) Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Configuration Adds custom parameter setters to handle specific query parameter types. ```APIDOC ## paramSetters(setters) ### Description Adds parameter setters to support query parameters of custom types, such as UUID or other value objects. `java.time` is supported by default. Setters can be defined to override existing types if necessary. Refer to Query parameter types for setter implementation details. ### Method Builder Method ### Endpoint N/A (Configuration) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```java FluentJdbc fluentJdbc = new FluentJdbcBuilder() .paramSetters(customParamSetter) .build(); ``` ### Response N/A ``` -------------------------------- ### Managing Transactions Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Covers programmatic transaction management including return values and isolation levels. ```java import org.codejargon.fluentjdbc.api.query.Transaction; // Transaction with no return value query.transaction().inNoResult(() -> { query .update("UPDATE ACCOUNT SET BALANCE = BALANCE - ? WHERE ID = ?") .params(100.00, 1L) .run(); query .update("UPDATE ACCOUNT SET BALANCE = BALANCE + ? WHERE ID = ?") .params(100.00, 2L) .run(); // Both updates commit together, or rollback on exception }); // Transaction with return value Long newId = query.transaction().in(() -> { UpdateResultGenKeys result = query .update("INSERT INTO CUSTOMER(NAME) VALUES(?)") .params("John Doe") .runFetchGenKeys(Mappers.singleLong()); Long customerId = result.generatedKeys().get(0); query .update("INSERT INTO CUSTOMER_PROFILE(CUSTOMER_ID, CREATED) VALUES(?, ?)") .params(customerId, Instant.now()) .run(); return customerId; }); // Transaction with isolation level query.transaction() .isolation(Transaction.Isolation.SERIALIZABLE) .inNoResult(() -> { // Critical operations requiring serializable isolation query.update("UPDATE INVENTORY SET QUANTITY = QUANTITY - 1 WHERE ID = ?") .params(productId) .run(); }); ``` -------------------------------- ### Manage programmatic transactions Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Get-started-guide Execute multiple queries within a transaction block. Exceptions trigger a rollback. ```java query.transaction().in( () -> { query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); someOtherBusinessOperationAlsoNeedingTransactions(); } ) ``` -------------------------------- ### Update with Named Parameters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Insert---Update Execute an UPDATE statement using named parameters. A map of parameter names to values is required. This improves readability for complex queries. ```java Map namedParams = new HashMap<>(); namedParams.put("name", "John Doe"); namedParams.put("address", "Dallas"); UpdateResult result = query .update("UPDATE CUSTOMER SET NAME = :name, ADDRESS = :address") .namedParams(namedParams) .run(); ``` -------------------------------- ### Query List of Results Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Retrieve multiple rows mapped to a list of objects. ```java List customers = query.select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .listResult(customerMapper); ``` -------------------------------- ### Map Results Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Define custom mappers or use automatic object mapping. ```java resultSet -> new Customer(resultSet.getString("NAME"), resultSet.getString("ADDRESS")); ``` ```java ObjectMappers objectMappers = ObjectMappers.builder().build(); //typically one instance per app ... Mapper customerMapper = objectMappers.forClass(Customer.class); ``` -------------------------------- ### Configure JpaFluentJdbcModule Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Guice-Persist Integrate with JpaPersistModule by providing a JpaConnectionExtractor and FluentJdbcBuilder. ```java FluentJdbcBuilder fluentJdbcBuilder = new FluentJdbcBuilder()... JpaConnectionExtractor extractor = ... JpaFluentJdbcModule fluentJdbcModule = new JpaFluentJdbcModule(fluentJdbcBuilder, extractor); install(..., jpaPersistModule, fluentJdbcModule, ...) ``` -------------------------------- ### Perform Database Inspection Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Accesses JDBC DatabaseMetaData to retrieve schema information and verify table existence. ```java import org.codejargon.fluentjdbc.api.query.inspection.DatabaseInspection; import java.sql.DatabaseMetaData; DatabaseInspection inspection = query.databaseInspection(); // Access DatabaseMetaData directly Integer majorVersion = inspection.accessMetaData( DatabaseMetaData::getDatabaseMajorVersion ); String productName = inspection.accessMetaData( DatabaseMetaData::getDatabaseProductName ); // Query tables - selectFromMetaData handles ResultSet iteration List tableNames = inspection .selectFromMetaData(meta -> meta.getTables(null, null, null, new String[]{"TABLE"})) .listResult(rs -> rs.getString("TABLE_NAME")); // Query columns for a specific table List> columns = inspection .selectFromMetaData(meta -> meta.getColumns(null, null, "CUSTOMER", null)) .listResult(Mappers.map()); // Check if table exists boolean tableExists = inspection .selectFromMetaData(meta -> meta.getTables(null, null, "CUSTOMER", null)) .firstResult(rs -> rs.getString("TABLE_NAME")) .isPresent(); ``` -------------------------------- ### Retrieve Results as a Set and Apply Filtering Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Fetch results directly into a Set to automatically handle duplicates. Java-side filtering can be applied using a Predicate before collecting results, but note that all rows are still fetched from the database. ```java import java.util.Set; // Get results as a Set (removes duplicates) Set uniqueCustomers = query .select("SELECT * FROM CUSTOMER WHERE CITY = ?") .params("Dallas") .setResult(customerMapper); // Apply Java-side filtering before collecting results // Note: All rows are still fetched from DB, use with caution List activeCustomers = query .select("SELECT * FROM CUSTOMER WHERE CITY = ?") .params("Dallas") .filter(Customer::isActive) // Predicate filter .listResult(customerMapper); ``` -------------------------------- ### Guice Persist Standalone Integration Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Configure FluentJdbc for standalone transaction management with Guice Persist using StandaloneFluentJdbcModule. This module binds a Query instance that respects Guice Persist's @Transactional annotations. ```java import org.codejargon.fluentjdbc.api.integration.guicepersist.standalone.StandaloneFluentJdbcModule; import org.codejargon.fluentjdbc.api.integration.guicepersist.jpa.JpaFluentJdbcModule; import org.codejargon.fluentjdbc.api.integration.guicepersist.jpa.JpaConnectionExtractor; import com.google.inject.persist.Transactional; // Standalone FluentJdbc with Guice Persist transactions DataSource dataSource = ... FluentJdbcBuilder builder = new FluentJdbcBuilder(); StandaloneFluentJdbcModule module = new StandaloneFluentJdbcModule(builder, dataSource); install(module); // Usage with @Transactional @Inject private Query query; @Transactional public void updateCustomer(Long id, String name) { query.update("UPDATE CUSTOMER SET NAME = ? WHERE ID = ?") .params(name, id) .run(); } ``` -------------------------------- ### Update and Insert Queries Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt The update API handles INSERT, UPDATE, DELETE, and DDL statements with positional or named parameters. It returns an UpdateResult with the number of affected rows. ```java import org.codejargon.fluentjdbc.api.query.UpdateResult; import java.util.HashMap; import java.util.Map; // Simple update with positional parameters UpdateResult result = query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); Long affectedRows = result.affectedRows(); // Number of rows affected // Insert with named parameters Map namedParams = new HashMap<>(); namedParams.put("name", "Jane Smith"); namedParams.put("address", "Austin"); query .update("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(:name, :address)") .namedParams(namedParams) .run(); // Using fluent named parameter methods query .update("UPDATE CUSTOMER SET NAME = :name, ADDRESS = :address WHERE ID = :id") .namedParam("name", "John Doe") .namedParam("address", "Dallas") .namedParam("id", 123L) .run(); ``` -------------------------------- ### Database Schema Inspection Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Inspection Obtain a DatabaseInspection interface to access JDBC DatabaseMetaData. ```APIDOC ## Database Schema Inspection ### Description Returns a `DatabaseInspection` interface that provides access to JDBC `DatabaseMetaData`. ### Method ```java DatabaseInspection databaseInspection = query.databaseInspection(); ``` ``` -------------------------------- ### Automatic POJO Mapping with ObjectMappers Source: https://context7.com/zsoltherpai/fluent-jdbc/llms.txt Leverage ObjectMappers to automatically map ResultSet columns to POJO fields based on case-insensitive name matching. Ensure POJOs have a no-arg constructor; fields can be private or final. ```java import org.codejargon.fluentjdbc.api.mapper.ObjectMappers; import org.codejargon.fluentjdbc.api.mapper.ObjectMapperRsExtractor; // Define a POJO (no-arg constructor required, can be private) class Customer { private Long id; private String name; private String address; private Instant createdAt; // Maps to CREATED_AT column // getters... } // Create ObjectMappers instance (typically one per application) ObjectMappers objectMappers = ObjectMappers.builder().build(); // Generate mapper for Customer class (cache this - reuse it) Mapper customerMapper = objectMappers.forClass(Customer.class); // Use the auto-generated mapper List customers = query .select("SELECT ID, NAME, ADDRESS, CREATED_AT FROM CUSTOMER") .listResult(customerMapper); // With custom type support (e.g., UUID) ObjectMapperRsExtractor uuidExtractor = (resultSet, i) -> UUID.fromString(resultSet.getString(i)); Map extractors = new HashMap<>(); extractors.put(UUID.class, uuidExtractor); ObjectMappers customMappers = ObjectMappers.builder() .converters(extractors) .build(); ``` -------------------------------- ### Acquire Transaction-Managed Connections from JdbcTemplate Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Spring-Jdbc Alternatively, transaction-managed connections can be acquired from JdbcTemplate's Connection callback. This provides a ConnectionProvider that uses the provided JdbcTemplate. ```java ConnectionProvider provider = query -> jdbcTemplate.execute(query::receive); ``` -------------------------------- ### Execute Transactions Source: https://github.com/zsoltherpai/fluent-jdbc/blob/master/README.md Run multiple operations within a single transaction block. ```java query.transaction().in( () -> { query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); someOtherBusinessOperationAlsoNeedingTransactions(); } ) ``` -------------------------------- ### Fetch Generated Keys from Insert/Update Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Insert---Update Retrieve database-generated keys (e.g., auto-increment IDs) after an insert or update operation. This requires JDBC driver support and a suitable mapper like `Mappers.singleLong()`. ```java UpdateResultGenKeys result = query .update("INSERT INTO CUSTOMER(NAME) VALUES(:name)") .namedParams(namedParams) .runFetchGenKeys(Mappers.singleLong()); Long id = result.generatedKeys().get(0); ``` -------------------------------- ### Configuring Custom Type Converters Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Auto-POJO-mapping Configure custom type converters within the ObjectMappers builder to support non-standard Java types in your POJOs. ```java Map extractors = ... ObjectMappers.builder() .converters(extractors) .build(); ``` -------------------------------- ### Retrieve Single or Optional Results Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Select Fetches a single mandatory result or an optional result that may be empty. ```java Long count = query .select("SELECT COUNT(*) FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .singleResult(Mappers.singleLong()); ``` ```java Optional customer = query .select("SELECT * FROM CUSTOMER WHERE NAME = ?") .params("John Doe") .firstResult(customerMapper); ``` -------------------------------- ### defaultFetchSize(Integer rows) Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Configuration Overrides the default fetch size for select queries. ```APIDOC ## defaultFetchSize(Integer rows) ### Description Overrides the vendor-specific default fetch size for select queries. Some vendors have default fetch sizes that may lead to poor performance (e.g., Oracle defaults to 10) or memory issues (e.g., MySQL defaults to infinite). ### Method Builder Method ### Endpoint N/A (Configuration) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```java FluentJdbc fluentJdbc = new FluentJdbcBuilder() .defaultFetchSize(100) .build(); ``` ### Response N/A ``` -------------------------------- ### Map Metadata ResultSets Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Inspection Iterate through ResultSets returned by DatabaseMetaData methods and map them to POJOs. ```java List tableNames = inspection .selectFromMetaData(meta -> meta.getTables(null, null, null, null)) .listResult(rs -> rs.getString(3)); ``` -------------------------------- ### Programmatic Transaction Handling with Fluent JDBC Source: https://github.com/zsoltherpai/fluent-jdbc/wiki/Transactions Execute a block of code within a transaction. All Fluent JDBC operations within the callback join this transaction if they use the same thread and ConnectionProvider. ```java query.transaction().in( () -> { query .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?") .params("John Doe", "Dallas") .run(); // ... other queries, method calls, etc.. } ) ```