A small, annotation-driven data access library built on Spring JDBC. It provides:
- Model mapping via annotations (
@Table,@Column,@PrimaryKey,@BelongsTo) on POJOs. - A lightweight
Repository<T>base with common query and persistence helpers. - A simple SQL builder through
QueryandModelMapperto generate SELECTs with joins and limits.
This is intended for pragmatic, minimal data access without a heavy ORM.
- Java 8+
- Maven 3+
- Spring JDBC 4.2.x (pulled via
pom.xml)
pom.xml— Maven build and dependenciessrc/main/java/io/retrorock/theory/— library sourceannotations/—@Table,@Column,@PrimaryKey,@BelongsTobase/—Model,Repository,Operationcomponents/— SQL building blocks (e.g.,From,Join)helpers/— mappers and utilities (e.g.,ModelMapper,RowMapperHelper)interfaces/—IRepository,IOperationoperations/—Query,Insert,Update,Delete
Build and install to your local Maven repository:
mvn clean installThen, in a separate project, add the dependency (adjust version if needed):
<dependency>
<groupId>io.github.wilburhimself</groupId>
<artifactId>theory</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>Annotate your entity with table/column mapping. Extend Model to get helpers like serialize() and JDBC RowMapper behavior.
import io.github.wilburhimself.theory.annotations.*;
import io.github.wilburhimself.theory.base.Model;
@Table(name = "users", alias = "u")
public class User extends Model {
@PrimaryKey
@Column(name = "id", alias = "u_id")
private Integer id;
@Column(name = "email", alias = "u_email")
private String email;
@Column(name = "name", alias = "u_name")
private String name;
// getters/setters ...
}Relationships can be declared with @BelongsTo on a field referencing another Model.
Extend Repository<T> and wire a JdbcTemplate (via Spring or manually through JdbcDaoSupport).
import io.github.wilburhimself.theory.base.Repository;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
public class UserRepository extends Repository<User> {
public UserRepository() {
this.setEntity(User.class);
this.setMapper((RowMapper<User>) new BeanPropertyRowMapper<>(User.class));
this.setTableName("users");
this.setPrimaryKeyName("id");
}
}Inject a DataSource so JdbcDaoSupport can provide JdbcTemplate:
import javax.sql.DataSource;
public class UserRepository extends Repository<User> {
public UserRepository(DataSource dataSource) {
this(); // calls default ctor to set entity/mapper
setDataSource(dataSource);
}
}Use the built-in Query builder. Repository#list() and Repository#find(id) leverage Query and your mapper.
UserRepository repo = new UserRepository(dataSource);
// Find by primary key
User u = repo.find(1);
// List all
List<User> users = repo.list();
// Custom select with Query
var q = new io.github.wilburhimself.theory.operations.Query();
q.db.from(User.class)
.fields(User.class)
.where("u.email = '%s'", "[email protected]")
.limit(10);
List<User> result = repo.select(q, repo.mapper);Note: Query#selectString() prints the generated SQL and resets internal state after building.
Repository exposes persist helpers that accept an Operation:
User user = new User();
user.setEmail("[email protected]");
user.setName("Bob");
// Insert and return generated key
Integer id = repo.persist(user, new io.github.wilburhimself.theory.operations.Insert());
user.identify(id);
// Update example
var update = new io.github.wilburhimself.theory.operations.Update();
repo.persist(user, update);
// Raw SQL
repo.persist("DELETE FROM users WHERE id = 123");This repo includes a minimal example using H2 in-memory DB under src/test/java/io/github/wilburhimself/theory/example/:
Usermodel:src/test/java/io/github/wilburhimself/theory/example/User.javaUserRepository:src/test/java/io/github/wilburhimself/theory/example/UserRepository.java- Test:
src/test/java/io/github/wilburhimself/theory/example/UserRepositoryTest.java
Run just the example test:
mvn -Dtest=io.github.wilburhimself.theory.example.UserRepositoryTest testIn XML or Java config, provide a DataSource and wire your repository. Example (Java config):
import org.springframework.context.annotation.*;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://localhost:5432/app");
ds.setUsername("app");
ds.setPassword("secret");
return ds;
}
@Bean
public UserRepository userRepository(DataSource ds) {
return new UserRepository(ds);
}
}- Build:
mvn clean package - Tests:
mvn test
- Write a failing test under
src/test/java/that describes desired behavior. - Run tests:
mvn testand watch it fail. - Implement the minimal code in
src/main/java/to make it pass. - Refactor ruthlessly while keeping tests green.
- Repeat.
- This library targets Spring 4.2.x APIs as specified in
pom.xml. - Some operations rely on column aliases matching the
@Column(alias=...)convention during mapping.
MIT — see LICENSE for details.