Database (PocketMine-MP)
Плагин для PMMP 5.36+ с поддержкой PostgreSQL/MySQL через PDO, пулом соединений, миграциями, ORM на атрибутах и кэшем сущностей.
Требования
- PHP 8.1+ (как у PMMP 5.x).
- Расширения:
pdo+pdo_pgsql(PostgreSQL) илиpdo_mysql(MySQL). Проверяется при запуске.
Установка
- Соберите плагин (zip папку
pmmp/Databaseили сборка через DevTools). - Поместите архив/папку в
plugins/. - Запустите сервер один раз для генерации
config.yml. - Заполните
config.yml, перезапустите сервер.
Конфигурация (config.yml)
driver: "postgres" # postgres | mysql
host: "127.0.0.1"
port: 5432 # 3306 для mysql по умолчанию
database: "server"
username: "postgres"
password: ""
options:
persistent: false # persistent соединения PDO
timeoutSeconds: 10
pool:
size: 4 # размер пула PDO
cache:
enabled: true
writeBehind: true
flushIntervalSeconds: 10
maxDirty: 100
ttlSeconds: 0
maxEntries: 0
preloadBatchSize: 20
preloadDelayTicks: 20
preloadAsync: true
migrations:
enabled: true
table: "db_migrations"
Быстрый старт
use andrewkydev\Database\DatabaseProvider;
use andrewkydev\Database\ORM\Attributes as ORM;
use andrewkydev\Database\ORM\Conditions;
$db = DatabaseProvider::get();
// Raw SQL
$db->query()->execute("UPDATE players SET level = level + 1 WHERE username = ?", ["Steve"]);
// ORM-модель
#[ORM\Entity(table: "players")]
final class Player {
#[ORM\Id(autoIncrement: true)]
#[ORM\Column(name: "id")]
public int $id;
#[ORM\Column(unique: true, length: 32)]
#[andrewkydev\Database\ORM\Attributes\CacheKey]
public string $username;
#[ORM\Column]
public int $level;
}
$orm = $db->orm();
$orm->enableCache(Player::class, preload: true);
$player = $orm->findOneWhere(Player::class, "username = ?", ["Steve"]);
$top = $orm->query(Player::class)
->where(Conditions::gt("level", 10))
->orderBy("level DESC")
->limit(10)
->list();
Компоненты API
DatabaseApi(черезDatabaseProvider::get()):config()— текущийDatabaseConfig.schema()—SchemaManager(DDL: create/drop db/table, колонки, индексы).query()—QueryRunner(сырой SQL sync/async).orm()—EntityManager(ORM, кэш, QueryBuilder).migrations()—MigrationManager.
Сырые запросы (QueryRunner)
execute($sql, $params=[])—rowCount().query($sql, $params=[], $mapper=null)— массив строк или маппер.executeAsync/queryAsync($sql, $params, $onSuccess, $onError=null)— выполняется в async-пуле PMMP, создаёт отдельный PDO.
ORM и атрибуты
- Основные атрибуты:
Entity,Id(autoIncrement),Column(name, nullable, length, unique, type),Json,CacheKey,Transient. - Связи:
OneToOne,ManyToOne,OneToMany,ManyToMany(target,mappedBy,joinColumn,referencedColumn,joinTable,inverseJoinColumn,cascadePersist/remove,lazy). - Ленивая загрузка свойств:
LazyRelationsTrait.
Операции ORM (EntityManager)
- CRUD:
insert/update/delete/save+ async аналоги. - Поиск:
findById/findAll/findOneWhere/findWhere/count/exists/deleteWhere(+ async). - Построитель:
query(Class)::QueryBuilder(select/where/and/or/group/having/order/limit,joinFetchдля manyToOne/oneToOne,withRelationsдля загрузки связей, asynclistAsync/oneAsync/countAsync/existsAsync/deleteAsync). - Загрузка связей:
loadRelation(s)и батчloadRelationsFor.
Условия (Conditions)
eq, ne, gt, gte, lt, lte, like, in, isNull, isNotNull, raw. Комбинации через Condition->and()/or().
Кэш сущностей
- Включается
cache.enabled. - Регистрация:
$orm->enableCache(Model::class, ['id','username'], preload: true); - Ключи по умолчанию: Id, поля с
CacheKey, уникальные колонки. writeBehind=true:update/deleteскладываются в очередь (CacheManager) и сбрасываются периодически (CacheFlushTask) или при достиженииmaxDirty.ttlSecondsиmaxEntriesконтролируют размер/старение. Прогрев —CachePreloadTask/CachePreloadAsyncTask.
Миграции
- Интерфейс
Migration { version(): int; up(SchemaManager $schema, QueryRunner $query): void; } - Регистрация:
$db->migrations()->register(new class implements Migration {...}); - Запуск:
$db->migrations()->runPending();(создаёт таблицуmigrations.tableпри необходимости). - Генерация схемы по модели:
OrmSchema::fromEntity(Model::class, SqlDialect::POSTGRES|MYSQL)→SchemaManager::createTable(...).
DDL (SchemaManager)
createDatabase/dropDatabasecreateTable(TableSpec),dropTableaddColumn/updateColumn/dropColumnaddIndex/dropIndex(учитывает синтаксис Postgres/MySQL).
Асинхронность
- Все async методы используют
Server::getInstance()->getAsyncPool()и собственный PDO, не блокируя main thread. - Колбэки:
onSuccess($rows|$entity|$count)и опциональныйonError($message).
Практические советы
- Всегда задавайте
#[Id]и уникальные поля — это улучшает кэш и генерацию схемы. - Для критичных данных можно отключить
writeBehind, чтобы обновления уходили сразу. joinFetchиспользуйте дляmanyToOne/oneToOne, а большие коллекции грузите черезwithRelationsили отдельные запросы.- Postgres: автоинкремент переводится в
SERIAL/BIGSERIAL; MySQL —AUTO_INCREMENT.
Отладка и проблемы
- Ошибка о расширениях — установите/включите
pdo,pdo_pgsqlилиpdo_mysql. DatabaseApi is not initialized— плагин ещё не загрузился; обращайтесь кDatabaseProvider::get()послеonEnable.- Пустой пул — проверьте доступ к БД и креды в конфиге.
Description
Languages
PHP
100%