using System;
using System.Data.SqlClient;
using Dapper;
using System.Collections.Generic;
public class UserRepository
{
private readonly string _connectionString;
public UserRepository(string connectionString)
{
_connectionString = connectionString;
}
// 공통 SELECT 컬럼 정의
private string GetSelectColumns()
{
return "id, name, email, created_at";
}
// 공통 WHERE 절 정의
private string GetWhereCondition()
{
return "WHERE status = @Status AND created_at > @CreatedAt";
}
// 사용자 수 조회
public int GetUserCount(int status, DateTime createdAt)
{
using (var connection = new SqlConnection(_connectionString))
{
// SQL 인젝션 방지를 위해 매개변수 바인딩 사용
string sql = $"SELECT COUNT(*) FROM users {GetWhereCondition()}";
return connection.QuerySingle<int>(sql, new { Status = status, CreatedAt = createdAt });
}
}
// 사용자 리스트 조회
public IEnumerable<User> GetUsers(int status, DateTime createdAt)
{
using (var connection = new SqlConnection(_connectionString))
{
// SQL 인젝션 방지를 위해 매개변수 바인딩 사용
string sql = $"SELECT {GetSelectColumns()} FROM users {GetWhereCondition()}";
return connection.Query<User>(sql, new { Status = status, CreatedAt = createdAt });
}
}
}
dapper 공통 쿼리 count list 샘플 mybtis의 include refid 비슷한 기능 where re use sonarqube s2077ChatGPT의 말:
ChatGPT
Dapper를 사용할 때, MyBatis의 include와 refid와 유사한 방식으로 WHERE 절을 재사용하는 방법과 함께 SonarQube의 S2077 규칙(즉, SQL 인젝션 방지)을 준수하는 샘플 코드를 제공하겠습니다.
1. 공통 WHERE 구문 정의하기
먼저, 공통으로 사용할 WHERE 절을 함수로 분리합니다. 이 함수는 매개변수를 사용하여 SQL 인젝션을 방지하면서 재사용 가능한 SQL 구문을 생성합니다.
csharp
코드 복사
public string GetWhereCondition() { return "WHERE status = @Status AND created_at > @CreatedAt"; }
2. COUNT와 LIST 쿼리에서 공통 WHERE 구문 재사용하기
이제 Dapper를 사용하여 COUNT와 LIST 쿼리를 작성하고, SQL 인젝션을 방지하기 위해 Dapper의 매개변수 바인딩을 사용합니다.
3. 설명
- GetWhereCondition 메서드: 공통적으로 사용될 WHERE 절을 반환합니다. 이는 MyBatis의 include와 refid와 유사한 기능을 제공합니다.
- SQL 인젝션 방지: Dapper는 기본적으로 매개변수 바인딩을 통해 SQL 인젝션을 방지합니다. @Status와 @CreatedAt 같은 매개변수를 사용해 안전하게 쿼리를 실행합니다. 이 방식은 SonarQube의 S2077 규칙을 준수합니다.
- GetUserCount 및 GetUsers 메서드: 공통 WHERE 절을 재사용하면서, SQL 인젝션을 방지하는 방법을 보여줍니다.
4. SonarQube S2077 규칙 준수
SonarQube의 S2077 규칙은 SQL 인젝션 공격에 대한 방어를 목적으로 합니다. 이 규칙을 준수하기 위해 다음 사항을 염두에 둡니다:
- 매개변수화된 쿼리: SQL 쿼리에서 변수 값을 직접 문자열에 포함시키지 않고, 매개변수를 사용하여 값을 전달합니다. Dapper는 @를 사용해 매개변수를 바인딩함으로써 SQL 인젝션을 방지합니다.
- 직접적인 문자열 결합 방지: 쿼리의 동적 부분을 문자열로 직접 연결하지 않도록 주의합니다. 모든 사용자 입력은 매개변수화해야 합니다.
이 코드 샘플은 Dapper에서 공통 쿼리 구문을 재사용하면서, SonarQube의 보안 규칙을 준수하는 방법을 보여줍니다
using System;
using System.Data.SqlClient;
using Dapper;
using System.Text;
using System.Collections.Generic;
public class UserRepository
{
private readonly string _connectionString;
public UserRepository(string connectionString)
{
_connectionString = connectionString;
}
public IEnumerable<User> GetUsers(int? status = null, DateTime? createdAt = null, string email = null)
{
using (var connection = new SqlConnection(_connectionString))
{
var sql = new StringBuilder("SELECT id, name, email, created_at FROM users");
var whereClauses = new List<string>();
var parameters = new DynamicParameters();
// 조건에 따른 동적 WHERE 절 생성
if (status.HasValue)
{
whereClauses.Add("status = @Status");
parameters.Add("Status", status.Value);
}
if (createdAt.HasValue)
{
whereClauses.Add("created_at > @CreatedAt");
parameters.Add("CreatedAt", createdAt.Value);
}
if (!string.IsNullOrEmpty(email))
{
whereClauses.Add("email = @Email");
parameters.Add("Email", email);
}
// WHERE 절이 존재하는 경우 추가
if (whereClauses.Count > 0)
{
sql.Append(" WHERE ");
sql.Append(string.Join(" AND ", whereClauses));
}
return connection.Query<User>(sql.ToString(), parameters);
}
}
}
728x90
댓글