728x90
반응형
SQLKata의 개념과 설치 방법을 알아보자.
공식 문서는 아래에 있다.
SqlKata | SqlKata
fluent SQL query builder, supports SqlServer, MySql, PostgreSql, SQLite, Oracle and Firebird
sqlkata.com
SQLKata
SQLKata는 다양한 데이터베이스 플랫폼에서 SQL 쿼리 작성을 더욱 쉽고 효율적으로 만들어주는 라이브러리이다.
데이터베이스 쿼리 작성 시 보다 직관적이고 편리한 문법을 제공한다.
예를 들어, SELECT 문에서 컬럼을 선택할 때, 별칭을 지정할 수 있다.
WHERE절에서는 다양한 조건문을 쉽게 작성할 수 있다.
IEnumerable<Post> posts = await db.Query("Posts")
.Where("Likes", ">", 10)
.WhereIn("Lang", new [] {"en", "fr"})
.WhereNotNull("AuthorId")
.OrderByDesc("Date")
.Select("Id", "Title")
.GetAsync<Post>();
이런식으로 말이다.
설치
마찬가지로, 터미널에서 명령어를 입력해 SQLKata를 설치해주자.
dotnet add package SqlKata
dotnet add package SqlKata.Execution
사용방법
1. 클래스 정의
public class IDNameValue
{
public int ID { get; set; }
public string Name { get; set; }
public int Value { get; set; }
//결과 확인을 위해
public override string ToString()
{
return $"ID = {ID} Name = {Name} Value = {Value}";
}
}
2. Program.cs 작성
using MySql.Data.MySqlClient;
using SqlKata.Compilers;
using SqlKata.Execution; // MySql.Data 추가
var builder = WebApplication.CreateBuilder(args);
// 1. 연결 문자열 (appsettings.json) 읽기
var connectionString = builder.Configuration.GetConnectionString("Default");
builder.Services.AddScoped<QueryFactory>(sp =>
{
var connection = new MySqlConnection(connectionString);
var compiler = new MySqlCompiler();
var db = new QueryFactory(connection, compiler);
//쿼리 로깅 (어떤 SQL이 나가는지 보고 싶을 때)
db.Logger = complied =>
{
Console.WriteLine($"발행된 SQL");
Console.WriteLine($"SQL: " + complied.Sql);
Console.WriteLine($"Parameters: " + string.Join(",", complied.Bindings));
};
return db;
});
//컨트롤러 사용
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
이 과정을 거치면, QueryFactory를 DI로 받아서 SqlKata 쿼리를 실행할 수 있다.
3. 연습용 컨트롤러 작성 (SqlController.cs)
using Microsoft.AspNetCore.Mvc;
using SqlKata.Execution;
namespace ServerStudy.Controllers
{
[ApiController]
[Route("[controller]")]
public class SQLController : ControllerBase
{
private readonly QueryFactory _db;
public SQLController(QueryFactory db)
{
_db = db;
}
// 1. 테이블 생성 + 샘플 데이터 삽입
[HttpPost("init")]
public async Task<IActionResult> Init()
{
//1.1. 테이블 없으면 생성 (MySql기준)
_db.Statement(@"
CREATE TABLE IF NOT EXISTS IDNameValue(
ID INT PRIMARY KEY AUTO_INCREMENT,
Name VARCHAR(100),
Value INT
);
");
//1.2. 기존 데이터 삭제
await _db.Query("IDNameValue").DeleteAsync();
//1.3. 행 1개 삽입
await _db.Query("IDNameValue").InsertAsync(new { Name = "Hoge1", Value = 101 });
// 1.4. 여러 행 삽입
var rows = new[]
{
new { Name = "Hoge2", Value = 102 },
new { Name = "Hoge3", Value = 103 },
new { Name = "Hoge4", Value = 104 },
};
foreach (var row in rows)
{
await _db.Query("IDNameValue").InsertAsync(row);
}
return Ok("Init done");
}
// 2 전체 조회
[HttpGet("all")]
public async Task<IEnumerable<IDNameValue>> GetAll()
{
var rows = await _db.Query("IDNameValue").GetAsync<IDNameValue>();
return rows;
}
// 3. 업데이트 예제 (ID=4의 Value 변경)
[HttpPost("update")]
public async Task<IActionResult> Update()
{
await _db.Query("IDNameValue")
.Where("ID", 4)
.UpdateAsync(new { Value = 904 });
return Ok("Updated");
}
// 4. 삭제 예제 (ID <= 2 삭제)
[HttpPost("delete")]
public async Task<IActionResult> Delete()
{
await _db.Query("IDNameValue")
.Where("ID", "<=", 2)
.DeleteAsync();
return Ok("Deleted");
}
}
public class IDNameValue
{
public int ID { get; set; }
public string Name { get; set; }
public int Value { get; set; }
//결과 확인을 위해
public override string ToString()
{
return $"ID = {ID} Name = {Name} Value = {Value}";
}
}
}
4. .http 파일을 만들어 테스트
@host = http://localhost:[port]
### 1. 테이블 생성 + 데이터 삽입
POST {{host}}/SQL/init
### 2. 전체 조회
GET {{host}}/SQL/all
### 3. 업데이트 (ID=4 Value를 904로)
POST {{host}}/SQL/update
### 4. 삭제 (ID <= 2 삭제)
POST {{host}}/SQL/delete
### 5. 다시 전체 조회
GET {{host}}/SQL/all
1번부터 차례대로 테스트 해보자.
### 1. 테이블 생성 + 데이터 삽입
POST {{host}}/SQL/init
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain; charset=utf-8
Date: Fri, 05 Dec 2025 01:41:58 GMT
Server: Kestrel
Transfer-Encoding: chunked
Init done

테이블이 잘 생성됐다. 안보인다면, DB에 다시 접속해보자.
### 2. 전체 조회
GET {{host}}/SQL/all
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json; charset=utf-8
Date: Fri, 05 Dec 2025 01:43:53 GMT
Server: Kestrel
Transfer-Encoding: chunked
[
{
"id": 3,
"name": "Hoge1",
"value": 101
},
{
"id": 4,
"name": "Hoge2",
"value": 102
},
{
"id": 5,
"name": "Hoge3",
"value": 103
},
{
"id": 6,
"name": "Hoge4",
"value": 104
}
]
정상적으로 조회도 잘 되었다.
### 3. 업데이트 (ID=4 Value를 904로)
POST {{host}}/SQL/update
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain; charset=utf-8
Date: Fri, 05 Dec 2025 01:44:40 GMT
Server: Kestrel
Transfer-Encoding: chunked
Updated
===========================================
### 2. 전체 조회
GET {{host}}/SQL/all
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json; charset=utf-8
Date: Fri, 05 Dec 2025 01:45:05 GMT
Server: Kestrel
Transfer-Encoding: chunked
[
{
"id": 3,
"name": "Hoge1",
"value": 101
},
{
"id": 4,
"name": "Hoge2",
"value": 904
},
{
"id": 5,
"name": "Hoge3",
"value": 103
},
{
"id": 6,
"name": "Hoge4",
"value": 104
}
]
값도 정상적으로 수정되었고,
### 4. 삭제 (ID <= 2 삭제)
POST {{host}}/SQL/delete
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain; charset=utf-8
Date: Fri, 05 Dec 2025 01:45:26 GMT
Server: Kestrel
Transfer-Encoding: chunked
Deleted
=================================
### 2. 전체 조회
GET {{host}}/SQL/all
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json; charset=utf-8
Date: Fri, 05 Dec 2025 01:45:42 GMT
Server: Kestrel
Transfer-Encoding: chunked
[
{
"id": 3,
"name": "Hoge1",
"value": 101
},
{
"id": 4,
"name": "Hoge2",
"value": 904
},
{
"id": 5,
"name": "Hoge3",
"value": 103
},
{
"id": 6,
"name": "Hoge4",
"value": 104
}
]
id가 2 이하인 값을 삭제하는 과정도 정상적으로 처리되었다. (이미 값이 2 이하인 데이터는 없었다..)
결론
_db.Statement(@"
CREATE TABLE IF NOT EXISTS IDNameValue(
ID INT PRIMARY KEY AUTO_INCREMENT,
Name VARCHAR(100),
Value INT
);
");
//1.2. 기존 데이터 삭제
await _db.Query("IDNameValue").DeleteAsync();
//1.3. 행 1개 삽입
await _db.Query("IDNameValue").InsertAsync(new { Name = "Hoge1", Value = 101 });
// 1.4. 여러 행 삽입
var rows = new[]
{
new { Name = "Hoge2", Value = 102 },
new { Name = "Hoge3", Value = 103 },
new { Name = "Hoge4", Value = 104 },
};
foreach (var row in rows)
{
await _db.Query("IDNameValue").InsertAsync(row);
}
await _db.Query("IDNameValue").GetAsync<IDNameValue>();
이렇게, SqlKata를 사용해서, 코드 상에서 SQL문을 활용해 더 명시적으로 DB를 조작할 수 있게 해주는 라이브러리인것 같다.
728x90
반응형
'Study > GameServer' 카테고리의 다른 글
| [ASP.NET Core] 11. CloudStructures (0) | 2025.12.05 |
|---|---|
| [ASP.NET Core] 10. Redis (0) | 2025.12.05 |
| [ASP.NET Core] 08. .NET Core에 MySQL 연결 (1) | 2025.12.04 |
| [ASP.NET Core] 07. API 서버간 통신 때 HttpClientFactory 사용하기 (0) | 2025.12.04 |
| [ASP.NET Core] 06. API 서버의 디렉토리 구성 예 (0) | 2025.12.04 |