120 lines
3.3 KiB
Markdown
120 lines
3.3 KiB
Markdown
# 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<String, Object> 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<PlayerModel> all = orm.findAll(PlayerModel.class);
|
|
PlayerModel one = orm.findOneWhere(PlayerModel.class, "level >= ?", java.util.Collections.singletonList(10));
|
|
List<PlayerModel> many = orm.findWhere(PlayerModel.class, "level >= ?", java.util.Collections.singletonList(10));
|
|
List<PlayerModel> 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<PlayerModel> 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<PlayerModel> players = orm.query(PlayerModel.class)
|
|
.where(eq("status", "ACTIVE").and(gt("level", 10)))
|
|
.list();
|
|
```
|
|
|
|
## Joins, Group By, Having
|
|
|
|
```java
|
|
List<PlayerModel> 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<SomeType>() {
|
|
@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());
|
|
}
|
|
});
|
|
```
|