본문 바로가기
.NET/SmartSQL

SmartSql 사용법

by ironman! 2023. 12. 3.

.NET 에서 JAVA 에서 일반적으로 사용하는 MyBatis 와 유사한 프레임워크를 찾아보다가 MyBatis.NET 을 검색해 알게 되었지만 2010년 이후로 더이상 릴리즈되고 있지 않았고 상위 .NET Framework 를 지원할지 여부가 불투명 하여 다른 대체군을 찾게 되었다.

 

MyBatis.NET

https://code.google.com/archive/p/mybatisnet/downloads

 

Google Code Archive - Long-term storage for Google Code Project Hosting.

 

code.google.com

여러 대체군들을 검색해 내용을 확인해 봤으나 사용 난이도와 가능하면 MyBatis 와 유사한 패턴을 찾다 보니 SmartSql 이이라는 라이브러리로 좁혀지게 되었다.

 

선택한 사유로는 StackOverFlow 에서 해당 라이브러리를 개발했다는 것과 자체 사이트에 적용하고 있다는 내용을 보았고 MyBatis 와 문법은 다르나 유사한 XML Mapper 형식을 이용하는 방식이 마음에 들었다.

 

공식 SmartSql 사이트 : https://smartsql.net/en/

 

SmartSql

 

smartsql.net

공식 문서대로 따라해 보고자 하는 경우에는 가이드 문서를 참고하면 되며 핵심 내용만 빠르게 적용 또는 핵심만 알고자 하는 경우에는 아래 내용을 참고 하시면 됩니다.

 

1) XML Mapper 를 작성할 때 인텔리전스를 지원되게 하기 위해 실행합니다.

Install-Package SmartSql.Schema

 

2) SmartSql 을 작업 프로젝트에 적용하기 위해 실행합니다.

Install-Package SmartSql

 

3) SmartSql 과 관련된 설정 목적의 XML 파일을 프로젝트에 추가합니다.

<?xml version="1.0" encoding="utf-8" ?>
<SmartSqlMapConfig xmlns="http://SmartSql.net/schemas/SmartSqlMapConfig.xsd">
  <Settings IgnoreParameterCase="false" ParameterPrefix="$" IsCacheEnabled="true"/>
  <Properties>
    <Property Name="ConnectionString" Value="Data Source=.;Initial Catalog=SmartSqlTestDB;Integrated Security=True"/>  
  </Properties>
  <Database>
    <DbProvider Name="SqlServer"/>
    <Write Name="WriteDB" ConnectionString="${ConnectionString}"/>
    <Read Name="ReadDb-1" ConnectionString="${ConnectionString}" Weight="100"/>
  </Database>
  <IdGenerator Type="SnowflakeId">
    <Properties>
      <Property Name="WorkerIdBits" Value="10"/>
      <Property Name="WorkerId" Value="888"/>
      <Property Name="Sequence" Value="14"/>
    </Properties>
  </IdGenerator>
  <SmartSqlMaps>
    <SmartSqlMap Path="Maps" Type="Directory"/>
  </SmartSqlMaps>
</SmartSqlMapConfig>

 

4) SmartSqlBuilder 라는 객체를 통해서 XML 을 로드하고 Session 을 얻어 CURD 를 구현한다.

  • 한가지 주의해야할 사항은 SmartSqlBuilder 는 어플리케이션에 1개의 인스턴스가 되도록 구현한다. 따라서 어플리케이션 시작 시 1개의 인스턴스를 생성하고 재사용 할 수 있도록 처리한다. (예 : Static 으로 선언된 전역 인스턴스)
  • 그렇지 않은 경우 이미 동일한 SmartSql 리파지토리가 있다라는 오류 메시지를 보게 된다.
SmartSqlBuilder life cycle
The best scope for SmartSqlBuilder is the application scope. You can use single-case mode or static singleton mode.

 

5) XML Mapper 를 아래와 같은 형식으로 작성되며 MyBatis 와 구조적인 틀은 유사하다.

<?xml version="1.0" encoding="utf-8" ?>
<SmartSqlMap Scope="TickerInfo" xmlns="http://SmartSql.net/schemas/SmartSqlMap.xsd">
  <Statements>    
    <Statement Id="Select_LastTickers" >
      WITH tmp_backdata AS (
      select
      MAX(tbd.trade_datetime) as trade_datetime,
      tbd.exckey,
      tbd.curkey,
      tbd.symbol
      from (
      select
      concat(trade_date,trade_time) as trade_datetime,
      exckey,
      curkey,
      symbol
      from
      backdata
      where 1 = 1
      and exckey = ?exckey
      and curkey = ?curkey
      and symbol in
      <For Open="(" Close=")" Key="CoinInfo" Property="items" Separator=",">
        ?Key
      </For>
          ) tbd
      GROUP BY
          tbd.exckey,
          tbd.curkey,
          tbd.symbol
      )
      select
        bd.trade_date,
        bd.trade_time,            
        tbd.symbol,
        bd.trade_price,
        bd.trade_volume
      from
        tmp_backdata tbd
    left join backdata bd on 1 = 1
        and bd.exckey = tbd.exckey
        and bd.curkey = tbd.curkey
        and bd.symbol = tbd.symbol
        and bd.trade_date = substring(tbd.trade_datetime, 1, 8)
        and bd.trade_time = substring(tbd.trade_datetime, 9, 8)
    </Statement>    
  </Statements>
</SmartSqlMap>

 

6) 실제 Mapper 를 호출 하는 부분은 아래와 같이 처리 합니다.

var dbSessionFactory = new SmartSqlBuilder()
    .UseXmlConfig()
    .Build()
    .GetDbSessionFactory();

using (var dbSession = dbSessionFactory.Open())
{
    dbSession.Open();
    
    DataTable dt = dbSession.GetDataTable(new RequestContext
    {
        Scope = nameof(TickerInfo),
        SqlId = "Select_LastTickers",
        Request = new
        {
            items = cis,
            exckey = this.Exchange.ToString().ToUpper(),
            curkey = this.Currency.ToString().ToUpper()
        }
    });

    if(dt == null || dt.Rows.Count == 0)
    {
        return tis;
    }

 

(현재 문서 내용 보완 중..)