# ORM (RU) Легковесный ORM: поля мапятся в колонки, без сложных связей. Есть sync и async версии. ## Аннотации - `@DbEntity(table = "players")` - имя таблицы. По умолчанию snake_case. - `@DbColumn(name = "username")` - имя колонки. - `@DbColumn(type = "VARCHAR(32)")` - SQL тип для генерации схемы. - `@DbColumn(length = 32, unique = true, nullable = false)` - влияет на schema генерацию. - `@DbId(autoIncrement = true)` - primary key. - `@DbJson` - JSON поле. - `@DbTransient` - игнорировать поле. ## Пример сущности ```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(); ``` ## Join, 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(); ``` Если выбрать часть колонок, маппятся только они, остальные остаются дефолтными. ## Auto ID Если `@DbId(autoIncrement = true)` и id пустой (0/null), `insert()` получает generated keys и прописывает id в объект. ## Type Adapters UUID уже поддержан. Для других типов: ```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()); } }); ```