Get Started
PikaORM is a lightweight ActiveRecord ORM for Java. Map a plain class to a table to get CRUD and a fluent query API, and drop to raw SQL whenever you want. There are no configuration files or annotations to write.
If this is the first time you have worked with a ORM or Database, refer to our Concepts tab to get started!
Install
Add PikaORM to your project (it targets Java 17):
<dependency>
<groupId>edu.montana.cs.pika</groupId>
<artifactId>pika-orm</artifactId>
<version>0.1.0</version>
</dependency>
Add a JDBC driver for your database too — for SQLite:
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.49.1.0</version>
</dependency>
See Changelog for the proper version compatibility
Define your schema
Schema lives in code. Extend Migrations and add one PikaMigration per change:
import edu.montana.pika.migrations.Migrations;
import edu.montana.pika.migrations.PikaMigration;
public class AppMigrations extends Migrations {
@Override
public void migrations() {
add(this::createTodos);
}
public PikaMigration createTodos() {
return makeMigration("001_create_todos")
.up("""
CREATE TABLE IF NOT EXISTS todos (
id INTEGER PRIMARY KEY,
title TEXT,
completed INTEGER
);
""")
.down("DROP TABLE todos;");
}
}
See Migrations for rollbacks and the interactive CLI.
Define a bean
A domain object is a plain class that extends PikaBean. Fields map to columns by convention — class Todo maps to table todos, field dueDate to column due_date. A static find() gives you a typed entry point for queries.
import edu.montana.pika.bean.PikaBean;
import edu.montana.pika.query.PikaClassFinder;
public class Todo extends PikaBean {
Long id;
String title;
Boolean completed = false;
public Todo() {}
public Todo(String title) { this.title = title; }
public void setCompleted(Boolean completed) { this.completed = completed; }
public static PikaClassFinder<Todo> find() {
return find(Todo.class);
}
}
Connect
Create the ORM once at startup and apply your migrations. makeDefaultORM() registers it as the default instance that backs every bean.
import edu.montana.pika.PikaORM;
PikaORM orm = new PikaORM("jdbc:sqlite:app.db")
.makeDefaultORM()
.withMigrations(new AppMigrations())
.applyMigrations();
CRUD
Beans persist themselves:
// Create
Todo todo = new Todo("Read the docs");
todo.save(); // INSERT
// Read by primary key
Todo found = Todo.find().byId(1L);
// Update — save() knows it is an existing row
found.setCompleted(true);
found.save(); // UPDATE
// Delete
found.delete();
Query
find() returns a fluent builder:
import edu.montana.pika.query.PikaList;
PikaList<Todo> open = Todo.find()
.where("completed = :done", "done", false)
.fetchList();
Where to next
- CRUD — the full create/read/update/delete surface
- Querying — filtering, ordering, joins, and aggregates
- Validation & Forms — validating beans and binding web form data
- Cheat Sheet — every operation at a glance