C# - sqlMap 사용하기 - 7

2023. 3. 21. 19:54프로그래밍

728x90

 

 

3.4. Parameter Maps and Inline Parameters

Most SQL statements are useful because we can pass them values at runtime. Someone wants a database record with the ID 42, and we need to merge that ID number into a select statement. A list of one or more parameters are passed at runtime, and each placeho

ibatis.apache.org

 

1. Parameter Maps and Inline Parameters

대부분의 SQL 문은 런타임시에 값을 세팅 할 수 있는 유용한 점이 있다

즉 데이터베이스에서 ID 42인 레코드를 가져오고 싶을 때 select 문에 ID 번호를 세팅하는 것이 필요 한데

런타임시에 하나 이상의 파라메터를 전달하고 각 placeholder는 차례로 값으로 교체되도록 한다는 것이다

외부 파라메터 맵 예제

<parameterMap id="parameterMapIdentifier" 
  [class="fullyQualifiedClassName, assembly|typeAlias"]
  [extends="[sqlMapNamespace.]parameterMapId"]>
  <parameter 
    property ="propertyName" 
    [column="columnName"]
    [direction="Input|Output|InputOutput"]
    [dbType="databaseType"] 
    [type="propertyCLRType"]
    [nullValue="nullValueReplacement"] 
    [size="columnSize"] 
    [precision="columnPrecision"] 
    [scale="columnScale"]  
    [typeHandler="fullyQualifiedClassName, assembly|typeAlias"]  
  <parameter ... ... />
  <parameter ... ... /> 
</parameterMap>
 

 

다음은 일반적으로 세팅되는 파라메터 맵이다

<parameterMap id="insert-product-param" class="Product">
  <parameter property="description" />
  <parameter property="id"/>
</parameterMap>

<statement id="insertProduct" parameterMap="insert-product-param">
  insert into PRODUCT (PRD_DESCRIPTION, PRD_ID) values (?,?);
</statement>
 

Note.

파라메터 맵은 항상 그 정의가 들어 있는 Data Map 정의 파일에 존재한다

다른 Data Map 정의 파일을 참조하고 싶다면 Data Map(<sqlMap> 루트 엘리먼트에 정의된)의 네임스페이스의 Parameter Map의 id를 접두사로 사용하면 된다

만약 Data Map 이름이 "Product" 이면 다른 파일에서는 "Product.insert-product-param"를 사용하여 참조할 수 있다

 

1.1 <parameterMap> 속성들

id (required), class (optional), and extends(optional) 세가지 속성값만 사용된다.

 

1.1.1 id

class 속성은(옵션) 이 <parameterMap>내에서 사용되는 오브젝트 클래스를 지정한다. 클래스 이름과 어셈블리 혹은 별명이

반드시 지정되어야 한다. 어떤 클래스에서도 사용될 수 있다

 

1.1.2 extends

extends 속성은 다른 parameterMap의 이름으로 지정될 수 있다 super parameterMap의 모든 프로퍼티들은 이 parameterMap의 부분으로 포함될 수 있으며 super parameterMap의 값들은 이 parameterMap의 값이 지정되기 전에 설정이 되어야 한다 클래스를 상속하는 것과 똑같은 효과이다

 

1.2 <parameter> 엘리먼트

<parameter> 엘리먼트 하나 이상의 SQL 문안의 placeholders를 대체할수 있는 오브젝트 프로퍼티의 파라메터 자식 엘리먼트를 가진다

 

1.2.1 property

property 속성은 파라메터 오브젝트의 필드나 프로퍼티의 이름이다

또한 IDictionary 오브젝트안의 엔트리의 이름이 될 수 있다

 

1.2.2 column

column 속성은 stored procedure에서 사용되어지는 파라메터 이름을 정의하는 데 사용된다

 

1.2.3 direction

direction 속성은 stored procedure 파라메터의 방향을 지정하는데 사용된다

값은 Input,Output 그리고 InputOutput으로 구성된다

 

1.2.4 dbType

dbType 속성은 명시적으로 이 프로퍼티로 세팅될 파라메터의 데이터베이스 컬럼타입을 지정하는 데 사용된다

 

컬럼의 dbTpye을 지정해야 할 경우 예

.NET의 경우 하나의 Data value 타입을 가지고 있지만(System.DateTime), 일반적으로 데이터베이스는 적어도 세가지 다른 타입(DATE, DATETIME, TIMESTAMP)을 가진다.

 

