[Blazor] Blazor + Mysql
페이지 정보
작성자 sbLAB 댓글 0건 조회 7,180회 작성일 21-03-20 18:31본문
1. BlazorServer 웹프로젝트 생성
[DBLibrary]
2. mysql 연동에 사용할 DBLibrary 프로젝트(Class Library) 생성
- Dapper(2.0.78)
- Mysql.Data(8.0.23) 설치(nuget)
3. 디비 접근 구조 인터페이스 IDbAccess 생성
namespace DBLibrary { public interface IDbAccess { Task<List<T>> LoadData<T, U>(string sql, U parameters, string connectionString); Task SaveData<T>(string sql, T parameters, string connectionString); } }
4. DB 접근 구조(IDbAccess)에 대한 인터페이스 구현(MysqlAccess)
namespace DBLibrary { public class MysqlAccess : IDbAccess { public async Task<List<T>> LoadData<T, U>(string sql, U parameters, string connectionString) { using (IDbConnection connection = new MySqlConnection(connectionString)) { var rows = await connection.QueryAsync<T>(sql, parameters); return rows.ToList(); } } public Task SaveData<T>(string sql, T parameters, string connectionString) { using (IDbConnection connection = new MySqlConnection(connectionString)) { return connection.ExecuteAsync(sql, parameters); } } }
5. BlazorServer 웹프로젝트 Dependencies에 DBLibrary 연결등록
6. [Shared] -> appsettings.json 에 mysql DB정보 세팅
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionStrings": { "default": "Server=localhost;Port=3306;database=blazor;user id=blazor;password=1111;charset=utf8" //"default": "Server=localhost;Port=3306;database=blazor;user id=blazor;password=1111;OldGuids=True;charset=utf8" } }
7. BlazorServer 프로젝트 Startup.cs 에서 ConfigureServices 부품박스(컨테이너)에 부품사용등록
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddServerSideBlazor(); services.AddSingleton<IDbAccess, MysqlAccess>(); }
8. Blazor People.razor 페이지에서 사용
[데이타 모델 구조]
namespace BlazorServer.Models { public class PersonModel { public string Name { get; set; } public string Point { get; set; } } }
[ razor 페이지에 부품 연결(inject) 사용]
@page "/people" @using DBLibrary @using BlazorServer.Models @using Microsoft.Extensions.Configuration @inject IDbAccess _data @inject IConfiguration _config <h3>People</h3> <button class="btn btn-primary" @onclick="InsertData">Insert</button> <button class="btn btn-warning" @onclick="UpdateData">Update</button> <button class="btn btn-danger" @onclick="DeleteData">Delete</button> @if (people == null) { <p><em>Loading...</em></p> } else { @foreach (var p in people) { <p> @p.Name @p.Point </p> } }
@code { List<PersonModel> people; private async Task InsertData() { string sql = "insert into people (Name, Point) values (@Name, @Point);"; await _data.SaveData(sql, new { Name = "Billy", Point = "300" }, _config.GetConnectionString("default")); await OnInitializedAsync(); } private async Task UpdateData() { string sql = "update people set Name = @Name where Point = @Point"; await _data.SaveData(sql, new { Name = "Timothy", Point = "100" }, _config.GetConnectionString("default")); await OnInitializedAsync(); } private async Task DeleteData() { string sql = "delete from people where Point = @Point"; await _data.SaveData(sql, new { Point = "70" }, _config.GetConnectionString("default")); await OnInitializedAsync(); } protected override async Task OnInitializedAsync() { string sql = "select * from people"; people = await _data.LoadData<PersonModel, dynamic>(sql, new { }, _config.GetConnectionString("default")); } }
[People 페이지를 partial behind code로 만든다면 아래와 같다. 분리가 프로그램 같아서 좋다.]
[People.razor]
@page "/people" <h3>People</h3> <button class="btn btn-primary" @onclick="InsertData">Insert</button> <button class="btn btn-warning" @onclick="UpdateData">Update</button> <button class="btn btn-danger" @onclick="DeleteData">Delete</button> @if (people == null) { <p><em>Loading...</em></p> } else { @foreach (var p in people) { <p> @p.Name @p.Point </p> } }
[People.razor.cs]
using BlazorServer.Models; using DBLibrary; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Configuration; using System.Collections.Generic; using System.Threading.Tasks; namespace BlazorServer.Pages { public partial class People { [Inject] public IDbAccess _data { get; set; } [Inject] public IConfiguration _config { get; set; } List<PersonModel> people; private async Task InsertData() { string sql = "insert into people (Name, Point) values (@Name, @Point);"; await _data.SaveData(sql, new { Name = "Billy", Point = "300" }, _config.GetConnectionString("default")); await OnInitializedAsync(); } private async Task UpdateData() { string sql = "update people set Name = @Name where Point = @Point"; await _data.SaveData(sql, new { Name = "Timothy", Point = "100" }, _config.GetConnectionString("default")); await OnInitializedAsync(); } private async Task DeleteData() { string sql = "delete from people where Point = @Point"; await _data.SaveData(sql, new { Point = "70" }, _config.GetConnectionString("default")); await OnInitializedAsync(); } protected override async Task OnInitializedAsync() { string sql = "select * from people"; people = await _data.LoadData<PersonModel, dynamic>(sql, new { }, _config.GetConnectionString("default")); } } }
//위 소스 개선할 점 -> MysqlAccess 변수명을 DbAccess 로 변경필요
MysqlAccess.cs ->DbAccess.cs 로 파일명 변경
[DbAccess.cs]
public class DbAccess : IDbAccess
[Startup.cs]
services.AddSingleton<IDbAccess, DbAccess>();
[이유]
DI 패턴 목적이 DB종류가 바뀔때 소스 수정을 최소화 하는것인데, MysqlAccess 로 변수명을 결정짓고 있다.
처음부터 DbAccess 로 하고, 만약 DB가 변경된다면 오로지 DbAccess.cs 에서 각 DB연동 로직만 변경하면 된다.
namespace DBLibrary
{
public class DbAccess : IDbAccess
{
public async Task<List<T>> LoadData<T, U>(string sql, U parameters, string connectionString)
{
using (IDbConnection connection = new MySqlConnection(connectionString)) {
var rows = await connection.QueryAsync<T>(sql, parameters);
return rows.ToList();
}
}
public Task SaveData<T>(string sql, T parameters, string connectionString) {
using (IDbConnection connection = new MySqlConnection(connectionString))
{
return connection.ExecuteAsync(sql, parameters);
}
}
}
}
[DI] ?
DI부품박스제어통(컨테이너)한테 부품(클래스)사용등록한다고 알려준다(외부에서 설정값으로 설정)
razor 페이지나 다른 로직에서 사용할때, 개발자가 소스에 부품 클래스 인스턴스를 생성하는
컴파일단계의 로직을 직접만들지 않고,
그 클래스는 [Inject] 하겠다는 표시를 해주면, 실행단계에서 그 클래스의 인스턴스를 알아서 연결(넣어)해준다.
그리고, 그 인스턴스를 이하 로직에서 사용하게된다.
내부에서 _repo 인스턴스 생성하는 경우
[Route("api/commands")]
[ApiController]
public class CommandsController : ControllerBase
{
private readonly MockCommanderRepo _repo = new MockCommanderRepo();
//GET api/commands
[HttpGet]
public ActionResult <IEnumerable<Command>>GetAllCommands()
{
var commandItems = _repo.GetAllCommands();
return OK(commandItems);
}
//GET api/commands/2
[HttpGet("{id}")]
public ActionResult <IEnumerable<Command>>GetCommandById(id);
{
var commandItem = _repo.GetCommandById(id);
return OK(commandItem);
}
}
외부에서 부품사용 등록 후 DI로 넣는 경우(Constructor 로 들어옴)
services.AddScoped<ICommanderRepo, MockCommanderRepo>();
--------------------------------------------------------
[Route("api/commands")]
[ApiController]
public class CommandsController : ControllerBase
{
//private readonly MockCommanderRepo _repo = new MockCommanderRepo();
private readonly ICommanderRepo _repo;
public CommandsController(ICommanderRepo repo){
_repo = repo;
}
//GET api/commands
[HttpGet]
public ActionResult <IEnumerable<Command>>GetAllCommands()
{
var commandItems = _repo.GetAllCommands();
return OK(commandItems);
}
//GET api/commands/2
[HttpGet("{id}")]
public ActionResult <IEnumerable<Command>>GetCommandById(id);
{
var commandItem = _repo.GetCommandById(id);
return OK(commandItem);
}
}
--------------------------------------------------------------
[IDbAccess 인터페이스, DbAccess 클래스 모두 적시] - OK
services.AddSingleton<IDbAccess, DbAccess>();
↓
[Inject]
public IDbAccess _data { get; set; }
_data.*** 사용
[이 게시물은 sbLAB님에 의해 2022-12-22 09:42:42 Web/PHP/API에서 이동 됨]
첨부파일
- ConnectingToMySQLSourceCode.zip (261.4K) 48회 다운로드 | DATE : 2021-03-20 18:38:02
- 이전글[Blazor] Checkbox List 21.04.24
- 다음글[Blazor] .NET Core 3.1 MVC REST API - Full Course 21.03.18
댓글목록
등록된 댓글이 없습니다.