Skip to content
ulifplPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

JSNDB Logo

JSNDB

Java JSON Data Base

JSNDB Banner

⚠️ MIGRATION NOTICE The official repository for JSNDB has moved from SourceForge to GitHub! This is now the main repository for future development, issues, and releases.

JSNDB is a fully embedded, 100% serverless NoSQL Document Database written purely in Java. It allows you to persist, query, update, and delete Java objects (POJOs) natively to disk using a lightweight JSON structure combined with an extremely optimized binary B-Tree indexing engine.

It eliminates the need for strict schemas, ORMs, and heavy connection protocols by working directly with your memory objects.

Key Features

  • No Dependencies, No Servers: Runs inside your JVM.
  • POJO Native: Save your Java Objects directly. No mappers or DTO conversions needed.
  • Blazing Fast Binary Indices: Properties are mapped into a binary B-Tree that avoids parsing JSON during operations.
  • Circular Reference Support: Handles cyclic relationships (e.g. Owner -> Pet -> Owner) gracefully without StackOverflow crashes, using lazy loading proxies.
  • Modern & Lightweight: Compatible with Java 17 / Java 21 LTS.

🚀 Quick Start Example

1. Define your POJOs

Just use your normal Java objects. Use @jsndbObjectId to mark the ID.

public class Persona {
    @jsndbObjectId
    private Long id;
    private String name;
    private int age;
    private List<Animal> pets;
    // constructors, getters, setters...
}

2. Initialize and Persist

// Open or create the database directory
jsndb db = new jsndb("my_database_dir");

// Create your complex nested objects
Persona user = new Persona("Alice", 28, new ArrayList<>());
Animal dog = new Animal("Buddy", "Golden Retriever", user);
user.getPets().add(dog);

// Persist the objects natively (JSNDB handles the relations automatically!)
db.persist(dog);
db.persist(user);
db.commit(); // Writes gracefully to disk

3. Query the Database

// Builder for searching
qwery q = qwery.create(Persona.class, "Alice", "name", comparators.equal);

List<Persona> results = db.select(Persona.class, q);
for (Persona p : results) {
    System.out.println("Found " + p.getName() + " with " + p.getPets().size() + " pets!");
}

⚡ Performance Benchmarks

JSNDB was heavily optimized and benchmarked directly against industry leviathans: SQLite (C-based relational DB) and Nitrite (Java embedded NoSQL DB).

The test involved inserting, selecting, and modifying 400,000 extreme relational objects (100,000 Persons each containing 3 nested Pets).

Results (100k Complex Entities)

Operation JSNDB (NoSQL) Nitrite Database (NoSQL) SQLite (RDBMS)
Insert 4.566 ms 10.259 ms 2.073 ms
Select (Indexed) 2.165 ms 7.683 ms 369 ms
Update (Bulk) 13 ms 🔥 10.436 ms 104 ms
Delete (Bulk) 0 ms (Instant) 🔥 12.790 ms 13 ms

Key Takeaway

  • Obliterates NoSQL Competition: JSNDB performs inserts 2.2x faster and selects 3.5x faster than Nitrite Database.
  • Bulk Dominance: In mass modifications (Updates and Deletes), JSNDB resolves logical operations seamlessly in under 15 milliseconds, beating even the raw C engine of SQLite (which took ~100ms) and destroying Nitrite which took more than 10-12 seconds.
  • Unhackable Circularity: Nitrite crashed (StackOverflowError) during the test due to cyclic POJO references via Jackson. JSNDB's lazyload proxy matrix resolved the references natively without requiring dirty @JsonIgnore decorators.

💻 Benchmark Comparison Code

JSNDB (Native Java POJO)

// 1. Insert 100k Entities (with relations)
for (int i = 0; i < COUNT; i++) {
    persona p = new persona("User " + i, i, new ArrayList<>());
    for (int k=0; k < 3; k++) {
        animal a = new animal("Pet " + k, "Breed", p);
        p.getMascota().add(a);
        js.persist(a);
    }
    js.persist(p);
}
js.commit();

// 2. Select by Property (Indexed)
qwery q = qwery.create(persona.class, "User 500", "name", comparators.equal);
List<persona> results = js.select(persona.class, q);

SQLite (JDBC RDBMS)

// 1. Relational Table Setup & Inserts
st.execute("CREATE TABLE persona (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
st.execute("CREATE TABLE animal (id INTEGER PRIMARY KEY, nombre TEXT, owner_id INTEGER)");
conn.setAutoCommit(false);

for (int i = 0; i < COUNT; i++) {
    psPersona.setString(2, "User " + i);
    psPersona.executeUpdate();
    for (int k=0; k < 3; k++) {
        psAnimal.setString(1, "Pet " + k);
        psAnimal.setInt(2, i);
        psAnimal.executeUpdate();
    }
}
conn.commit();

Nitrite Database (NoSQL)

// 1. Repository Setup & Indexing
ObjectRepository<persona> repo = db.getRepository(persona.class);
repo.createIndex("name", IndexOptions.indexOptions(IndexType.NonUnique));

for (int i = 0; i < COUNT; i++) {
    persona p = new persona("User " + i, i, new ArrayList<>());
    repo.insert(p); // Nitrite crashes on circular references
}
db.commit();

Download (Beta 1)

Download the jsndb-beta1.jar from the release section to try it directly in your project.

Compiling manually

javac -d bin src/**/*.java
jar cvf jsndb-beta1.jar -C bin/ .

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages