プログラム言語 データベース操作 ORM
目次
データ取得
全件
$tests = Test::all();
クエリビルダ
$tests = DB::table('テーブル物理名')->get();
users = User.query.all()
tests = Test.objects.all()
$tests = $this->Tests->find()->all();
$testsTable = $this->getTableLocator()->get('Tests');
$tests = $testsTable->find()->all();
db.Model.findAll()
.then(models => {
console.log(models);
});
主キー指定
$tests = Test::find(999);
$tests = Test::where('id', 999)->first()
と同じ;$tests = Test::findOrFail(999);
先頭
末尾
N件
存在チェック
$isExist = Test::exists();
ture/false
$isEmpty = Test::all()->isEmpty();
$isNotEmpty = Test::all()->isNotEmpty();
COUNT
$tests = Test::count();
結合先テーブルのレコード数
->withCount('モデルクラス名');
$tests = $this->Tests->find()
->count();
SUM
$tests = Test::get->sum(列名);
$query = $this->Tests
->find()
->where([
〜
]);
$test = $query->select([
'定義名' => $query->func()->sum('列名'),
])
->first();
MAX
$max = Test::max('列名');
$max:5
値のみ
$tests = Test::all()->pluck('列名');
結果 $tests = [1, 2, 3, 4, 5];
リレーション先の列名指定
$tests = Test::all()->pluck('リレーション名.列名');
$tests = $this->Tests->find()
->select(['列名'])
->enableHydration(false)
->all()
->extract('列名')
->toList();
結果 $tests = [1, 2, 3, 4, 5];
SELECT
$tests = Test::select(['列名', '列名'])
->addSelect(〜)
FROM
テーブル指定
$tests = Test::all();
モデルクラスのインスタンスを要素とするコレクションを取得
$tests = $this->Tests->find()->all();
モデルクラスのインスタンスを要素とするコレクションを取得
別名
$tests = Test::all();
別名
$tests = Test::from('tests as t')->all();
WHERE
=
$tests = Test::where('列名', 100)
->where('列名', XXX) And条件
->orWhere('列名', XXX) Or条件
->get();
$tests = Test::where('列名', '<>', 100)
否定 ※!=はダメ
->get();
$tests = Test::whereRaw(‘列名 = 100’)->get();
entries = User.query.filter_by(id=1).all()
$tests = $this->Tests->find()
->where([
'列名' => 100,
'列名' => XXX, And条件
]);
->andWhere([
'列名' => 100,
]);
->orWhere([
'列名' => 100,
]);
->all();
db.Model.findAll({
where: {
id: 〜
}
}).then(models => {
console.log(models);
});
db.Model.findByPk(〜)
.then(model => {
console.log(model);
});
IN/NotIN
$tests = Test::whereIn('列名', [100, 200, 300])
->whereNotIn('列名', [100, 200, 300])
->get();
$tests = $this->Tests->find()
->where([
'列名 IN' => [100, 200, 300],
]);
->all();
BETWEEN
$tests = Test::whereBetween('列名', [100, 200])
->get();
$tests = $this->Tests->find()
->where(function ($exp) {
$timestamp = FrozenTime::now()->subDay(1);
return $exp->between(
'Tests.created',
$timestamp->startOfDay()->toDateTimeString(),
$timestamp->endOfDay()->toDateTimeString()
);
})
->all();
NULL判定
$tests = Test::whereNull(列名)
->orWhereNull(列名); OR条件
->whereNotNull(列名); AND条件
->orWhereNotNull(列名); OR条件
->get();
A AND (B OR C)
$tests = Test::where(function($query){
return $query
->where(〜)
->orWhere(〜);
})
->get();
LIKE
$tests = Test::where('列名', 'LIKE', "%検索語%")
->get();
$tests = Test::where('列名', 'NOT LIKE', "%検索語%")
->get();
GROUPBY
$tests = Test::groupBy('列名')
->get();
JOIN
INNER JOIN
$tests = Test::with('結合先テーブルクラス名')->all();
$tests = Test::with(['結合先テーブルクラス名' => function($query){
$query->where('結合先テーブル列名', 'LIKE', '%〜%');
}])->get(),
↓は可能だがEager Loadingを使用しない為にメリット無し
$tests = Test::join(
'結合先テーブル物理名',
'結合先テーブル物理名.列名', '=', 'テーブル物理名.列名'
)
->get();
結果
foreach($tests as $t){
$t->結合先テーブルクラス名->〜;
}
from .models import Other
tests = Test.objects.select_related('other').all()
tests = Other.objects.prefetch_related('test').all()
$tests = $this->Tests
->contain([
'結合先テーブルクラス名1',
'結合先テーブルクラス名2',
結合先と更に結合
'結合先テーブルクラス名3' => [
'結合先テーブルクラス名4',
],
結合条件指定
'結合先テーブルクラス名5' => function (Query $query) use ($test) {
return $query->where(['結合先テーブルクラス名5.列名' => $test->id]);
},
])
->find()->all();
結果
foreach($tests as $t){
$t->結合先テーブル名->〜;
}
結合先テーブルのデータは取得しない場合1
$tests = $this->Tests
->innerJoinWith('結合先テーブルクラス名6')
->innerJoinWith('結合先テーブルクラス名7', function ($q) use ($test) {
return $q
->where(['結合先テーブルクラス名7.列名' => $test->id]);
})
->find()->all();
結合先テーブルのデータは取得しない場合2
$tests = $this->Tests
->join()
'table' => 'テーブル物理名',
'alias' => 'テーブル別名',
'type' => 'INNER',
'conditions' => 'テーブル別名.列名 = 結合元テーブル名.列名',
->find()->all();
LEFT JOIN
$tests = Test::leftJoin(
'結合先テーブル物理名',
'結合先テーブル物理名.列名', '=', 'テーブル物理名.列名'
)
->get();
結果
foreach($tests as $t){
$t->結合先テーブルクラス名->〜;
}
$tests = $this->Tests
->contain([
〜
])
->find()->all();
結合先テーブルのデータは取得しない場合1
$tests = $this->Tests
->leftJoinWith('結合先テーブルクラス名6')
->leftJoinWith('結合先テーブルクラス名7', function ($q) use ($test) {
return $q
->where(['結合先テーブルクラス名7.列名' => $test->id]);
})
->find()->all();
結合先テーブルのデータは取得しない場合2
$tests = $this->Tests
->join()
'table' => 'テーブル物理名',
'alias' => 'テーブル別名',
'type' => 'LEFT',
'conditions' => 'テーブル別名.列名 = 結合元テーブル名.列名',
->find()->all();
結合先テーブルのデータも取得する場合
$tests = $this->Tests
->matching('結合先テーブルクラス名8')
->matching('結合先テーブルクラス名8', function ($q) use ($test) {
return $q
->where(['結合先テーブルクラス名8.列名' => $test->id]);
})
->find()->all();
結果
foreach($tests as $t){
$t->_matchingData['結合先テーブルクラス名']->〜;
}
has/doesnt
結合先テーブルのレコードがあるもののみ取得
$tests = Test::has('リレーション名') ※結合先テーブル物理名ではない
->orHas('リレーション名') ※結合先テーブル物理名ではない
->whereHas(function($query){
return $query->where(〜);
})
->get();
hasの条件指定も可
$tests = Test::has('リレーション名', function($query) { ※結合先テーブル物理名ではない
検索条件
return $query->where(〜);
})〜
結合先テーブルのレコードがないもののみ取得
$tests = Test::doesntHave('リレーション名') ※結合先テーブル物理名ではない
->orDoesntHave('リレーション名') ※結合先テーブル物理名ではない
->whereDoesntHave(function($query){
return $query->where(〜);
})
->get();
ORDER BY
$tests = Test::orderBy(列名, 'ASC')
->orderBy(列名, 'DESC')
->get();
サブクエリ
SELECT句
$tasks = Test::leftJoin(〜)
->leftJoin(〜)
->select()
->selectSub(
use App\Models\TestMany;
TestMany::selectRaw('count(*)')
->whereRaw('副問い合わせ先テーブル名.列名 = 〜.id')
, 'SubCount')
->get();
※with(EargerLoading)を用いてのサブクエリは調査中
FROM句
span class=”gray”>use App\Models\Test;
$subquery = Test::select([
DB::raw('IFNULL(col1, id) AS col1'
),
'col2'
,
])
->toSql();
$counts = DB::table(DB::raw(
"(${subquery}) AS counts"
))
->select([
'counts.col1'
,
DB::raw('SUM(counts.col2) AS col2'
),
])
->groupBy('counts.col1'
)
->get();
JOIN
use App\Models\TestSub;
$subQuery = TestSub->where(〜, 555);
use App\Models\Test;
$tasks = Test::joinSub($subQuery->getQuery(), 'サブクエリテーブル別名', function ($join) {
$join->on('サブクエリテーブル別名.列名', '=', 'tests.列名');
});
)
getQuery()メソッド=Eloquentのクエリビルダー化関数
これを利用せずにjoinSubしている参考サイト多数あり(要調査)
use App\Models\TestMany;
$subQuery = DB::table(〜)
->where(〜, 555);
use App\Models\Test;
$tasks = Test::leftJoin(
DB::raw("($subQuery->toSql()) AS SubTable", 'SubTable.列名', '=', 'tests.id')
)
サブクエリのバインディングをここで指定(過去バージョンのLaravelのみ)
->mergeBindings($subQuery)
->get();
Loop
collectionの中身を変更しない場合に利用
Test::all()->each(function ($test) {
continue
return true;
break
return false;
$test->aaa = 555;
$test->save();
});
collectionの中身を変更する場合に利用
Test::all()->mapfunction ($test) {
$test->aaa = 555;
return $test;
});
データ更新
INSERT
$user = new User();
$user->fill([
'name' => 'Laravel',
'email' => 'laravel@php.com'
]);
↓も可
$user->name = ‘Laravel’;
$user->email = ‘laravel@php.com’;
$user->save();
【方法2 インスタンス作成&保存】
$user = User::create([
'name' => 'Laravel',
'email' => 'laravel@php.com'
]);
【複数件INSERT】
User::createMany(
[
'name' => 'Laravel',
'email' => 'laravel@php.com'
],
[
〜
]
);
product = Product.query.filter_by(id=5).first()
product.name = “aaa”
db.session.add(product)
db.session.commit()
db.Model.create({
col1: 〜,
col2: 〜,
col3: 〜
})
.then(model => {
console.log(model);
});
UPDATE
$user = User::findOrFail(10);
$user->name = 'Laravel';
$user->email = 'laravel@php.com';
$user->save();
User::where(〜)
->update([
'列名' => 値,
'列名' => 値,
]);
product = Product.query.filter_by(id=5).first()
product.name = “aaa”
db.session.commit()
db = require('〜/models/index');
db.Model.update({
col1: 〜,
col2: 〜,
col3: 〜
},
{
where: {
id: 〜
}
})
.then(model => {
console.log(model);
});
db.Model.findByPk(〜)
.then(model => {
model.col1 = 〜;
model.col2 = 〜;
model.col3 = 〜;
model.save()
.then(model => {
console.log(model);
});
});
UpdateOrInsert
[
’更新対象検索条件列名’ => 値,
’更新対象検索条件列名’ => 値,
],
[
’更新列名’ => 値,
’更新列名’ => 値,
],
);
where: {
id: 5
},
update: {
where対象がある場合の処理
column: 10
},
以下もOK
update: {},
create: {
where対象がない場合の処理
column: 10
},
);
DELETE
User::destroy(1);
【複数件削除】
User::where('name', 'Laravel')->delete();
【全件削除】(クエリビルダ)
User::query()->delete();
product = Product.query.filter_by(id=5).first()
db.session.delete(product)
db.session.commit()
db.Model.destroy({
where: {
id: 〜
}
})
.then(model => {
console.log(model);
});
ATTACH / DETTACH
多対多のリレーションレコードを挿入
$user = User::find(1);
usersとrolesとの中間テーブルにroles.id=999のレコードを挿入
$user->roles()->attach(999);
挿入時の中間テーブルレコードを作成
$user->roles()->attach(999, [
'expires' => $expires
]);
【DETTACH】
usersとrolesとの中間テーブルからroles.id=999のレコードを削除
$user->roles()->detach(999);
全て削除
$user->roles()->detach();
updateExistingPivot
$user->roles()->updateExistingPivot(999, ['expires' => $expires
]);
中間テーブルの値がない場合は作成後、ある場合は更新(主キー=999)
$user->roles()->syncWithPivotValues(999, [
'expires' => $expires
], false);
SQL利用
DB::select('select * from users where active = ?', [1000]);
DB::User
->select(DB::raw('sum(〜) as actcnt'))
->selectRaw('price * ? as price_with_tax', [1.0825])
->whereRaw('price > IF(state = 1, ?, 100)', [200])
->orWhereRaw('price > IF(state = 1, ?, 100)', [200])
->get();
SQL生成
$sql = Test::toSql();
パラメータ付き
$query = Test::where(〜);
$sql = preg_replace_array('/\?/'
, $query->getBindings(), $query->toSql());