はじめに
MySqlとBlazorをdocker-compose動かしてみたいと思います。
Blazorの開発環境の構築はこちら
ASP.NET Core Blazor のホスティング モデルで構築しています。
ブラウザ側ではWebAssembly ベースの .NET ランタイム(Blazor WebAssembly) が動作してます。
MySqlを読み込ませるコードを追加していきます。
サーバ側のコード
サーバ側にapi/MySql
でアクセスするコントローラを作成します。MySqlにアクセスして、データを取得します。
using BrazorwasmDotNetCoreHostedWithDocker.Shared;
using Microsoft.AspNetCore.Mvc;
using MySql.Data.MySqlClient;
using SqlKata.Compilers;
using SqlKata.Execution;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BrazorwasmDotNetCoreHostedWithDocker.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class MySqlController : ControllerBase
{
[HttpGet]
public async Task<IEnumerable<MySqlData>> Get()
{
MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder
{
Server = "mysql",
Database = "MyDatabase",
UserID = "root",
Password = "root1234",
SslMode = MySqlSslMode.Required,
};
IEnumerable<MySqlData> list = null;
using (MySqlConnection connection = new MySqlConnection(builder.ConnectionString))
{
await connection.OpenAsync();
MySqlCompiler compiler = new MySqlCompiler();
QueryFactory db = new QueryFactory(connection, compiler);
list = db.Query("MyData").Select("Id", "Title", "CreatedAt").Get<MySqlData>();
}
return list;
}
}
}
今回はSqlKataというライブラリを利用しています。
https://sqlkata.com/
内部的にはDapperが使われているようで、データをGetする際にクラスを指定するとちゃんとオブジェクト化してくれました。すごく可読性がよく使いやすそうな印象でした。
クライアント側のコード
/mysql
でアクセスできるようにClient側を修正していきたいと思います。
ナビゲーションにmysql
を追加します。
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
・・・
<li class="nav-item px-3">
<NavLink class="nav-link" href="mysql">
<span class="oi oi-list-rich" aria-hidden="true"></span> MySql
</NavLink>
</li>
</ul>
・・・
</div>
@page "/mysql"
@using BrazorwasmDotNetCoreHostedWithDocker.Shared
@inject HttpClient Http
@code {
private MySqlData[] data;
protected override async Task OnInitializedAsync()
{
data = await Http.GetFromJsonAsync<MySqlData[]>("api/MySql");
}
}
<h1>MySql</h1>
@if (data == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>CreatedAt</th>
</tr>
</thead>
<tbody>
@foreach (var value in data)
{
<tr>
<td>@value.Id</td>
<td>@value.Title</td>
<td>@value.CreatedAt.ToShortDateString()</td>
</tr>
}
</tbody>
</table>
}
共通のコード
using System;
namespace BrazorwasmDotNetCoreHostedWithDocker.Shared
{
public class MySqlData
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime CreatedAt { get; set; }
}
}
docker-composeの設定
version: '3.7'
services:
db:
container_name: mysql
image: mysql
ports:
- "3306:3306"
volumes:
- ./db/mysql_init:/docker-entrypoint-initdb.d
- ./db/mysql_data:/var/lib/mysql
- ./db/mysql_conf/:/etc/mysql/conf.d
environment:
MYSQL_ROOT_PASSWORD: root1234
MYSQL_USER: test
MYSQL_PASSWORD: test1234
command: >
mysqld
--character-set-server=utf8
--collation-server=utf8_unicode_ci
--skip-character-set-client-handshake
app:
container_name: brazor
build:
context: .
dockerfile: Dockerfile
ports:
- "80:80"
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_ENVIRONMENT: Development
で開発者モードにすることができます。
MySqlの設定
ソリューションフォルダの配下に、MySql用のファイルを格納しています(Visual Stadio上で作らない方がいいかもしれません)。
├─db
├─mysql_conf
│ default_authentication.cnf
│
├─mysql_data
│
└─mysql_init
1_create.sql
2_insert.sql
/docker-entrypoint-initdb.d
の下に格納すれば、最初に実行してもらえますので、
docker-compose.yml
の中で、mysql_init
にマウントされるように設定しています。
MyDatabase
というデータベース、そこにMySqlData
というテーブルを作成して、
データをInsertしています。
CREATE DATABASE MyDatabase;
use MyDatabase;
CREATE TABLE MySqlData (
Id INT(11) AUTO_INCREMENT NOT NULL,
Title VARCHAR(64) NOT NULL,
CreatedAt Date NOT NULL,
PRIMARY KEY (id));
use MyDatabase;
INSERT INTO MySqlData (Title, CreatedAt) VALUES ('タイトル1', '2020-10-10');
INSERT INTO MySqlData (Title, CreatedAt) VALUES ('タイトル2', '2020-10-11');
日本語で登録したかったので、docker-compose.yml
の中でutf8になるように設定しています。
mysqld
--character-set-server=utf8
--collation-server=utf8_unicode_ci
--skip-character-set-client-handshake # 強制上書き
起動
docker-compose up --build
http://localhost/mysql
にアクセスして、下記画面が出れば成功です。
その他メモ
コンテナに入るとき
docker-compose exec db bash
MySqlにアクセス
mysql -u root -p