Datenbank & ORM

Die Entitätshierarchie, das BaseService-Muster, Migrationen und Seed-Daten.

Auf dieser Seite

Datenbank & ORM

Entitätshierarchie

Jede Entität erweitert BaseEntity (@mappedsuperclass, selbst eine Erweiterung von cborm.models.ActiveEntity), das jeder Tabelle automatisch createdDate, modifiedDate und ein isActive-Soft-Delete-Flag hinzufügt:

classDiagram
    class BaseEntity {
        +createdDate
        +modifiedDate
        +isActive
        +getId()
        +isLoaded()
        +appendToMemento()
    }
    class User
    class Role
    class Permission
    class APIToken
    class RememberToken
    class Passkey
    class Setting

    BaseEntity <|-- User
    BaseEntity <|-- Role
    BaseEntity <|-- Permission
    BaseEntity <|-- APIToken
    BaseEntity <|-- RememberToken
    BaseEntity <|-- Passkey
    BaseEntity <|-- Setting

    User "many" --> "many" Role : roles
    User "many" --> "many" Permission : à la carte
    User "1" --> "many" APIToken
    User "1" --> "many" RememberToken
    User "1" --> "many" Passkey
    Role "many" --> "many" Permission : role_permissions

dbcreate: "none" (gesetzt in public/Application.bxs ormSettings) bedeutet, dass das Schema ausschließlich von Migrationen verwaltet wird — das ORM erzeugt oder ändert niemals automatisch Tabellen.

Service-Layer-Muster

Jeder Service erweitert BaseService (@singleton, erweitert cborm.models.VirtualEntityService), das qb, coldbox, wirebox und cachebox:template injiziert und ensureSortOrder() bereitstellt:

component
    extends="BaseService"
    singleton
    threadSafe
{

    property name="qb"    inject="provider:QueryBuilder@qb";
    property name="cache" inject="cachebox:template";

    function list( struct criteria = {} ){
        return newCriteria()
            .when( criteria.search, function( c, term ){
                c.like( "name", "%#term#%" );
            } )
            .list();
    }

}
/**
 * A role: a named bundle of permissions.
 */
class extends="app.models.BaseEntity" table="roles" {

    property name="roleId" fieldtype="id" generator="uuid2" ormtype="string";
    property name="name" type="string";

    property name="permissions"
        fieldtype="many-to-many"
        cfc="Permission"
        linktable="role_permissions";

}
component extends="app.models.BaseService" singleton threadSafe {

    function getAllForLookup(){
        return newCriteria().resultTransformer( "distinct" ).list();
    }

}

Migrationen

Betrieben von cfmigrations über das commandbox-migrations-CLI-Modul, konfiguriert in .cbmigrations.json (migrationsDirectory: resources/database/migrations/, seedsDirectory: resources/database/seeds/, Verbindung aufgebaut aus denselben DB_*-Umgebungsvariablen wie public/Application.bx).

box migrate up           # Run pending migrations
box migrate down         # Rollback the last batch
box migrate reset        # Rollback everything, then re-migrate
box migrate seed run     # Run database seeders

Migrationen laufen in Dateiname-/Zeitstempel-Reihenfolge:

MigrationErstellt
..._settings.bxsettings (GUID-PK, eindeutiger name, Longtext-value)
..._security.bxpermissions, roles, role_permissions (Join-Tabelle mit zusammengesetztem PK, kaskadierende FKs)
..._users.bxusers (GUID-PK, eindeutige email, nullbares pendingEmail für Self-Service-E-Mail-Änderungsanfragen, nullbares password, JSON-preferences, boolesches hasAvatar, das verfolgt, ob ein Benutzer einen hochgeladenen Avatar auf der cbfs-assets-Disk hat), plus user_roles, user_permissions, user_remember_tokens, user_api_tokens, user_action_tokens, user_passkeys, user_sso_identities — jede Kindtabelle per FK mit ON DELETE CASCADE an users.userId gebunden (siehe Sicherheit & Berechtigungen und Frontend)
..._auditlogs.bxaudit_logs, append-only Aktivitätsdatensätze mit Schweregrad/Kategorie/Aktion, Akteur- und Request-Metadaten sowie Abfrage-Indizes

Seed-Daten

resources/database/seeds/AdminData.bx, ausgeführt über box migrate seed run, erstellt:

  • Eine Admin-Rolle
  • 20 Berechtigungen über fünf Ressourcen (users, roles, permissions, settings, auditlog), jede mit read/write/delete/admin (auditlog verwendet read/export/delete/admin) — alle der Admin-Rolle zugewiesen
  • Einen Admin-Benutzer, admin@cbgenesis.com, dem die Admin-Rolle zugewiesen ist, als reset-pending eingesät, sodass das öffentliche Bootstrap-Passwort bei der ersten Anmeldung ersetzt werden muss

Siehe Sicherheit & Berechtigungen dafür, wie diese Slugs auf Handler-Ebene durchgesetzt werden.

Diese Seite bearbeiten Markdown herunterladen Zuletzt aktualisiert Oct 1, 2026, 2:02:30 PM