Note.

거의 대부분의 벤더들은 단지 널허용 컬럼에 대해서만 dbType을 지정한다. 이경우 그 컬럼이 널을 허용한다는것을 명시할 필요가 있다

 

1.2.5 type

type 속성은 파라메터의 property의 CLF 타입을 지정하는 데 사용된다

이 속성은 InputOutput와 Output parameters를 stored procedures로 전달 할 때 유용한다

 

1.2.6 nullValue

nullValue 속성는 어떤 유효한 값(프로퍼티 타입을 기반으로)에 세팅할 수 있다

nullValue 는 outgoing 널 값의 변환을 지정할 때 사용되어진다 반대 행동은 inbound 널값 변환)

이 말은 나의 애플리케이션에사 사용하는 널 값을 지원하지 않는 타입(int, double,float 같은)값에 매직 널 숫자를 붙여 사용할 수 있다는 의미인데 이타임의 프로퍼티가 해당하는 널 값(-9999)이면, NULL 값이 그 값 대신에 데이터베이스로 전달된다

 

1.2.7 size

size 속성은 컬럼내 데이터의 최대 크기를 지정한다

 

1.2.8 precision

precision 속성은 프로퍼티 값으로 대변되는 숫자의 최대 개수를 지정하는 데 사용한다

 

1.2.9 scale

scale 속성은 프로퍼티 값을 변환 하는 데 사용되는 십진수의 개수를 지정하는 데 사용된다

 

1.2.10 typeHandler

typeHandler 속성은 Custom Type Handler의 사용에 대한 허용을 나타낸다

데이터베이스 프로바이더에 특정적인 타입을 조작하기 위한 DataMapper의 능력을 확장 할 수 있도록 해 주는 것

데이터베이스로 부터 불리언값들이나 Guid를 저장하거나 다시 불러 올 수 있는 커스텀 타입의 핸들러를 생성할 수 있다

 

1.3 Inline Parameter Maps

parameter maps 대신에 inline parameters를 사용하는 것을 선호 한다면 extra type information inline를 첨가 할 수 있다

 

가. inline parameters를 이용한 statement 예제

