LaravelによるOracleからMySQLへのデータ移行

この記事は、Laravelを使用してORACLEに接続しMySQLにデータ転送を行うまでの手順書です。

# 事前準備
以下の動作環境を docker-composer 等で事前に用意します。

- PHP7.1以降, Composer の動く環境
- Oracleの動く環境

OracleとPHPが動作する docker-composer は以下に置いてあります。
https://github.com/bluemooninc/OraclePHP

### Laravel をインストールする。

```
composer global require "laravel/installer"
```
### Migrationプロジェクト作成

```
cd ~
laravel new migration
cd migration
```

### OCI8ドライバをインストールする

```
composer require yajra/laravel-oci8
```

データベースのconfigにOracleへの接続情報を記載する。
以下は環境変数で設定する

- ORACLE_URL -> OracleデータベースのURL
- ORACLE_PDB -> 接続先DB名
- ORACLE_SID -> SID
- ORACLE_USER -> ユーザー名
- ORACLE_PWD -> パスワード

```php
## config/database.php

        'oracle' => [
            'driver'    => 'oracle',
            'host'      => env('ORACLE_URL', '127.0.0.1'),
            'port'      => '1521',
            'database'  => env('ORACLE_PDB',''),
            'service_name' => env('ORACLE_SID',''),
            'username'  => env('ORACLE_USER',''),
            'password'  => env('ORACLE_PWD',''),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],
```


### ORCLE接続用のモデルを作成する

```
php artisan make:model Models/ORA_TEST
```

モデルに接続情報を記載します。

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ORA_TEST extends Model
{
    protected $connection = 'oracle';
    protected $table = 'TEST';
}

```
### MySQL側に転送先のテーブルを作成する

- マイグレーションファイルを生成します。

 database/migrationsフォルダに yyyy_mm_dd_hhiiss_create_test_table.php というファイルが生成される。

```
php artisan make:migration create_test_table
```

- マイグレーションの中身を編集します。

```php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTestTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('test', function (Blueprint $table) {
            $table->increments('id'); // autoincrimentが必須です
            $table->string('name', 50);
            $table->timestamp	('created_at')->default(DB::raw('CURRENT_TIMESTAMP')); // ORMで必須です
            $table->timestamp	('updated_at')->default(DB::raw('CURRENT_TIMESTAMP')); // ORMで必須です
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('test');
    }
}
```
- マイグレーション実行

```
php artisan migrate
```

### MySQL側のモデルを作成する

テーブルの用意ができたら、データ転送用のモデルを作成します。

```
php artisan make:model Models/test_table
```

接続情報を記述します。

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Tests extends Model
{
    protected $connection = 'mysql';
    protected $table = 'test';
    protected $fillable= array('name');

    /**
     * MySQLテーブルへ保存
     */
    public static function ora_to_mysql(array $ora_arr) {
        // Userオブジェクトに対する処理
        $t = new Tests();
        $t->fill([
            'name' => $ora_arr['name'],
        ]);
        $t->save();
    }
}
```


### データ転送用のコントローラを書く

以下のプログラムはcursorメソッドを使用して１レコード毎にOracleからデータを読み込んでMySQLレコードを追加します。

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\ORA_TEST;
use App\Models\Tests;

class Test_controller extends Controller
{
    public function index()
    {
        foreach (ORA_TEST::query()->cursor() as $test) {
            $ora_arr = $teset->toArray();
            Tests::ora_to_mysql($ora_arr);
        }
    }
}
```

### routes設定

最後にwebからコントローラを動作させるようにします。

routes/web.php を編集します。

```php
Route::get('/index', 'Ttest_controller@index');
```