Table definition helper
https://gyazo.com/24ff19bd6684cdb91dbfdd13cf37022a #Table_specified_ORM_interface #Core
Overview
The SORM4J Table Definition Helper provides a system for defining, creating, and managing database table schemas programmatically with Java code. This framework is part of the SORM4J Object-Relational Mapping (ORM) library and is marked as @Experimental, indicating it may change in future versions.
The framework allows developers to:
1. Define table structures with columns, data types, and constraints
2. Create tables in databases based on these definitions
3. Add indexes to optimize query performance
4. Apply various constraints (primary key, unique, check, etc.)
5. Map Java classes to database tables through annotations
Core Components
Table Definition Classes
TableDefinition
The central class that represents a table schema. It provides:
A fluent builder API for creating table definitions
Methods to generate SQL statements (CREATE TABLE, DROP TABLE)
Utilities to execute these statements against a database
Support for defining indexes and constraints
code: (java)
// Example of creating a table definition
TableDefinition personTable = TableDefinition.builder("PERSONS")
.addColumnDefinition("ID", "integer", "primary key", "auto_increment")
.addColumnDefinition("NAME", "varchar", "not null")
.addColumnDefinition("AGE", "integer")
.addIndexDefinition("NAME")
.addUniqueConstraint("NAME", "AGE")
.build();
// Create the table in the database
personTable.createTableIfNotExists(orm);
TableWithDefinition<T>
Extends the standard SORM4J Table<T> class and implements the TableWithDefinition<T> interface. This class:
Binds a Java class to a table definition
Provides ORM operations while maintaining schema information
Allows for table creation and management operations
code: (java)
// Create a table with definition for the Person class
TableWithDefinition<Person> personTable =
TableWithDefinition.of(orm, Person.class);
// Create the table in the database
personTable.createTableIfNotExists();
TableWithDefinition<T> and WithTableDefinition
Interfaces that define the contract for classes that work with table definitions:
TableWithDefinition<T> extends both Table<T> and WithTableDefinition
WithTableDefinition provides methods for table operations:
createTableIfNotExists()
createIndexesIfNotExists()
dropTableIfExists()
dropTableIfExistsCascade()
Annotation Framework
The framework includes a rich set of annotations to define table schemas directly on Java classes:
Class-Level Annotations
@PrimaryKeyColumns: Defines multi-column primary keys
@IndexColumns: Creates multi-column indexes (repeatable)
@UniqueColumns: Defines multi-column unique constraints (repeatable)
@CheckConstraint: Specifies check constraints for the table (repeatable)
Field-Level and Parameter Annotations
@PrimaryKey: Marks a field as part of the primary key
@AutoIncrement: Indicates a column should auto-increment
@NotNull: Specifies a column cannot contain NULL values
@Index: Creates an index on the column
@Unique: Makes the column values unique
@Check: Adds a check constraint to the column
@Default: Sets a default value for the column
Data Type Mapping
The TableDefinition class provides automatic mapping between Java types and SQL data types:
table:table
Java Type SQL Data Type
int, Integer integer
double, Double double
boolean, Boolean boolean
String varchar
LocalDateTime timestamp
LocalDate date
LocalTime time
java.util.List, java.util.Map json
... ...
Usage Examples
Creating a Table Definition from a Java Class
code: (java)
// Define a Java class with annotations
@IndexColumns({"NAME", "AGE"})
@UniqueColumns({"EMAIL"})
public class Person {
@PrimaryKey
@AutoIncrement
private int id;
@NotNull
private String name;
private int age;
@Unique
private String email;
// Constructor, getters, setters
}
// Create a table definition
TableDefinition definition = TableDefinition.builder(Person.class).build();
// Create the table
definition.createTableIfNotExists(orm);
Creating a Table Definition Programmatically
code: (java)
TableDefinition definition = TableDefinition.builder("USERS")
.addColumnDefinition("USER_ID", "integer", "primary key")
.addColumnDefinition("USERNAME", "varchar", "not null")
.addColumnDefinition("EMAIL", "varchar", "not null")
.addColumnDefinition("CREATED_AT", "timestamp", "default CURRENT_TIMESTAMP")
.addUniqueConstraint("USERNAME")
.addUniqueConstraint("EMAIL")
.addIndexDefinition("USERNAME", "EMAIL")
.build();
// Create the table
definition.createTableIfNotExists(orm);
Working with Table Instances
code: (java)
// Create a table instance with definition
TableWithDefinition<User> userTable =
TableWithDefinition.of(orm, User.class);
// Create the table and indexes
userTable.createTableIfNotExists()
.createIndexesIfNotExists();
// Use standard ORM operations
User user = new User("john", "john@example.com");
userTable.insert(user);
List<User> users = userTable.selectAll();
Important Notes
1. This framework is marked as @Experimental, meaning its API may change in future versions.
2. The table definition in the code does not guarantee it matches the actual database schema.
3. The framework automatically handles Java to SQL type conversions but may not cover all edge cases.
4. Field-level annotations work with both fields and constructor parameters in records.
5. The generated SQL is intended to be database-agnostic but may require adaptation for specific database systems.
Architectural Design
The framework follows these design principles:
1. Separation of concerns: Table definitions are separate from the ORM operations
2. Fluent API: Builder pattern for creating and modifying table definitions
3. Annotation-driven: Support for defining schemas through Java annotations
4. Type safety: Generic types ensure type safety in ORM operations
5. Extensibility: Easy to extend with custom data types and constraints