Laravel5.6 DBアクセス
公開日:2018-06-16 更新日:2020-03-16
[Laravel5]
1. 概要
Laravel5.6 で MySQL による DB アクセスを行います。
プロジェクトは前回作成したものを使用します。
プロジェクトは前回作成したものを使用します。
2. データベースの作成
以前作成した cmd_for_php.bat でコマンドプロンプトを開き、以下のコマンドを実行して DB を作成します。
mysql -u root -p
CREATE DATABASE db_laravel DEFAULT CHARACTER SET utf8mb4;
3. .env の修正
laravel のプロジェクト直下にある .env を環境に合わせて変更します。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_larave
DB_USERNAME=root
DB_PASSWORD=root
4. テーブルの作成
以下のコマンドを実行します。
今回は、2018_06_15_023558_create_articles_table.php と言うファイルが作成されました。
この段階では、まだ DB にテーブルは作成されていません。
migrations 配下には、作成されたファイル以外に create_users_table.php、create_password_resets_table.php と言うファイルも入っています。
create_users_table.php のソースを見てみます。
create_users_table.php抜粋
create_articles_table.php には id とタイムスタンプしか項目がないため、data を追加します。
create_articles_table.php抜粋
up() を動かすには、以下のコマンドを実行します。
実行すると、以下のエラーが発生しました。
テーブルを確認します。
DB のエンコーディングを utf8mb4 にしたため、255文字 * 4 = 1020バイトとなり、767バイトを越えています。
「$table->string('email')->unique();」が email の項目に該当しますが、ここで文字数が指定できないか調べます。
$table は Blueprint で、use より
string() の定義は、
以下のように191(191 * 4 = 764 で 767以下)を指定します。
エラー
create_password_resets_table.php の email も同様に 191 を指定します。
テーブルを削除して、もう1度 migrate を実行します。
エラーが出なくなりました。
テーブルを確認すると、migrations、articles、password_resets、users の4つのテーブルが作成されました。
articles テーブルは以下のようになります。
また、timestamps() は、created_at と updated_at になるようです。
migrations テーブルには、migrate したファイル名の一部が入っています。
ここに入っているものは、次回 migrate した時に、対象外となります。
試しに migrations はそのままにして、articles テーブルを削除して migrate すると、
「Nothing to migrate.」と表示され、テーブルが作成されなくなります。
また、migrations テーブルから articles のレコードを削除して、migrate すると、
今度は articles テーブルが作成されます。
なお、以下のコマンドを実行すると、全て再作成してくれます。
cd C:\pleiades\xampp\htdocs\laravel_test
php artisan make:migration create_articles_table
実行すると、laravel_test/database/migrations 配下に、ファイルが作成されます。今回は、2018_06_15_023558_create_articles_table.php と言うファイルが作成されました。
この段階では、まだ DB にテーブルは作成されていません。
migrations 配下には、作成されたファイル以外に create_users_table.php、create_password_resets_table.php と言うファイルも入っています。
create_users_table.php のソースを見てみます。
create_users_table.php抜粋
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
up() でテーブル定義をしています。create_articles_table.php には id とタイムスタンプしか項目がないため、data を追加します。
create_articles_table.php抜粋
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('data1'); //追加
$table->string('data2'); //追加
$table->timestamps();
});
}
up() を動かすには、以下のコマンドを実行します。
php artisan migrate
実行すると、以下のエラーが発生しました。
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))
email を unique にしようしたが、サイズが大きすぎるためエラーとなったようです。テーブルを確認します。
MariaDB [db_laravel]> desc users;
+----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+----------------+------------------+------+-----+---------+----------------+
email は varchar(255) となっています。DB のエンコーディングを utf8mb4 にしたため、255文字 * 4 = 1020バイトとなり、767バイトを越えています。
「$table->string('email')->unique();」が email の項目に該当しますが、ここで文字数が指定できないか調べます。
$table は Blueprint で、use より
vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php
だとわかります。string() の定義は、
public function string($column, $length = null)
となっているため、2番目の引数に文字列長を指定できそうです。以下のように191(191 * 4 = 764 で 767以下)を指定します。
$table->string('email', 191)->unique();
テーブルが作成されているため、テーブルを削除してもう1度以下のコマンドを実行します。php artisan migrate
エラー
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `password_resets` add index `password_resets_email_index`(`email`))
最初に出たエラーと似ていますが、今度は他の項目が文字数の制限に引っかかっているようです。create_password_resets_table.php の email も同様に 191 を指定します。
テーブルを削除して、もう1度 migrate を実行します。
エラーが出なくなりました。
テーブルを確認すると、migrations、articles、password_resets、users の4つのテーブルが作成されました。
articles テーブルは以下のようになります。
MariaDB [db_laravel]> desc articles;
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| data1 | varchar(255) | NO | | NULL | |
| data2 | varchar(255) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+------------+------------------+------+-----+---------+----------------+
追加した data が入っています。また、timestamps() は、created_at と updated_at になるようです。
migrations テーブルには、migrate したファイル名の一部が入っています。
ここに入っているものは、次回 migrate した時に、対象外となります。
試しに migrations はそのままにして、articles テーブルを削除して migrate すると、
「Nothing to migrate.」と表示され、テーブルが作成されなくなります。
また、migrations テーブルから articles のレコードを削除して、migrate すると、
今度は articles テーブルが作成されます。
なお、以下のコマンドを実行すると、全て再作成してくれます。
php artisan migrate:refresh
3. データの追加
1. シーダーの作成
以下のコマンドを実行します。
ArticlesTableSeeder.php を以下のように修正します。
次に、ArticlesTableSeeder.php と同じ階層にある database/seeds/DatabaseSeeder.php を修正します。
php artisan make:seeder ArticlesTableSeeder
実行すると、database/seeds/ArticlesTableSeeder.php が作成されます。ArticlesTableSeeder.php を以下のように修正します。
<?php
use Illuminate\Database\Seeder;
class ArticlesTableSeeder extends Seeder
{
public function run()
{
DB::table('articles')->truncate(); //全データの削除
DB::table('articles')->insert([
[
'data1' => 'aaa1',
'data2' => 'aaa2'
],
[
'data1' => 'bbb1',
'data2' => 'bbb2'
],
[
'data1' => 'ccc1',
'data2' => 'ccc2'
],
]);
}
}
次に、ArticlesTableSeeder.php と同じ階層にある database/seeds/DatabaseSeeder.php を修正します。
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(ArticlesTableSeeder::class); //追加
}
2. シーダーの実行
以下のコマンドを実行します。
以下のエラーが出ました。
クラス名、ファイル名、パスに問題がなくても上記エラーが出る場合は、以下のコマンドを実行します。
もう1度以下のコマンドを実行します。
エラーが出なければ、articles テーブルにデータが追加されています。
php artisan db:seed
以下のエラーが出ました。
ReflectionException : Class ArticlesTableSeeder does not exist
クラス名、ファイル名、パスに問題がなくても上記エラーが出る場合は、以下のコマンドを実行します。
composer dump-autoload
これで vendor/composer 配下の autoload_classmap.php と autoload_static.php にクラスが登録されて、オートロードできるようになります。もう1度以下のコマンドを実行します。
php artisan db:seed
エラーが出なければ、articles テーブルにデータが追加されています。
MariaDB [db_laravel]> select * from articles;
+----+-------+-------+------------+------------+
| id | data1 | data2 | created_at | updated_at |
+----+-------+-------+------------+------------+
| 1 | aaa1 | aaa2 | NULL | NULL |
| 2 | bbb1 | bbb2 | NULL | NULL |
| 3 | ccc1 | ccc2 | NULL | NULL |
+----+-------+-------+------------+------------+
3. DBアクセス
1. モデムの作成
以下のコマンドを実行します。
初めから User.php と言うファイルも入っています。
php artisan make:model Article
実行すると、app/Article.php が作成されます。初めから User.php と言うファイルも入っています。
2. データの取得
app/Http/Controllers/TestController.php を以下のように修正します。
routes/web.php抜粋
出力されたHTMLのソースを確認すると、articles テーブルのデータが取得できていることがわかります。
Users テーブルでも試してみます。今回はシーダーを使わずに直接SQLでデータを入れます。
コンストラクタの引数を Article から User に変更して以下のようにすると、users テーブルの値が取得できます。
どうやら、コンストラクタの引数の型で、入ってくるデータが変わるようです(コンストラクタインジェクション)。
以下のように、引数を複数入れることも可能です。
また、メソッドでも同様に行えます(メソッドインジェクション)。
以下のようにすると、引数で取得しなくてもデータが取得できます。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Article;
use App\User;
class TestController extends Controller
{
protected $article;
public function __construct(Article $article)
{
$this->article = $article;
}
public function test() {
$list = $this->article->all();
var_dump($list[0]->id);
var_dump($list[0]->data1);
var_dump($list[0]->data2);
//$a = "Hello";
//return view('test')->with(compact('a'));
}
}
routes/web.php抜粋
Route::get('/test/', 'TestController@test');
http://localhost/laravel_test/public/test/ にアクセスします。出力されたHTMLのソースを確認すると、articles テーブルのデータが取得できていることがわかります。
Users テーブルでも試してみます。今回はシーダーを使わずに直接SQLでデータを入れます。
insert into users (name, email, password) values ('aaa', 'aaa@aaa', 'pass1');
insert into users (name, email, password) values ('bbb', 'bbb@bbb', 'pass2');
コンストラクタの引数を Article から User に変更して以下のようにすると、users テーブルの値が取得できます。
var_dump($list[0]->id);
var_dump($list[0]->name);
var_dump($list[0]->email);
var_dump($list[0]->password);
どうやら、コンストラクタの引数の型で、入ってくるデータが変わるようです(コンストラクタインジェクション)。
以下のように、引数を複数入れることも可能です。
public function __construct(Article $article, User $user)
また、メソッドでも同様に行えます(メソッドインジェクション)。
public function test(Article $article, User $user) {
$list1 = $article->all();
$list2 = $user->all();
var_dump($list1[0]->data1);
var_dump($list2[0]->name);
}
Laravel の DI コンテナとしての機能だそうです。以下のようにすると、引数で取得しなくてもデータが取得できます。
use DB;
:
public function test() {
$articles = DB::table('articles')->get();
var_dump($articles[0]->data1);
}
3. データの取得
最初の1レコードを取得します。
TestController.php抜粋
条件を指定して取得します。
指定した項目の値だけ取得します。
TestController.php抜粋
public function test() {
$article = DB::table('articles')->first();
var_dump($article->data1);
}
条件を指定して取得します。
public function test() {
$article = DB::table('articles')->where('data1', 'aaa1')->first();
var_dump($article->data1);
}
指定した項目の値だけ取得します。
$data2 = DB::table('articles')->where('data1', 'aaa1')->value('data2');
var_dump($data2);
などなど。4. データの更新
データを追加します。
データを追加します。
これは、database/seeds/ArticlesTableSeeder.php のデータ追加方法と同じです。
データを更新します。
データを削除します。
$data = [
'data1' => 'abc',
'data2' => 'def'
];
$article->insert($data);
データを追加します。
これは、database/seeds/ArticlesTableSeeder.php のデータ追加方法と同じです。
$data = [
'data1' => 'xxx',
'data2' => 'yyy'
];
DB::table('articles')->insert($data);
データを更新します。
DB::table('articles')->where('data1', 'xxx')->update(['data1' => 'zzz']);
データを削除します。
DB::table('articles')->where('data1', 'zzz')->delete();
などなど。