PHPackages                             taro/db-model - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. taro/db-model

ActiveLibrary[Database &amp; ORM](/categories/database)

taro/db-model
=============

php-ormapperの改良バージョン。

v1.0.1(3y ago)05MITPHP

Since Oct 22Pushed 3y agoCompare

[ Source](https://github.com/tekku-taro/db-model)[ Packagist](https://packagist.org/packages/taro/db-model)[ RSS](/packages/taro-db-model/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (3)Used By (0)

DB Model
========

[](#db-model)

PHPでリレーショナルデータベースを操作するための O/Rマッパーです。以前作成した **php-ormapper** の改良版です。 このライブラリを使って、データベース／テーブルの作成・更新やレコードの作成・更新・取得などが可能です。

使い方
---

[](#使い方)

モデルクラス
------

[](#モデルクラス)

*\\Taro\\DBModel\\Models\\Model* クラスを継承します

```
class Post extends Model
{
    // フィールド名を protected で定義
    protected $title;

    protected $body;

    // リレーションメソッドを定義
    public function relatedComments()
    {
        return $this->hasMany(Comment::class);
    }
}
```

### リレーションの定義

[](#リレーションの定義)

モデルクラス内に、リレーションメソッドを定義します。 以下の関係を定義できます。

- 1対1：hasOne(関係先のモデルクラス);
- 1対多：hasMany(関係先のモデルクラス);
- 多対1：belongsTo(関係先のモデルクラス);
- 多対多：manyToMany(関係先のモデルクラス, 中間テーブル名);
- 中間モデルを介した１対多：hasManyThrough(関係先のモデルクラス, 中間モデルクラス);
- 中間モデルを介した多対1：belongsToThrough(関係先のモデルクラス, 中間モデルクラス);

```
// モデル と Post が1対1
public function post()
{
    return $this->hasOne(Post::class);
}

// モデル と Post が1対多
public function posts()
{
    return $this->hasMany(Post::class);
}

// モデル と User が多対1
public function user()
{
    return $this->belongsTo(User::class);
}

// モデル と Post が favorites 中間テーブルを介して 多対多
public function favoritePosts()
{
    return $this->manyToMany(Post::class , 'favorites');
}

// モデル と Comment が Postモデルを介して 1対多
public function comments()
{
    return $this->hasManyThrough(Comment::class, Post::class);
}

// モデル と User が Postモデルを介して 多対1
public function users()
{
    return $this->belongsToThrough(User::class, Post::class);
}
```

### レコードの新規作成

[](#レコードの新規作成)

方法1：インスタンスを作成し、プロパティに値を代入して保存します

```
$post = new Post;
$post->title = 'title1';
$post->body = 'test';
$post->insert();
```

方法2：**fill**メソッドに、配列を渡して一括保存します

```
$post = new Post();
$data = [
    'title'=>'How to cook pizza2',
    'content'=>'test create from array'
];
$post->fill($data)->insert();
```

### レコードの更新

[](#レコードの更新)

方法1：インスタンスのプロパティに更新データを代入します。

```
$post = Post::query()->findById(1);
$post->body = 'updated';
$post->update();
```

方法2：インスタンスの**fill**メソッドに、更新データを配列で渡して更新します。

```
$post = Post::query()->findById(1);
$data = [
    'body' => 'updated'
];
$post->fill($data)->update();
```

### レコードの削除

[](#レコードの削除)

```
$post = Post::query()->findById(1);
$post->delete();
```

クエリビルダとクエリの実行
-------------

[](#クエリビルダとクエリの実行)

モデルクラスの **query** を起点にクエリを作成していきます。

### クエリビルダの作成

[](#クエリビルダの作成)

必要なメソッドをメソッドチェーンで繋いでいきます。

```
// where(カラム名, 値) 又は、 where(カラム名, oper, 値)
Post::query()->where('title', 'IN', ['test1', 'test2'])
Post::query()->where('id', '1')
// whereIn(カラム名, 値の配列)
Post::query()->whereIn('id', [1,2,3])
// whereBetween  (カラム名, min, max)
Post::query()->whereBetween('id', 2, 4)

// orderBy(カラム名, ['DESC' | 'ASC'])
Post::query()->orderBy('id', 'DESC')
// limit(取得数)
Post::query()->limit(2)
// groupBy(カラム名)
Post::query()->groupBy('user_id')

// カラムを選択
Post::query()->select('title','body')
```

### クエリの実行

[](#クエリの実行)

クエリビルダを作成した後、あるいは単独で実行できるメソッド。

```
// 複数のモデルを取得
$posts = Post::query()->where('id', '>', '2')->getAll();
// 複数のレコードを配列で取得
$posts = Post::query()->where('id', '>', '2')->getArrayAll();
// 最初のレコードを取得
$posts = Post::query()->where('id', '1')->getFirst();
// モデルクラスから単独で実行できる
$posts = Post::query()->getAll();

// 集計用のメソッド
// count, average, max, min, sum
Post::query()->count();
Post::query()->count('views'); // カラムを指定
```

### 複雑な WHERE 句の作成

[](#複雑な-where-句の作成)

**Wh** クラスを使って、Where句を作成できます。作成後にクエリビルダの**addWhClause**メソッドで、クエリに追加します。

```
$query = Post::query();
// where 句の作成
// WHERE (views > 2) AND (hidden = "public") OR (title = "test3")
$where = new Wh();
$where->add('views', '>', '2');
$where->addAnd('hidden','public');
$where->addOr('title', 'test3');
// where句をクエリに追加
$query->addWhClause($where);

$posts = $query->getAll();
```

入れ子の構造を作成するには、Whの **static なメソッド**を使います。

```
$where = new Wh();
// WHERE (hidden = "public") AND ((views > 2) OR (title = "test3"))
$where->addBlock(
    Wh::and(
        Wh::block('hidden', 'public'),
        Wh::or(
            Wh::block('views', '>', '2'),
            Wh::block('title', 'test3')
        )
    )
);
$query2->addWhClause($where);
```

### モデルのリスト用クラス

[](#モデルのリスト用クラス)

クエリビルダで **getAll**・**getArrayAll** 実行後の結果は、**ActiveList** を実装したクラスのオブジェクトとして返されます。AcitveList は **ArrayList**, **ObjectList** のインターフェースです。配列として扱えるうえ、リストを操作する便利なメソッドを提供します。

- ArrayList: 配列データが対象
- ObjectList: モデルオブジェクトのリストが対象

```
// getAllの戻り値は、モデルのリストオブジェクト（ObjectList）になります
$posts = Post::query()->where('id', '>', '2')->getAll();
// getArrayAllの戻り値は、配列のリストオブジェクト（ArrayList）になります
$posts = Post::query()->where('id', '>', '2')->getArrayAll();
```

#### 上記インターフェースが提供するメソッド

[](#上記インターフェースが提供するメソッド)

```
merge(): ActiveList 同士の結合

orderBy(key, 'asc'): リストの並び替え
orderBy(callback)

pluck(key): リストの各要素の特定キーのみを取得する

filter(condition): リストを条件で絞り込む

shift():  先頭を取得してリストから取り除く

pop()：末尾を取得してリストから取り除く

first(): リストの先頭を取得

last(): リストの末尾を取得

slice(offset, length): 先頭から offset 番目から length 個取り出す

map(callback): 各要素に処理を実行する

ifAny(callback): 条件が true のものがひとつでもあるか

ifAll(callback): すべての要素で条件が true になるか

groupBy(key): key の値でリストをグループ分けする

toArray(): 格納したデータを配列として返す

clone(): リストのクローン（シャローコピー）

// 使用例　Post の id >= 3 のレコードの title を配列で取得
$posts = Post::query()->getAll();
$titles = $posts->filter(function($item) {
    return $item->id >= 3;
})->pluck('title');
```

### ページネーション

[](#ページネーション)

レコードを指定した数のモデルを取得、戻り値は Paginator クラスになります。

```
// paginate(一度に取得するレコード数)
$posts = Post::paginate(10);
?>

```

### リンクデータの取得

[](#リンクデータの取得)

タグではなく、データのみ必要な場合は、 **getLinkData** メソッドを使います。

```
$data = $posts->getLinkData();

// 以下、データのフォーマット
$data =[
    'routeUrl' => 'http://localhost/posts?key1=value1',
    'links' =>
    array (
        array (
            'label' => '最初',
            'href' => 'http://localhost/posts?key1=value1?pageNo=0',
        ),
        array (
            'label' => '前',
            'href' => 'http://localhost/posts?key1=value1?pageNo=1',
        ),
        array (
            'label' => 1,
            'href' => 'http://localhost/posts?key1=value1?pageNo=0',
        ),
        array (
            'label' => 2,
            'href' => 'http://localhost/posts?key1=value1?pageNo=1',
        ),
        array (
            'label' => 3,
            'href' => 'http://localhost/posts?key1=value1?pageNo=2',
            'selected' => true,
            'disabled' => true,
        ),
        array (
            'label' => '次',
            'href' => 'http://localhost/posts?key1=value1?pageNo=2',
            'disabled' => true,
        ),
        array (
            'label' => '最後',
            'href' => 'http://localhost/posts?key1=value1?pageNo=2',
            'disabled' => true,
        ),
    ),
];
```

### リンクのデザインのカスタマイズ

[](#リンクのデザインのカスタマイズ)

デフォルトでは、bootstrapデザインのリンクが表示されます（要Bootstrapライブラリ）。

カスタマイズしたい場合は、BasicLinks クラスを拡張したクラスを作成し、Paginator::setTemplate() の引数に渡してください。

```
$posts = Post::paginate(10);
$posts->setTemplate(new CustomLinks);
```

モデルクラスを使わないクエリ実行方法
------------------

[](#モデルクラスを使わないクエリ実行方法)

### DirectSql クラス

[](#directsql-クラス)

**DirectSql** を使えば、モデルクラスを介さずクエリを作成・実行したり、直接SQL文を実行できます。

```
// 直接SQL文を実行
$sql = 'SELECT * FROM posts WHERE title = :title';
$query = DirectSql::query()->prepareSql($sql);
$query->bindParam(':title', 'my first post');
$results = $query->runSql();

// よりORM的な記述方法
// レコードの取得
$results = DirectSql::query()
    ->table('posts')
    ->select('title','body')
	->where('id','>=', 2)
	->orderBy('create_date')
	->limit(10)
    ->getAsModels(Post::class);
// 更新
DirectSql::query()
    ->table('posts')
    ->where('title', 'test')
    ->update([
        'title' => 'test 1',
        'body' => 'test post 1'
    ]);
// 削除
DirectSql::query()
    ->table('posts')
    ->where('id', 5)
    ->delete();
```

### リレーション先のモデルの取得

[](#リレーション先のモデルの取得)

```
// 関連モデルのデータを取得
$user = $post->user->getFirst();
$posts = $user->posts->getAll();

// eagerloading N+1問題の解決
// eagerLoad(['リレーション名'])
User::query()->eagerLoad(['tasks'])->getAll();
$tasks = $user->tasks;
```

#### 中間テーブルレコードの作成

[](#中間テーブルレコードの作成)

多対多のリレーションで、中間テーブルにレコードを作成します。

1. 多対多のリレーションを定義

    ```
    public function favoritePosts()
    {
        return $this->manyToMany(Post::class , 'favorites');
    }
    ```
2. **insertPivot** メソッドを使って、レコードを作成

```
// insertPivot(関連テーブルのid, [独自のカラムに登録するデータを配列形式で])
$user->favoritePosts()->insertPivot($postId, ['star'=>$star]);
```

#### レコードの更新

[](#レコードの更新-1)

**updatePivot** メソッドを使って、レコードを更新

```
// updatePivot(関連テーブルのid, [独自のカラムに更新するデータを配列形式で])
$user->favoritePosts()->updatePivot($postId, ['star'=>$star]);
```

#### レコードの削除

[](#レコードの削除-1)

**deletePivot** メソッドを使って、レコードを削除

```
// deletePivot(関連テーブルのid)
$user->favoritePosts()->deletePivot($postId);
```

DB接続設定ファイル
----------

[](#db接続設定ファイル)

*プロジェクトルート/config/database.php* ファイル内にデータベース接続情報を登録します。 **.env** ファイルに記載した情報を使う場合は、 **env()** メソッドを使います。

```
// connections 以下に、接続名をキーとして、接続情報を指定する
return [
    'default'=>'mysql', // デフォルト接続先
    'connections' => [
        'mysql'=>[
            'driver'=>'mysql',
            'host'=>'localhost',
            'user'=>'root',
            'password'=> env('DB_PASSWORD'),  // .env ファイルのデータを指定
            'dbname'=>'tasksdb',
        ],
        'pgsql'=>[
            'driver'=>'pgsql',
            'host'=>'localhost',
            'user'=>'postgres',
            'password'=>'password',
            'dbname'=>'MyDB',
            'schema'=>'public',
            'port'=>5433,
        ],
        // 例では、プロジェクトルート/database 直下の database.sqlite ファイルを読み込む
        'sqlite'=>[
            'driver'=>'sqlite',
            'dsn'=>'sqlite:' . FileHandler::sqlitePath(),
        ],
    ]
];
```

### データベースへ接続

[](#データベースへ接続)

モデルクラスを使う前に、**DB::start**メソッドでDBへ接続します。

```
use Taro\DBModel\DB\DB;
// 引数として利用する接続名を渡す（省略すると、database.phpに記載したdefault値が使われる）
$db = DB::start('mysql', true);

// 接続を閉じる
DB::stopGlobal();
```

### トランザクション制御

[](#トランザクション制御)

DBクラスを使って、トランザクションをコントロールします。

```
// トランザクション開始
DB::beginTrans();
// ロールバック
DB::rollback();
// コミット
DB::commit();
```

DDL関連
-----

[](#ddl関連)

### データベースの管理

[](#データベースの管理)

データベースの作成や削除を実行します。(Sqlite は対象外)

```
use Taro\DBModel\Schema\Database;

// データベースを作成
Database::create('データベース名');
// データベースを削除
Database::dropIfExists('データベース名');
```

### テーブルの作成

[](#テーブルの作成)

**Schema::createTable** を使い、テーブルを作成します。引数のコールバックのタイプヒンティングにはデータベースに応じて、MySqlTable／PostgreSqlTable／SqliteTable を指定してください。

```
use Taro\DBModel\Schema\Schema;
use Taro\DBModel\Schema\MySql\MySqlTable;
// use Taro\DBModel\Schema\PostgreSql\PostgreSqlTable;
// use Taro\DBModel\Schema\Sqlite\SqliteTable;

Schema::createTable('test', function(MySqlTable $table){
    $table->addColumn('id','int')->unsigned()->primary();
    $table->addColumn('content','text')->nullable();
    $table->addColumn('status','string')->length(5)->default('good');
    $table->addColumn('user_id','int')->unsigned();

    $table->addUnique('content', 'status');
    $table->addForeign('user_id')->references('users', 'id')->onDelete('CASCADE');
});
// データベースによっては、一部のメソッドが利用できません。（例：postgresqlでは、unsigned()　利用不可）
```

### テーブルの更新

[](#テーブルの更新)

テーブルを更新するには、まず対象となるテーブルを**Schema::getTable**で取得し、変更内容を記述後に**Schema::alterTable**を実行します。

```
// test テーブルを取得
$table = Schema::getTable('test');
// 変更内容を記述
$table->addColumn('post_id','int');
$table->changeColumn('status')->default(0);
$table->addForeign('post_id')->references('posts','id')->onDelete('cascade')->name('FK1');
$table->dropForeign('fk_test2_user_id_users_id');
$table->dropIndexByColumns('content','status');
$table->addIndex('status')->name('INDEX1');
$table->dropColumn('content');
// 最後に変更クエリを実行
Schema::alterTable($table);
```

テーブルの削除
-------

[](#テーブルの削除)

テーブルを削除するには、**Schema::dropTableIfExists**を実行します。また、取得したテーブルを削除（**Schema::dropTable**）することもできます。

```
// 取得したテーブルを削除
$table = Schema::getTable('test');
Schema::dropTable($table);

// test テーブルを削除
Schema::dropTableIfExists('test');
```

テーブルの一元管理
---------

[](#テーブルの一元管理)

**Schema::saveTable**を使うことで、上記のテーブルの作成・更新・削除を自動で実行することもできます。コールバック内のコードを変更して実行することで、既存の同名テーブルとの差分クエリを作成してテーブルを更新します。

```
use Taro\DBModel\Schema\Schema;
use Taro\DBModel\Schema\MySql\MySqlTable;
// use Taro\DBModel\Schema\PostgreSql\PostgreSqlTable;
// use Taro\DBModel\Schema\Sqlite\SqliteTable;

Schema::saveTable('test', function(MySqlTable $table){
    $table->addColumn('id','int')->primary();
    $table->addColumn('content','text')->nullable();
    $table->addColumn('status','string')->length(5)->default('good');

    $table->addUnique('content', 'status');
});
```

ライセンス (License)
---------------

[](#ライセンス-license)

**DB Model**は[MIT license](https://opensource.org/licenses/MIT)のもとで公開されています。

**DB Model** is open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT).

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

1304d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/439fd70e81e54865b201c97664b3438730a4f751329ebdb1509eb702dae6a51a?d=identicon)[tekku-taro](/maintainers/tekku-taro)

---

Top Contributors

[![tekku-taro](https://avatars.githubusercontent.com/u/59961751?v=4)](https://github.com/tekku-taro "tekku-taro (113 commits)")

---

Tags

orm-libraryphp7

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/taro-db-model/health.svg)

```
[![Health](https://phpackages.com/badges/taro-db-model/health.svg)](https://phpackages.com/packages/taro-db-model)
```

###  Alternatives

[bolt/core

🧿 Bolt Core

585142.5k54](/packages/bolt-core)[laravel-freelancer-nl/aranguent

Laravel bridge for the ArangoDB Multi-model database

517.0k](/packages/laravel-freelancer-nl-aranguent)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
