# ORM The ORM is lightweight: it maps fields to columns and does not manage complex relationships. It supports sync and async operations. ## Annotations - `@DbEntity(table = "players")` sets table name. Default: snake_case class name. - `@DbColumn(name = "username")` overrides column name. - `@DbColumn(type = "VARCHAR(32)")` overrides SQL type for schema generation. - `@DbColumn(length = 32, unique = true, nullable = false)` influences schema generation. - `@DbId(autoIncrement = true)` marks the primary key. - `@DbJson` stores the field as JSON. - `@DbTransient` ignores the field. ## Example entity ```java @DbEntity(table = "players") public class PlayerModel { @DbId(autoIncrement = true) private long id; @DbColumn(name = "username", nullable = false, unique = true, length = 32) private String name; @DbColumn private int level; @DbJson private java.util.Map metadata; @DbTransient private String temp; public PlayerModel() { } } ``` ## CRUD ```java EntityManager orm = api.orm(); orm.insert(entity); orm.update(entity); orm.delete(entity); PlayerModel player = orm.findById(PlayerModel.class, 1L); List all = orm.findAll(PlayerModel.class); PlayerModel one = orm.findOneWhere(PlayerModel.class, "level >= ?", java.util.Collections.singletonList(10)); List many = orm.findWhere(PlayerModel.class, "level >= ?", java.util.Collections.singletonList(10)); List paged = orm.findWhere(PlayerModel.class, "level >= ?", java.util.Collections.singletonList(10), "level DESC", 10, 0); long count = orm.count(PlayerModel.class, "level >= ?", java.util.Collections.singletonList(10)); boolean exists = orm.exists(PlayerModel.class, "username = ?", java.util.Collections.singletonList("Steve")); int deleted = orm.deleteWhere(PlayerModel.class, "level < ?", java.util.Collections.singletonList(1)); ``` ## Query Builder ```java EntityManager orm = api.orm(); List top = orm.query(PlayerModel.class) .where("level >= ?", 10) .orderBy("level DESC") .limit(10) .list(); boolean exists = orm.query(PlayerModel.class) .where("username = ?", "Steve") .exists(); ``` ## Fluent Conditions ```java import static com.andrewkydev.database.orm.Conditions.*; List players = orm.query(PlayerModel.class) .where(eq("status", "ACTIVE").and(gt("level", 10))) .list(); ``` ## Joins, Group By, Having ```java List rows = orm.query(PlayerModel.class) .select("players.*") .join("LEFT JOIN clans ON clans.id = players.clan_id") .groupBy("players.id") .having("COUNT(clans.id) > ?", 0) .list(); ``` Selecting a subset of columns maps only those fields; missing fields keep default values. ## Auto ID on insert If `@DbId(autoIncrement = true)` is used and the id is empty (0 or null), `insert()` will read generated keys and set the id back on the entity. ## Custom Type Adapters UUID mapping is built-in. For other types: ```java orm.registerAdapter(SomeType.class, new TypeAdapter() { @Override public Object toDatabase(SomeType value) { return value == null ? null : value.toString(); } @Override public SomeType fromDatabase(Object value) { return value == null ? null : SomeType.parse(value.toString()); } }); ```