Skip to content

zouari-oss/skinned-rat-orm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Contributors Forks Stargazers Issues GPL3.0 License Linkedin

skinned-rat-orm-logo

Skinned Rat ORM

A lightweight, annotation-based ORM framework for Java with zero dependencies (excluding JDBC drivers).

OverviewKey FeaturesQuick StartSupported AnnotationsAdvanced FeaturesSupported DatabasesExamplesPerformanceRoadmapContributingLicenseContactAcknowledgments

Overview

Skinned Rat ORM is a lightweight, annotation-based ORM framework for Java with zero external dependencies (excluding JDBC drivers).

I developed this package because my instructor explicitly told me not to use Hibernate or any external ORM libraries and instead work directly with JDBC even if it meant implementing the ORM manually :). This project demonstrates how to build a simple, type-safe, and flexible ORM from scratch while still supporting essential features like CRUD operations, entity relationships, and schema generation.

Note

Some parts of this project developed with the assistance of AI tools: GitHub Copilot CLI + Claude sonnet 4.5 While AI helped accelerate development, a big part of the core ORM logic, design decisions, and implementation were authored and reviewed manually (+youtube & stackoverflow & .. :)) to ensure correctness and learning outcomes.

Key Features

  • Simple & Lightweight - No complex configuration, just annotations
  • Fast - Direct JDBC with minimal overhead
  • Flexible - Works with any JDBC-compatible database
  • Zero Dependencies - Only requires a JDBC driver
  • Type-Safe - Full compile-time type checking
  • Production-Ready - Tested with MariaDB, MySQL, PostgreSQL

Quick Start

Installation

Option 1: JitPack (Easiest)

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.zouari-oss:skinned-rat-orm:v1.0.0'

    // Add your JDBC driver
    implementation 'org.mariadb.jdbc:mariadb-java-client:3.3.2'
}

Option 2: Maven Local (for testing)

git clone https://github.com/zouari-oss/skinned-rat-orm.git
cd skinned-rat-orm/project
./gradlew publishToMavenLocal
repositories {
    mavenLocal()
}

dependencies {
    implementation 'org.zouarioss:skinned-rat-orm:1.0.0'
}

Basic Usage

1. Define Your Entity

import org.zouarioss.skinnedratorm.annotations.*;

@Entity
@Table(name = "users")
public class User extends TimestampedEntity {

    @Column(nullable = false, unique = true, length = 150)
    private String email;

    @Column(nullable = false)
    private String passwordHash;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserRole role;

    @PrePersist
    protected void onCreate() {
        if (this.role == null) {
            this.role = UserRole.USER;
        }
    }

    // Getters and setters...
}

2. Use the EntityManager

import org.zouarioss.skinnedratorm.core.EntityManager;
import org.zouarioss.skinnedratorm.engine.*;
import java.sql.*;

// Setup
Connection connection = DriverManager.getConnection(
    "jdbc:mariadb://localhost:3306/mydb",
    "user",
    "password"
);
EntityManager em = new EntityManager(connection);

// Create table (first time only)
SchemaGenerator generator = new SchemaGenerator(connection, SQLDialect.MYSQL);
generator.createTable(User.class);

// CREATE
User user = new User();
user.setEmail("john@example.com");
user.setPasswordHash("hashed_password");
user.setRole(UserRole.ADMIN);
em.persist(user);

// READ
User found = em.findById(User.class, user.getId());

// UPDATE
found.setRole(UserRole.MODERATOR);
em.update(found);

// DELETE
em.delete(found);

// QUERY
List<User> admins = em.createQuery(User.class)
    .where("role", "ADMIN")
    .orderBy("email")
    .limit(10)
    .getResultList();

Supported Annotations

Entity Mapping

  • @Entity - Mark class as an entity
  • @Table(name = "...") - Specify table name
  • @MappedSuperclass - Inherit fields without creating table

Field Mapping

  • @Id - Primary key field
  • @Column(name, nullable, unique, length, updatable) - Column configuration
  • @GeneratedValue(strategy = UUID) - Auto-generate IDs
  • @Enumerated(STRING|ORDINAL) - Enum mapping strategy

Timestamps

  • @CreationTimestamp - Auto-set on creation
  • @UpdateTimestamp - Auto-update on modification

Relationships

  • @OneToOne - One-to-one relationship
  • @ManyToOne - Many-to-one relationship
  • @JoinColumn - Foreign key configuration

Lifecycle

  • @PrePersist - Called before entity is persisted

Indexes & Constraints

  • @Index(name, columnList) - Create indexes
  • @UniqueConstraint(name, columnNames) - Unique constraints

Advanced Features

QueryBuilder API

List<User> users = em.createQuery(User.class)
    .where("role", "=", UserRole.ADMIN)
    .where("email", "LIKE", "%@example.com")
    .orderBy("createdAt", "DESC")
    .limit(20)
    .offset(10)
    .getResultList();

long count = em.createQuery(User.class)
    .where("role", "ADMIN")
    .count();

Schema Generation

SchemaGenerator generator = new SchemaGenerator(connection, SQLDialect.MYSQL);

// Create tables
generator.createTable(User.class);
generator.createTable(Profile.class);

// Drop tables
generator.dropTable(User.class);

Entity Inheritance

@MappedSuperclass
public abstract class IdentifiableEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    protected UUID id;
}

@MappedSuperclass
public abstract class TimestampedEntity extends IdentifiableEntity {
    @CreationTimestamp
    @Column(nullable = false, updatable = false)
    protected Instant createdAt;

    @UpdateTimestamp
    @Column(nullable = false)
    protected Instant updatedAt;
}

@Entity
@Table(name = "users")
public class User extends TimestampedEntity {
    // Automatically inherits id, createdAt, updatedAt
}

Supported Databases

  • MariaDB / MySQL
  • PostgreSQL
  • H2
  • SQLite
  • Any JDBC-compatible database

Examples

See the /lib/src/test/java/org/zouarioss/skinnedratorm/ directory for complete examples:

  • User Entity - Basic CRUD operations
  • Profile Entity - One-to-one relationships
  • AuditLog Entity - Timestamps and pre-persist callbacks
  • Integration Tests - Full CRUD test suite with MariaDB

Performance

Skinned Rat ORM is designed for simplicity and performance:

  • Direct JDBC - No reflection overhead at runtime
  • Prepared Statements - SQL injection protection
  • Lazy Initialization - Metadata cached after first use
  • No Proxy Objects - Work with real POJOs

Roadmap

  • Lazy loading for relationships
  • Batch operations
  • Criteria API
  • Connection pooling integration
  • Query caching
  • Multi-database support in one application

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This repository is licensed under the GPL-3.0 License. You are free to use, modify, and distribute the content. See the LICENSE file for details.

Contact

For questions or suggestions, feel free to reach out:

Acknowledgments

Built with ❤️ for the Java community.


After my haircut, I feel like a skinned rat... ⭐ Star this repo if you find it useful! and save me from this look!

About

A lightweight ORM framework for Java with annotation-based entity mapping

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Languages