Shell Script 문법 정리
Title: Bash Shell Script 문법 정리 Author: DongDongE Tags: Programming Release: 2021.02.08 [Shell
Title: PHP Laravel - 데이터베이스
Author: DongDongE
Tags: Programming
Release: 2020.08.10
라라벨은 Raw SQL를 사용하거나 "쿼리 빌더" 또는 "Eloquent ORM"을 사용하여 다양한 데이터베이스 백엔드에서 데이터베이스와 상호작용을 매우 간편하게 만들 수 있습니다. 현재 라라벨은 4가지 데이터베이스를 지원하고 있습니다.
애플리케이션의 데이터베이스 설정은 "config/database.php"에 있습니다. 해당 파일에서 모든 데이터베이스 연결을 정의하고 기본적으로 어떤 데이터베이스를 연결할지 지정할 수 있습니다. 지원되는 대부분의 데이터베이스 시스템에 대한 기본 예제가 들어 있습니다.
기본적으로 라라벨의 샘플 환경 구성은 로컬 머신에서 개발을 진행하기 위해 라라벨의 "Homestead"을 사용할 준비가 되어 있습니다. 물론 로컬 데이터베이스 필요에 따라 해당 구성을 자유롭게 변경할 수 있습니다.
"touch database/database.sqlite"와 같은 명령을 사용하여 새로운 SQLite 데이터 베이스를 만들고 데이터베이스의 절대 경로를 사용하여 새로 만든 데이터베이스를 가리키도록 설정을 쉽게 변경할 수 있습니다.
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
.env
라라벨은 supports SQL Server를 지원합니다. 하지만 데이터베이스에 대한 연결 구성은 "config/database.php"에서 추가해야합니다.
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
"SELECT"문에 대해 하나의 데이터베이스에 연결하여 사용하고, "INSERT, UPDATE, DELETE" 문에 대해서는 다른 데이터베이스에 연결하여 사용할 수 있습니다. 라라벨은 이부분을 쉽게 만들 수 있도록 처리해주며, Raw 쿼리를 사용하거나, "쿼리 빌더" 또는 "Eloquent ORM"을 사용하든 적절한 연결이 사용됩니다.
읽기 / 쓰기 연결 설정은 아래와 같습니다.
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
config/database.php
mysql 배열에는 "read"와 "write" 라는 2개의 키가 존재합니다. 각 키에는 단일 키 "host"가 포함된 배열값이 존재합니다. "read"와 "write" 연결에 대한 나머지 데이터베이스 옵션은 기본 "mysql" (ex. username, password)배열에서 합쳐져 사용됩니다.
만약 기본 배열(mysql 배열)의 값을 재정의하려는 경우 "read"와 "write" 배열에 항목을 추가하면됩니다. 따라서 위 예제 경우 "192.168.1.1" IP는 "read(읽기 권한만)" 연결을 위한 호스트로 사용되며, "192.168.1.2" IP는 "write(쓰기 권한만)"에 사용됩니다. 메인 "mysql" 배열의 데이터베이스의 연결정보, "prefix", "database", "username" 등 기타 모든 옵션은 두 배열(read, write) 모두에 공유됩니다.
여러 연결을 사용하는 경우 "DB" 파사드의 "connection" 메소드를 사용하여 각각 연결에 액세스할 수 있습니다. "connection" 메소드에 전달된 "name"은 "config/database.php" 설정파일에 나열된 이름이랑 일치해야 합니다.
$users = DB::connection('foo')->select(...);
연결 인스턴스에서 "getPdo" 메소드를 사용하여 Raw PDO 인스턴스에 접근할 수 있습니다.
$pdo = DB::connection()->getPdo();
데이터베이스 연결을 구성한 후에는 "DB" 파사드를 사용하여 쿼리를 실행할 수 있습니다. "DB" 파사드는 "select, update, insert, delete" 그리고 "statement"의 각 쿼리 유형에 대한 메소드를 제공합니다.
기본 쿼리를 실행하려면 "DB" 파사드에서 "select" 메소드를 사용할 수 있습니다.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*
* @return Response
*/
public function index()
{
$users = DB::select('select * from users where active = ?', [1]);
return view('user.index', ['users' => $users]);
}
}
"select" 메소드에 전달된 첫 번째 인자는 Raw SQL 쿼리이며, 두 번째 인자는 쿼리에 바인딩해야하는 매개변수값입니다. 일반적으로 이들은 "where" 절 제약을 위한 조건값입니다. 매개변수 바인딩은 SQL Injection에 대응하기 위해 제공합니다.
"select" 메소드는 항상 배열로 반환합니다. 배열내의 각 값 결과는 PHP "StdClass" 객체가 되어 결과값에 액세스할 수 있습니다.
foreach ($users as $user) {
echo $user->name;
}
기존 "?"를 사용하여 매개변수 바인딩을 표시하는 대신 이름(Named)를 사용하여 쿼리를 실행할 수 있습니다.
$results = DB::select('select * from users where id = :id', ['id' => 1]);
"insert" Statement 실행하려면 "DB" 파사드에서 "insert" 메소드를 사용할 수 있습니다. "select"와 마찬가지로 해당 메소드도 Raw SQL 쿼리를 첫 번째 인자로 전달되며, 두 번째 인자로는 쿼리에 바인딩할 매개변수를 전달합니다.
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
데이터베이스의 기존 레코드(데이터)를 업데이트(수정)하려면 "update" 메소드를 사용하면 됩니다. 결과값으로는 해당 쿼리문의 영향을 받는 행 갯수가 반환됩니다.
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
데이터베이스의 레코드(데이터)를 삭제하려면 "delete" 메소드를 사용할 수 있습니다. "update" 메소드와 마찬가지로 해당 쿼리문으로 영향을 받는 행 갯수가 반환됩니다.
$deleted = DB::delete('delete from users');
일부 데이터베이스는 값을 반환하지 않는 경우가 있습니다. 이러한 유형은 "DB" 파사드에서 "statement" 메소드를 사용할 수 있습니다.
DB::statement('drop table users');
애플리케이션에서 실행되는 각 쿼리를 확인하기 위해 "listen" 메소드를 사용할 수 있습니다. 해당 메소드는 "쿼리 로깅" 또는 "디버깅"에 유용합니다. "서비스 프로바이더"에 쿼리 리스너를 등록할 수 있습니다.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
"transaction" 메소드는 교착상태가 발생할 때 트랜잭션을 재시도해야 하는 횟수를 정의하는 두 번째 인자로 선택적으로 전달 받습니다. 이러한 시도가 모두 종료되면 "exception" 예외가 발생합니다.
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
}, 5);
트랜잭션을 수동으로 시작하고 "롤백"과 "커밋"을 완벽하게 제어하기 위해 "DB" 파사드에서 "beginTransaction" 메소드를 사용할 수 있습니다.
DB::beginTransaction();
"rollback" 메소드를 통하여 트랜잭션을 롤백할 수 있습니다.
DB::rollBack();
마지막으로 "commit" 메소드를 통하여 트랜잭션을 커밋할 수 있습니다.
DB::commit();
"DB" 파사드의 트랜잭션 메소드를 사용하여 "쿼리 빌더" 및 "Eloquent ORM"에 대한 트랜잭션도 제어할 수 있습니다.
라라벨의 데이터베이스 쿼리 빌더는 데이터베이스 쿼리를 생성하고 실행하기 위해 편리한 인터페이스를 제공합니다. 애플리케이션에서 대부분의 데이터베이스 작업을 수행하는데 사용할 수 있으며, 지원되는 모든 데이터베이스 시스템에서 작동합니다.
라라벨 쿼리 빌더는 "PDO" 매개 변수 바인딩을 사용하여 SQL Injection으로 부터 애플리케이션을 보호합니다. 바인딩으로 전달되는 문자열을 따로 정리할 필요는 없습니다.
쿼리를 시작하기 위해 "DB" 파사드에서 "table" 메소드를 사용할 수 있습니다. "table" 메소드는 주어진 테이블에 대한 쿼리 빌더 인스턴스를 반환하므로, 쿼리에 더 많은 제약 조건을 연결한 다음 마지막으로 "get" 메소드를 사용하여 결과를 가져올 수 있습니다.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*
* @return Response
*/
public function index()
{
/* Table users 모든행 가져오기 => SELECT * FROM users */
$users = DB::table('users')->get();
return view('user.index', ['users' => $users]);
}
}
"get" 메소드는 각 결과가 PHP "StdClass" 객체의 인스턴스인 결과를 포함하는 "Illuminate\Support\Collection"을 반환합니다. 객체의 속성으로 컬럼에 액세스하여 각 컬럼의 값에 액세스할 수 있습니다.
foreach ($users as $user) {
/* users 테이블의 "name" 컬럼의 값에 접근 */
echo $user->name;
}
데이터베이스 테이블에서 단일 행 결과를 가져오려면 "first" 메소드를 사용할 수 있습니다. 해당 메소드는 단일 "StdClass" 개체를 반환합니다.
/* SELECT * FROM users WHERE name = "John" limit 0,1 */
$user = DB::table('users')->where('name', 'John')->first();
echo $user->name;
아래는 위 SQL 쿼리에 실행에 대한 General Log 입니다.
2020-08-11T16:01:28.431755Z 5 Prepare select * from `users` where `name` = ? limit 1
2020-08-11T16:01:28.431927Z 5 Execute select * from `users` where `name` = 'dongdonge' limit 1
또한 전체 행이 필요하지 않은 경우 "value" 메소드를 사용하여 레코드에서 단일 값을 출력할 수 있습니다. 해당 메소드는 컬럼 값을 직접 반환합니다.
$email = DB::table('users')->where('name', 'John')->value('email');
아래는 위 SQL 쿼리에 실행에 대한 General Log 입니다.
2020-08-11T16:08:09.885615Z 5 Prepare select `email` from `users` where `name` = ? limit 1
2020-08-11T16:08:09.885814Z 5 Execute select `email` from `users` where `name` = 'dongdonge' limit 1
2020-08-11T16:08:09.886155Z 5 Close stmt
단일 컬럼값을 포함하는 컬렉션을 검색하려면 "pluck" 메소드를 사용할 수 있습니다. 아래 예제에서 "roles" 테이블의 "title" 컬렉션을 검색합니다.
$titles = DB::table('roles')->pluck('title');
foreach ($titles as $title) {
echo $title;
}
아래는 위 SQL 쿼리에 실행에 대한 General Log 입니다.
2020-08-12T02:54:19.929864Z 8 Prepare select `title` from `roles`
2020-08-12T02:54:19.930199Z 8 Execute select `title` from `roles`
2020-08-12T02:54:19.930546Z 8 Close stmt
아래는 PHP artisan(아티즌)을 통하여 해당 결과값을 확인하였습니다.
**>>> DB::table('roles')->pluck('title');
=> Illuminate\Support\Collection {#706
all: [
"Big_Title",
"test123",
],
}**
또한 반환된 컬렉션에 대해 사용자 지정 키 컬럼(열)을 지정할 수 있습니다.
$roles = DB::table('roles')->pluck('title', 'name');
foreach ($roles as $name => $title) {
echo $title;
}
아래는 위 SQL 쿼리에 대한 General Log 입니다
2020-08-12T04:51:28.263119Z 8 Prepare select `title`, `name` from `roles`
2020-08-12T04:51:28.263336Z 8 Execute select `title`, `name` from `roles`
2020-08-12T04:51:28.263454Z 8 Close stmt
수천 개의 데이터베이스 레코드로 작업해야하는 경우 "chunk" 메소드를 사용하면 됩니다. 해당 메소드는 한 번에 결과의 작은 "chunk"를 검색하고 각 chunk를 "Closure"에 처리합니다. 해당 방법은 수천 개의 데코드를 처리하는 "Artisan" 명령어를 작성할 때 유용합니다.
예를 들어, "users" 테이블을 한 번에 100개의 레코드 chunk로 작업해 보겠습니다.
DB::table('users')->orderBy('id')->chunk(100, function ($users) {
foreach ($users as $user) {
//
}
});
"Closure"에서 "false"를 반환하여 추가 chunks를 중지할 수 있습니다.
DB::table('users')->orderBy('id')->chunk(100, function ($users) {
// Process the records...
return false;
});
쿼리 빌더는 "count", "max", "min", "avg", "sum"과 같은 다양한 집계 메소드를 제공합니다. 쿼리는 생성한 후 다음 메소드중 하나를 호출하여 사용하시면 됩니다.
$users = DB::table('users')->count();
$price = DB::table('orders')->max('price');
또는 아래와 같이 메소드를 다른 구문과 결합하여 사용할 수 있습니다.
$price = DB::table('orders')
->where('finalized', 1)
->avg('price');
물론, 데이터베이스 테이블에서 모든 컬럼(열)을 항상 선택할 수 있는 것은 아닙니다. "select" 메소드를 사용하여 쿼리에 대한 사용자 지정 "select" 구문을 사용할 수 있습니다.
$users = DB::table('users')->select('name', 'email as user_email')->get();
"distinct" 메소드를 사용하여 쿼리가 고유한 결과를 반환할 수 있도록 할 수 있습니다.
$users = DB::table('users')->distinct()->get();
이미 쿼리 빌더 인스턴스가 있고 기존 "select" 구문에 컬럼(열)을 추가하려는 경우 "addSelect" 메소드를 사용할 수 있습니다.
$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();
때로는 쿼리에서 Raw 표현식을 사용해야 할 때가 있습니다. 이러한 구문의 쿼리는 문자열로 주입되므로 SQL Injection이 되지 않도록 조심해야 합니다. Raw Expression을 만들려면 "DB::raw" 메소드를 사용할 수 있습니다.
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
쿼리 빌더를 사용하여 "join" 구문을 작성할 수 있습니다. 기본 "inner join(내부 조인)"을 수행하려면 쿼리 빌더 인스턴스에 "join" 메소드를 사용할 수 있습니다. 조인 메소드에 전달된 첫 번째 인수는 조인해야 하는 테이블의 이름이고 나머지 인자는 조인에 대한 컬럼(열) 조건을 지정합니다. 물론 단일 쿼리로 여러 테이블에 조인할 수 있습니다.
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();
"inner join(내부조인)" 대신 "left join(왼쪽 조인)"을 수행하려면 "leftJoin" 메소드를 사용해야합니다. "leftJoin" 메소드는 "join" 메소드와 동일한 시그니처를 갖습니다.
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
"cross join(교차 조인)"을 수행하려면 교차 결합하려는 테이블의 이름과 함께 "cross join" 메소드를 사용하면 됩니다. "Cross joins"는 첫 번째 테이블과 조인된 테이블 사이 cartesian product을 생성합니다.
$users = DB::table('sizes')
->crossJoin('colours')
->get();
고급 조인 구문을 지정하여 사용할 수 있습니다. 사용하려면 "join" 메소드에서 두 번째 인수로 "Closure"를 전달하면 됩니다. "Closure"는 "join" 구문에 제약 조건을 지정할 수 있는 "JoinClause" 개체를 받습니다.
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
조인에 "where" 스타일 구문을 사용하려면 join에 "where" 및 "orWhere" 메소드를 사용할 수 있습니다. 두 컬럼을 비교하는 대신 이러한 메소드는 컬럼을 값과 비교합니다.
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
또한 쿼리 빌더는 두 쿼리를 합계 "union(결합)"하는 빠른 방법을 제공합니다. 예를 들어, 초기 쿼리를 생성하고 union 메소드를 사용하여 두 번째 쿼리와 "union" 할 수 있습니다.
$first = DB::table('users')
->whereNull('first_name');
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();
"unionAll" 메소드도 사용할 수 있으며, "union"과 동일한 메소드 시그니처입니다.
쿼리 빌더 인스턴스에서 "where" 메소드를 사용하여 쿼리에 "where" 구문을 추가할 수 있습니다. 가장 기본적인 호출에는 3가지 인자가 필요합니다. 첫 번째 인자는 컬럼명이며, 두 번째 인자는 데이터베이스의 지원되는 모든 연산자가 될 수 있는 연산자이며, 마지막으로 세 번째 인자는 컬럼에 대한 비교 값입니다.
예를 들어, 아래 에제는 "votes" 컬럼의 값이 "100" 인지 확인하는 쿼리입니다.
$users = DB::table('users')->where('votes', '=', 100)->get();
편리하게 사용하기 위해 단순히 컬럼이 주어진 값과 같은지 확인하려는 경우 값을 두 번째 인자로 "where" 메소드에 직접 전달할 수 있습니다.
$users = DB::table('users')->where('votes', 100)->get();
물론 "where" 구문을 사용할 때 다양한 다른 연산자를 사용할 수 있습니다.
$users = DB::table('users')
->where('votes', '>=', 100)
->get();
$users = DB::table('users')
->where('votes', '<>', 100)
->get();
$users = DB::table('users')
->where('name', 'like', 'T%')
->get();
"where" 메소드에 조건을 배열로 전달할 수 있습니다.
$users = DB::table('users')->where([
['status', '=', '1'],
['subscribed', '<>', '1'],
])->get();
"where" 조건을 함께 연결하고 "or" 구문을 쿼리에 추가할 수 있습니다. "orWhere" 메소드는 "where" 메소드와 동일한 인자를 받습니다.
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
"whereBetween" 메소드는 컬럼의 값이 두 값 사이에 있는지 확인합니다.
$users = DB::table('users')
->whereBetween('votes', [1, 100])->get();
"whereNotBetween" 메소드는 컬럼의 값이 두 값 사이 밖에 있는지 확인합니다.
$users = DB::table('users')
->whereNotBetween('votes', [1, 100])
->get();
"whereIn" 메소드는 주어진 컬럼의 값이 배열에 포함되어 있는지 확인합니다.
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
"whereNotIn" 메소드는 주어진 컬럼의 값이 배열에 포함되어 있지 않는지 확인합니다.
$users = DB::table('users')
->whereNotIn('id', [1, 2, 3])
->get();
"whereNull" 메소드는 주어진 컬럼의 값이 "NULL"인지 확인합니다.
$users = DB::table('users')
->whereNull('updated_at')
->get();
"whereNotNull" 메소드는 컬럼의 값이 "NULL"이 아닌지 확인합니다.
$users = DB::table('users')
->whereNotNull('updated_at')
->get();
"whereDate" 메소드를 사용하여 컬럼의 값을 날짜와 비교할 수 있습니다.
$users = DB::table('users')
->whereDate('created_at', '2016-12-31')
->get();
"whereMonth" 메소드를 사용하여 특정 연도의 특정 월과 컬럼값을 비교할 수 있습니다.
$users = DB::table('users')
->whereMonth('created_at', '12')
->get();
"whereDay" 메소드를 사용하여 특정 날짜와 컬럼의 값을 비교할 수 있습니다.
$users = DB::table('users')
->whereDay('created_at', '31')
->get();
"whereYear" 메소드는 특정 연도와 컬럼의 값을 비교하는데 사용할 수 있습니다.
$users = DB::table('users')
->whereYear('created_at', '2016')
->get();
"wehreColumn" 메소드를 사용하여 두 컬럼이 같은지 확인할 수 있습니다.
$users = DB::table('users')
->whereColumn('first_name', 'last_name')
->get();
메소드에 비교 연션자를 추가할 수 있습니다.
$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
"whereColumn" 메소드는 여러 조건의 배열을 전달할 수 있습니다. 이러한 조건은 "and" 연산자를 사용하여 연결됩니다.
$users = DB::table('users')
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at']
])->get();
경우에 따라 "where exists" 구문이나 중첩된 매개변수 그룹과 같은 고급 "where" 구문을 만들 수 있습니다. 라라벨 쿼리빌더는 이것도 처리할 수 있으며 시작하려면 괄호 안의 그룹 제약 조건의 예제를 살펴 보겠습니다.
DB::table('users')
->where('name', '=', 'John')
->orWhere(function ($query) {
$query->where('votes', '>', 100)
->where('title', '<>', 'Admin');
})
->get();
위 예제를 보시면 "Closure"를 "orWhere" 메소드에 전달하면 쿼리 빌더가 제약 그룹을 시작하도록 지시합니다. "Closure"는 괄호 그룹에 포함되어야 하는 제약 조건을 설정하는데 사용할 수 있는 쿼리 빌더 인스턴스를 받습니다. 위의 예제는 다음 SQL을 생성합니다.
select * from users where name = 'John' or (votes > 100 and title <> 'Admin')
"whereExists" 메소드를 사용하면 "where Exists" SQL 구문을 작성할 수 있습니다. "whereExists" 메소드는 "Closure" 인자를 받습니다. 해당 인수는 "exists" 구문내에 배치되어야 하는 쿼리를 정의할 수 있는 쿼리 빌더 인스턴스를 받습니다.
DB::table('users')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
다음 쿼리는 SQL을 생성합니다.
select * from users
where exists (
select 1 from orders where orders.user_id = users.id
)
라라벨은 또한 JSON 컬럼 유형에 대한 지원을 데이터베이스에서 JSON 컬럼 유형 쿼리를 지원합니다. 현재 여기에는 "MySQL 5.7" 및 "Postgres"가 포함됩니다. "JSON" 컬럼을 쿼리하려면 "->" 연산자를 사용해야 합니다.
$users = DB::table('users')
->where('options->language', 'en')
->get();
$users = DB::table('users')
->where('preferences->dining->meal', 'salad')
->get();
"orderBy" 메소드를 사용하면 주어진 컬럼을 기준으로 쿼리 결과를 정렬할 수 있습니다. "orderBy" 메소드의 첫 번째 인자는 정렬 기준이되는 컬럼이어 하고, 두 번째 인자는 "asc" 또는 "desc"로 정렬 방향을 제어합니다.
$users = DB::table('users')
->orderBy('name', 'desc')
->get();
"latest" 및 "oldest" 메소드를 사용하면 날짜별로 결과를 쉽게 정렬할 수 있습니다. 기본적으로 결과는 "created_at" 컬럼을 기준으로 정렬됩니다. 또는 정렬하려는 컬럼 이름을 전달할 수 있습니다.
$user = DB::table('users')
->latest()
->first();
"inRandomOrder" 메소드는 쿼리 결과를 무작위로 정렬하는데 사용할 수 있습니다. 예를 들어 해당 메소드를 사용하여 임의의 사용자를 가져올 수 있습니다.
$randomUser = DB::table('users')
->inRandomOrder()
->first();
"groupBy" 및 "having" 메소드를 사용하여 쿼리 결과를 그룹화할 수 있습니다. "having" 메소드의 시그니처는 "where" 메소드의 비슷합니다.
$users = DB::table('users')
->groupBy('account_id')
->having('account_id', '>', 100)
->get();
"havingRaw" 메소드는 "having" 구문의 값으로 raw 문자열을 설정할 수 있습니다. 예를 들어, 매출 금액이 "$2,500" 달러 이상인 모든 부서를 찾을 수 있습니다.
$users = DB::table('orders')
->select('department', DB::raw('SUM(price) as total_sales'))
->groupBy('department')
->havingRaw('SUM(price) > 2500')
->get();
쿼리에서 반환되는 결과 수를 제한하거나 쿼리에서 주어진 결과 수를 건너 뛰려면 "skip" 및 "take" 메소드를 사용할 수 있습니다.
$users = DB::table('users')->skip(10)->take(5)->get();
또는 "limit" 및 "offset" 메소드를 사용할 수 있습니다.
$users = DB::table('users')
->offset(10)
->limit(5)
->get();
때로는 다른 것이 참일 때만 쿼리에 "when" 쿼리에 적용할 수 있습니다. 예를 들어 주어진 입력 값이 들어오는 요청에 있는 경우에만 "where" 구문을 적용할 수 있습니다. "when" 메소드를 사용하여 이를 수행할 수 있습니다.
$role = $request->input('role');
$users = DB::table('users')
->when($role, function ($query) use ($role) {
return $query->where('role_id', $role);
})
->get();
"when" 메소드는 첫 번째 매개변수가 "true"일 때 지정된 "Closure(클로저)"만 실행합니다. 첫 번째 인자가 "false"이면 "Closure"가 실행되지 않습니다.
"when" 메소드에 세 번째 인자로 다른 "Closure"를 전달할 수 있습니다. 해당 클로저는 첫 번째 인자가 "false"로 평가되면 실행됩니다. 해당 기능을 사용하는 방법을 설명하기 위해 이 기능을 사용하여 쿼리의 기본 정렬을 구성할 수 있습니다.
$sortBy = null;
$users = DB::table('users')
->when($sortBy, function ($query) use ($sortBy) {
return $query->orderBy($sortBy);
}, function ($query) {
return $query->orderBy('name');
})
->get();
쿼리 빌더는 데이터베이스 테이블에 레코드를 삽입하기 위해 "insert" 메소드를 제공합니다. "insert" 메소드는 컬럼 이름과 값의 배열을 허용합니다.
DB::table('users')->insert(
['email' => 'john@example.com', 'votes' => 0]
);
한 번의 호출로 여러 개의 레코드를 테이블에 "insert" 하여 배열의 배열을 전달하여 삽입할 수 있습니다. 각 배열은 테이블에 삽입할 행을 나타냅니다.
DB::table('users')->insert([
['email' => 'taylor@example.com', 'votes' => 0],
['email' => 'dayle@example.com', 'votes' => 0]
]);
테이블에 "Auto incrementing(자동 증가)" ID가 있는 경우 "insertGetId" 메소드를 사용하여 레코드를 삽입한 다음 ID를 검색합니다.
$id = DB::table('users')->insertGetId(
['email' => 'john@example.com', 'votes' => 0]
);
"PostgreSQL"을 사용할 때 "insertGetId" 메소드를 "auto incrementing" 컬럼의 이름이 "id"가 될 것으로 예상됩니다. 다른 "sequence"에서 ID를 검색하려면 시퀸스 이름을 두 번째 인자로 "insertGetId" 메소드에 전달할 수 있습니다.
물론 데이터베이스에 레코드를 삽입하는 것 외에도 쿼리 빌더 "update" 메소드를 사용하여 기존 레코드를 업데이트할 수 있습니다. "insert" 메소드와 마찬가지로 "update" 메소드는 업데이트할 컬럼을 포함하는 컬럼 및 깞 쌍의 배열을 받습니다. "where" 절을 사용하여 "update" 쿼리를 제한할 수 있습니다.
DB::table('users')
->where('id', 1)
->update(['votes' => 1]);
JSON 컬럼을 업데이트할 때 "->" 구문을 사용하여 JSON 개체의 적절한 키에 액세스할 수 있습니다. 해당 작업은 JSON 컬럼을 지원하는 데이터베이스에서만 사용가능합니다.
DB::table('users')
->where('id', 1)
->update(['options->enabled' => true]);
또한 쿼리 빌더는 주어진 컬럼의 값을 늘리거나 줄이는 편리한 방법을 제공합니다. 단순히 단축키이며, "update" statement을 수동으로 작성하는 것보다 더 표현적이로 간결한 인터페이스를 제공합니다.
이 두 방법 모두 최소한 하나의 인자 (수정할 컬럼)을 허용합니다. 컬럼이 증가하거나 감소되어야 하는 양을 제어하기 위해 두 번째 인자가 선택적으로 전달될 수 있습니다.
DB::table('users')->increment('votes');
DB::table('users')->increment('votes', 5);
DB::table('users')->decrement('votes');
DB::table('users')->decrement('votes', 5);
작업 중에 업데이트할 추가 컬럼을 지정할 수 있습니다.
DB::table('users')->increment('votes', 1, ['name' => 'John']);
쿼리 빌더는 "delete" 메소드를 통하여 테이블에서 레코드를 삭제할 수 있습니다 "delete" 메소드를 호출하기 전에 "where" 구문을 추가하여 "delete" 구문을 제한할 수 있습니다.
DB::table('users')->delete();
DB::table('users')->where('votes', '>', 100)->delete();
모든 행을 제거하고 auto incrementing ID를 0으로 재설정하는 작업을 "truncate method"를 사용하여 처리할 수 있습니다.
DB::table('users')->truncate();
쿼리 빌더에서는 "select" 구문에 "pessimistic locking"을 수행 하는데 도움이 되는 몇가지 함수도 포함되어 있습니다. "share lock"으로 구문을 실행하려면 쿼리에서 "sharedLock" 메소드를 사용할 수 있습니다. "shared lock"은 트랜잭션이 커밋될 때 까지 선택한 행이 수정되는 것을 방지합니다.
DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
또는 "lockForUpdate" 메소드를 사용할 수 있으며, "for update" 잠금은 행이 수정되거나 shared lock으로 선택되는 것을 방지합니다.
****