<statement id="insertProduct" parameterClass="Product">
  insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
  values (#id#, #description#)
</statement>
 

 

나. 타입을 사용한 inline parameter map을 사용한 statement 예제

<statement id="insertProduct" parameterClass="Product">
  insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
  values (#id:int#, #description:VarChar#)
</statement>
 

다음 예제는 dbType이나 널 값 대체를 선언된 인라인에서 어떻게 사용 할 수 있는 지 보여주는 예제이다

 

다. 널 값 대체 inline parameter map을 사용한 statement 예제

<statement id="insertProduct" parameterClass="Product">
  insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
  values (#id:int:-999999#, #description:VarChar#)
</statement>
 

 

라. property, type, dbType, 그리고 널값 대체가 있는 alternate inline syntax를 사용한 statement 예제

<update id="UpdateAccountViaInlineParameters" parameterClass="Account">
 update Accounts set
 Account_FirstName = #FirstName#,
 Account_LastName = #LastName#,
 Account_Email = #EmailAddress,type=string,dbType=Varchar,nullValue=no_email@provided.com#
 where
 Account_ID = #Id#
</update>
 

Note

inline parameters를 사용할 때 dbType의 명시 없이 널 값 대체를 명시할 수 없다

파싱 순서 때문에 두개다 명시해야 한다

 

1.4 Standard Type Parameters

실행 중 하나의 파라메터를 사용하는 많은 문을 만날수 있는 데, 종종 Integer나 String이 그것일 것이다

다른 오브젝트로 이 클래스를 덧씌우기 보다는 파라메터로 기본 라이브러리가 제공하는 그 자체로 사용할 수 있다

standard type 파라메터를 사용한 statement 예제

<statement id="getProduct" parameterClass="System.Int32">
   select * from PRODUCT where PRD_ID = #value#
</statement>
 

 

여기서 PRD_ID는 숫자 타입이라고 가정하고 기본 Integer 오브젝트를 전달하고 있다

원시타입의 데이터도 가능한데 이는 3.6, "Supported Types for Parameter Maps and Result Maps". 참조한다

 

1.5 Map or IDictionary Type Parameters

IDictionary 인스턴스를 파라메터 오브젝트로 사용할 수 있다 이경우 일반적으로 Hashtable이다

parameterClass클래스로 Map 혹은 IDictionary를 사용한 statement예제

<statement id="getProduct" parameterClass="System.Collections.IDictionary">
  select * from PRODUCT
  where PRD_CAT_ID = #catId#
  and PRD_CODE = #code#
</statement>
 

이때 각 키는 컬럼의 타입과 맞아야만 한다 3.6, "Supported Types for Parameter Maps and Result Maps". 참조한다

 

2. Result Maps

Result Maps는 오브젝트 프로퍼티들에 대한 데이터베이스 질의(컬럼 집합)의 결과를 매핑함으로써 job를 마친다

Mapped Statements 다음으로, 아마도 Result Map은 가장많이쓰고 가장 중요하게 알아야할 특징이다

 

<resultMap> element구조

<resultMap id="resultMapIdentifier" 
           [class="fullyQualifiedClassName, assembly|typeAlias"] 
           [extends="[sqlMapNamespace.]resultMapId"]>

   <constructor > 
       <argument property="argumentName" 
           column="columnName"
           [columnIndex="columnIndex"] 
           [dbType="databaseType"] 
           [type="propertyCLRType"]
           [resultMapping="resultMapName"]
           [nullValue="nullValueReplacement"] 
           [select="someOtherStatementName"] 
           [typeHandler="fullyQualifiedClassName, assembly|typeAlias"] />
   </constructor > 

   <result property="propertyName" 
           column="columnName"
           [columnIndex="columnIndex"] 
           [dbType="databaseType"] 
           [type="propertyCLRType"]
           [resultMapping="resultMapName"]
           [nullValue="nullValueReplacement"] 
           [select="someOtherStatementName"] 
           [lazyLoad="true|false"]
           [typeHandler="fullyQualifiedClassName, assembly|typeAlias"]
   />
   <result ... .../>
   <result ... .../>
    // Inheritance support
   <discriminator column="columnName" 
                     [type|typeHandler="fullyQualifiedClassName, assembly|typeAlias"]
   />
    <subMap value="discriminatorValue" 
               resultMapping="resultMapName"
   />
   <subMap .../> 
</resultMap>
 

 

"[" 옵션사항

id 속성은 문장을 참조하기 위한 이름으로 쓰이기 때문에 필요하다

class 속성도 Type Alias 혹은 the fully qualified name of a class을 명시함으로 필요하다

Note

parameter classes를 사용한다면 결과 클래스는 .NET 오브젝트나 IDictionary 인스턴스여야만 한다

 

2.1 resultMaps 확장

 

2.2 <resultMap> 속성

id (required), class (optional), 그리고 extends(optional) 이상 세게의 속성을 가질 수 있다.

 

2.2.1 id

id 속성은 Data Map상의 <resultMap>의 고유한 아이디를 제공한다

 

2.2.2 class

옵션인 class 속성는 <resultMap>내에 사용 할 수 있는 오브젝트 클래스를 명시한다

 

2.2.3 extends

extends 속성은 "super" resultMap으로부터 상속 받은 모든 프로퍼티를 사용 할 수 있도록 허용한다

2.2.4 groupBy

옵션인 groupBy 속성은 resultMap에서 만들어진 결과 오브젝트의 .NET property 이름들의 리스트를 지정한다

 

2.3 <constructor> element

결과 클래스 생성자 중 하나의 시그너쳐와 매칭 되어야 한다

<constructor> element는 하나이상의 <argument> 엘리먼트를 자식 엘리먼트로 가진다 이 엘리먼트는 SQL resultset 들을 생

성자의 오브젝트 아규먼트와 매핑한다

<resultMap id="account-result-constructor" class="Account" >
	 <constructor>
		<argument argumentName="id" column="Account_ID"/>
		<argument argumentName="firstName" column="Account_FirstName"/>
		<argument argumentName="lastName" column="Account_LastName"/>
	</constructor>
	<result property="EmailAddress" column="Account_Email" nullValue="no_email@provided.com"/>
	<result property="BannerOption" column="Account_Banner_Option" dbType="Varchar" type="bool"/>
	<result property="CartOption"	column="Account_Cart_Option" typeHandler="HundredsBool"/>
</resultMap>
 

2.3.1 argumentName

argumentName 속성은 Mapped Statement에서 리턴된 결과 오브젝트의 생성자 아규먼트의 이름이다

2.3.2 column

column 속성은 결과 집합안의 컬럼이름이다

 

2.3.3 columnIndex

옵션인 columnIndex 오브젝트 아규먼트를 생성할때 사용될 값으로 부터 온 ResultSet 내에 컬럼의 인덱스이다

 

2.3.4 dbType

dbType 속성은 아규먼트를 만들어 낼때 사용되는 ResultSet column의 데이터베이스 컬럼 타입을 명시한다

 

2.3.5 type

type 속성은 CLR argument type을 명시적으로 지정하는 데 사용된다

 

2.3.6 resultMapping

resultMapping 속성은 아규먼트를 채워줄 다른 resultMap의 이름을 지정할 수 있다

 

2.3.7 nullValue

1.2.6 nullValue 참조

 

2.3.8 select

select 속성은 오브젝트간의 관계를 설명하고 복잡한 프로퍼티 타입을 자동적으로 로딩하는 데 사용된다

 

2.3.9 typeHandler

1.2.10 typeHandler 참조

 

2.4 <result> Elements

<resultMap> element 한개이상의 <result> 자식 엘리먼트를 가진다

 

2.4.1 property

property 속성은 Mapped Statement에서 리턴된 결과 오브젝트의 필드나 프로퍼티의 이름이다

 

2.4.2 column

1.2.2 column 참조.

 

2.4.3 dbType

1.2.4 dbType 참조.

 

2.4.4 type

2.3.5 type참조.

 

2.4.6 resultMapping

resultMapping 속성은 다음과 같다

resultMapping="[namespace.sqlMap.]resultMappingId"
resultMapping="Newspaper"
<!--resultMapping with a fully qualified name.-->
resultMapping="LineItem.LineItem
 

2.4.7 nullvalue

1.2.6 nullValue 참조

예제 Result Map 내에 nullvalue 속성을 명시한 예제

 <resultMap id="get-product-result" class="product"> 
  <result property="id" column="PRD_ID"/>
  <result property="description" column="PRD_DESCRIPTION"/>
  <result property="subCode" column="PRD_SUB_CODE" nullValue="-9999"/>
</resultMap>
 

2.4.8 select

2.3.8 select 참조

 

2.4.9 lazyLoad

select 속성과 함께 lazyLoad 속성은 select문의 결과가 느슨한 로딩을 해야 할지 말지를 지정한다

결과가 필요하거나 접근할 수있을 때까지 select문의 결과의 로딩을 지연함으로써 성능향상을 가져올 수 있다

Lazy loading은 IList and IList<T>구현으로 지원될 수 있다

Lazy loading은 Castle.DynamicProxy 컴포넌트를 통해 strongly typed collection을 지원한다

이 경우 listClass 속성을 지정해야만 하고

만든 컬렉션내의 proxy로 만들고 싶은 모든 메서드나 프로퍼티를 virtual로 선언한다

Lazy loading은 Castle.DynamicProxy 컴포넌트를 사용해서 concrete class로 만들 수 있도록 지원한다

이 경우도 proxy로 만들고 싶은 모든 메서드나 프로퍼티를 virtual로 선언한다

proxy call을 이용한 strongly typed collection 샘플

[C#]

[Serializable]
public class LineItemCollection : CollectionBase 
{
	public LineItemCollection() {}

	public virtual LineItem this[int index] 
	{
		get	{ return (LineItem)List[index]; }
		set { List[index] = value; }
	}

	public virtual int Add(LineItem value) 
	{
		return List.Add(value);
	}

	public virtual void AddRange(LineItem[] value) 
	{
		for (int i = 0;	i < value.Length; i++) 
		{
			Add(value[i]);
		}
	}

	public virtual void AddRange(LineItemCollection value) 
	{
		for (int i = 0;	i < value.Count; i++) 
		{
			Add(value[i]);
		}
	}

	public virtual bool Contains(LineItem value) 
	{
		return List.Contains(value);
	}

	public virtual void CopyTo(LineItem[] array, int index) 
	{
		List.CopyTo(array, index);
	}

	public virtual int IndexOf(LineItem value) 
	{
		return List.IndexOf(value);
	}
	
	public virtual void Insert(int index, LineItem value) 
	{
		List.Insert(index, value);
	}
	
	public virtual void Remove(LineItem value) 
	{
		List.Remove(value);
	}

	public new virtual int Count
	{
		get {return this.List.Count;}
	}
}
 
 

2.4.10 typeHandler

1.2.10 typeHandler 참조

 

 

이상

 

 

728x90