DartでMySQLを操作した話


### 初めに
大学の研究でDartを触っているので、この機会にデータベースとの連携を練習することにした。
著者はDB操作の経験が乏しいので、手探りで進めています。
アドバイスや注意点があれば教えていただけると幸いです。

本記事でしているユーザ名やパスワードは全て仮のものです。
__実行環境__

||version|
:---|:---|
Ubuntu|Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-112-generic x86_64)|
MySQL|mysql  Ver 8.0.28 for macos12.2 on x86_64 (Homebrew)|
Dart|Dart VM version: 2.7.1 (Unknown timestamp) on "linux_x64"|

### 1. UbuntuでDartを実行できるようにする
```
$ sudo sh -c 'wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
$ sudo sh -c 'wget -qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
$ sudo apt-get update
$ sudo apt-get install dart
```
```
$ dart --version
Dart VM version: 2.7.1 (Unknown timestamp) on "linux_x64"
```
以前は```pub```コマンドを使用するためにパスを通す必要があったが、
現在は```dart pub```で実行するため不要となった。

####  実行できるか確認
```dart:~/Desktop/test.dart
void main() {
  print('hello world');
}
```
ローカルでtest.dartを作成し、サーバに転送
```
// scp コピー元ファイル ユーザ名@リモート・ホスト名:/リモート先のPATH
 
$ scp ~/Desktop/test.dart user@ホスト名:/home/user/public_html
```

```
$ dart test.dart
hello world 
```

### 2. MySQL関連のセッティング
現状：サーバにMySQLはインストールされているが、自分用のユーザアカウントは作られていない

#### 2-1. ユーザの作成と権限の付与
```
// rootでログイン
$ su

// MySQL実行
$ mysql

// 先に今回のテストDBを作成
mysql> CREATE DATABASE test_db;

//ユーザの作成
mysql> CREATE USER test_user@localhost IDENTIFIED WITH mysql_native_password BY 'password'

// test_dbを利用する権限の設定
mysql> GRNT ALL ON test_db.* TO test_user@localhost;
```
上記では、仮のユーザ名と仮のパスワードを記述しています。
MySQLにはパスワードポリシーというものがあり簡単なパスワードを設定すると```ERROR 1819 (HY000)```というエラーが出てしまうので、実際に作成するときはもっと複雑にする必要があります。
[Mysql 5.7* パスワードをPolicyに合わせるとめんどくさい件について](https://qiita.com/keisukeYamagishi/items/d897e5c52fe9fd8d9273)

#### 2-2. 作成したユーザでログイン
```
// MySQL終了
mysql> exit

// rootからログアウト
$ exit

// 作成したユーザでログイン
// mysql -u ユーザ名　-h ホスト名 -p
mysql -u test_user -h localhost -p

// パスワードの入力
password

// テーブルの作成
mysql> CREATE TABLE test_db.test_table(
mysql> id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
mysql> contents VARCHAR(10)
mysql> );

// データを追加
mysql> INSERT INTO test_table VALUES(1, 'test')

// データの取得
mysql> SELECT * FROM test_table
```
```AUTO_INCREMENT```:自動インクリメント
```NOT NULL```:NULLを許容しない
```PRIMARY KEY```:プライマリーキー（主キー）に設定
とりあえずDBの作成は成功してそうなのでこれをDartプログラムで操作する。

### 3. DartでMySQLに接続&SQL文でデータを取得
[mysql1](https://pub.dev/packages/mysql1/example)パッケージを使用。
再度ローカルでプログラムを作成し、サーバに送ります。
```
$ mkdir ~/Desktop/test_mysql
$ cd ~/Desktop/test_mysql
$ touch mysql1.dart
$ touch pubspec.yaml

// mysql1パッケージのインストール
$ dart pub add mysql1
$ dart pub get
```
```dart:~/Desktop/test_mysql/mysql.dart
import 'package:mysql1/mysql1.dart';
import 'dart:async';

Future<void> main() async {
  final conn = await MySqlConnection.connect(ConnectionSettings(
      host: 'localhost',
      port: 3306,,
      user: 'test_user',
      db: 'test_db',
      password: 'password'));

  var results = await conn.query('SELECT * FROM test_table');
  for (var row in results) {
    print('id: ${row[0]} contents: ${row[1]}');
  }
  await conn.close();
}
```
```dart:~/Desktop/test_mysql/pubspec.yaml
name: test_mysql
description: test sql
publish_to: 'none'

environment:
  sdk: ">=2.7.0 <3.0.0"
dependencies: {mysql1: ^0.19.2}
```
#### 4. サーバに転送
```
// scp -r コピー元ディレクトリ ユーザ名@リモート・ホスト名:/リモート先のPATH
 
$ scp -r ~/Desktop/test_mysql/ user@ホスト名:/home/user/public_html
```

#### 5. pub getでパッケージをサーバ側でもインストール
```
$ cd /public_html/test_mysql/
$ dart pub get
$ dart mysql.dart
id: 1 contents: test
```


### 6. 終わりに
今回はDartでMySQLを操作しました。
今後Dartからの追加や削除、もっと複雑な取得も行いたいと思います。

### 7. 参考文献
- [Mac および Ubuntu で Dart をインストールする方法](https://obel.hatenablog.jp/entry/20191118/1574087400)
- [MySQLでユーザーアカウントの権限を制御する](https://mugendennou.net/mysql/grantuseracc/)
- [【scp】Linuxでリモート・ローカル間でファイルを転送するコマンド](https://uxmilk.jp/50946)
- [Mysql 5.7* パスワードをPolicyに合わせるとめんどくさい件について](https://qiita.com/keisukeYamagishi/items/d897e5c52fe9fd8d9273)