반응형
해당 글에서는 MyBatis에서 사용되는 비교, 사칙, 비트, 시프트 연산자, CDATA에 대해 알아봅니다.
1) MyBatis
💡 MyBatis
- 개발자들이 SQL 쿼리를 쉽게 작성하고 관리할 수 있도록 도와주는 퍼시스턴스 프레임워크입니다.
- 이를 사용하여 SQL 쿼리와 프로그래밍 코드를 분리하여 관리할 수 있어서 코드의 가독성과 재사용성을 높이고 유지 보수를 용이하게 합니다.
- 또한 JDBC 코드의 복잡성을 추상화하고 SQL 쿼리의 실행 결과와 자바 객체에 매핑하기 위한 강력한 매핑 기능을 제공합니다.
[더 알아보기 ]
💡퍼시스턴스 프레임워크
- 데이터의 저장, 복원, 쿼리, 업데이트 등의 작업을 자동화해 주는 소프트웨어 라이브러리입니다.
- 이를 사용하면 개발자는 데이터베이스에 대한 복잡한 코드를 작성하지 않아도 되며 이로 인해 개발시간을 단축하고 코드의 품질을 향상할 수 있습니다.
- 대표적인 퍼시스턴스 프레임워크로는 Hibernate, MyBatis 등이 있습니다
💡 MyBatis와 iBatis의 차이는 무엇일까?
- iBatis 프로젝트가 중단되고 이를 기반으로 MyBatis가 개발되었습니다.
- iBatis보다 MyBatis는 동적 SQL, 프로시저 호출, 고급 매핑 기능 등을 지원합니다.
2) CDATA(Character Data Section)
💡 CDATA
- SQL 쿼리에 특수 문자를 안전하게 삽입하기 위해 사용됩니다. 해당 안에 포함된 내용은 XML 파서에 의해 파싱 되지 않습니다.
- 비교 연산자를 위해 ‘<’, ‘>’ 기호를 사용하는 경우 기호들은 XML 문법에서 태그를 나타내므로 XML 문서내에서는 오류를 일으킬 수 있습니다.
- 이를 해결하기 위해 SQL 쿼리를 CDATA 섹션 안에 넣어 기호를 안전하게 쿼리에 포함시킬 수 있습니다.
1. SQL 전체 CDATA 사용
💡 SQL 전체 CDATA 사용
- SQL 쿼리에 특수 문자를 안전하게 삽입하기 위한 방법입니다. 이 방법에서는 SQL 쿼리 전체를 <![CDATA[ ]]>로 감싸게 됩니다.
- CDATA 섹션 내에 포함된 내용은 XML 파서에 의해 파싱되지 않습니다.
<select id="selectPerson" parameterType="int" resultType="hashmap">
<![CDATA[
SELECT * FROM PERSON WHERE AGE < #{age}
]]>
</select>
2. 연산자만 CDATA 사용
💡 연산자만 CDATA 사용
- SQL 쿼리에서 특정 연산자에 특수 문자를 안전하게 삽입하기 위한 방법입니다. 이 방법에서는 연산자 부분만 CDATA 섹션(<![CDATA[ ]]>)으로 감싸게 됩니다.
- CDATA 섹션 내에 포함된 내용은 XML 파서에 의해 파싱되지 않습니다. 따라서, 이 방법은 SQL 쿼리의 일부분에 특수 문자를 포함시키고자 할 때 유용하게 사용될 수 있습니다.
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT *
FROM PERSON
WHERE AGE <![CDATA[ < ]]> #{age}
</select>
3) 비교 연산자
💡 비교 연산자
- MyBatis 태그 중 <if>, <choose>, <when>, <otherwise>, <where>, <set>, <foreach>, <bind>와 같은 태그 안에서 test 속성에서 사용이 됩니다.
- 이러한 연산자들은 SQL 쿼리의 동적 생성을 위해 사용되며 특히 조건문이나 반복문 등에서 유용하게 활용됩니다.
1. 동등 비교 연산자
💡 동등 비교 연산자
- 두 값이 같은지를 비교하고자 할 때 사용하는 연산자입니다.
- MyBatis에서는 ==, eq, equals, equalsIgnoreCase 네 가지의 동등 비교 연산자를 제공하며, 이들은 서로 다른 상황에서 사용됩니다.
1. == 와 eq 는 두 값이 동일한지를 비교합니다.
2. equals 는 두 객체가 동일한 객체인지를 비교합니다.
3. equalsIgnoreCase는 대소문자를 구분하지 않고 두 문자열이 동일한지를 비교합니다.
MyBatis 연산자 | 비교 | 설명 |
== | A == B | 동등 비교 |
eq | A eq B | 동등 비교 |
equals | A.equals(B) | 동등 비교(동일한 객체 비교) |
equalsIgnoreCase | A.equalsIgnoreCase(B) | 동등 비교(대소문자 구분 없이 비교) |
<!-- 사용자 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="username != null">
WHERE username = #{username}
</if>
<if test="email eq null">
AND email = #{email}
</if>
<if test="password.equals(null)">
AND password = #{password}
</if>
<if test="!firstName.equalsIgnoreCase(null)">
AND first_name = #{firstName}
</if>
</select>
2. 불일치 비교 연산자
💡 불일치 비교 연산자
- 두 값이 같지 않은지를 비교하는 연산자입니다.
- MyBatis에서는 !=, neq, !equals, !equalsIgnoreCase 네 가지의 불일치 비교 연산자를 제공하며, 이들은 서로 다른 상황에서 사용됩니다.
1. != 와 neq는 두 값이 동일하지 않은지를 비교합니다.
2. !equals 는 두 객체가 동일한 객체가 아닌지를 비교합니다.
3. !equalsIgnoreCase는 대소문자를 구분하지 않고 두 문자열이 동일하지 않은지를 비교합니다.
MyBatis 연산자 | 비교 | 설명 |
!= | A != B | 같지 않음 |
neq | A neq B | 같지 않음 |
!equals | !A.equals(B) | 같지 않음(동일한 객체 비교) |
!equalsIgnoreCase | !A.equalsIgnoreCase(B) | 같지 않음(대소문자 구분 없이 비교) |
<!-- 전체 코드를 조회합니다-->
<select id="selectCodeList" resultType="codeDto">
SELECT t1.*
FROM tb_code t1
WHERE t1.use_yn = true
<if test="grpCd != null">
AND t1.grp_cd = #{grpCd}
</if>
<if test="cd ne null">
AND t1.cd = #{cd}
</if>
<if test="!grpCdNm.equals(null)">
AND t1.grp_cd_nm = #{grpCdNm}
</if>
<if test="!cdNm.equalsIgnoreCase(null)">
AND t1.cd_nm = #{cdNm}
</if>
</select>
3. 논리 연산자
💡 논리 연산자
- 주로 조건식에서 두 개 이상의 조건을 결합시키는 데 사용되며, 결과는 참(True) 또는 거짓(False)입니다.
- MyBatis에서 지원하는 논리 연산자에는 '||' (또는 'or')와 '&&' (또는 'and')가 있습니다.
1. '||' 또는 'or' 연산자는 두 조건 중 하나 이상이 참일 경우 전체 결과를 참으로 반환합니다.
2. '&&' 또는 'and' 연산자는 두 조건 모두 참일 경우에만 전체 결과를 참으로 반환합니다.
MyBatis 연산자 | 비교 | 설명 |
or | A or B | A 또는 B |
&& | A && B | A 그리고 B |
and | A and B | A 그리고 B |
<!-- 사용자 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="username != null and email != null">
WHERE username = #{username} and email = #{email}
</if>
<if test="username != null or email != null">
WHERE username = #{username} or email = #{email}
</if>
</select>
4. 대소 비교 연산자
💡 대소 비교 연산자
- 한 값이 다른 값보다 크거나 작은지, 또는 동일한지를 확인합니다.
- 이 연산자들은 XML 문법 오류를 발생시킬 수 있으므로, 이스케이프 처리(<, >, <e;, >e;)를 사용하여 안전하게 코드를 작성합니다.
MyBatis 연산자 | Escape | 비교 | 설명 |
< | A < B | 왼쪽 값이 오른쪽 값보다 큰지 검사(Less Than) | |
lt | < | A lt B | 왼쪽 값이 오른쪽 값보다 큰지 검사(Less Than) |
> | A > B | 왼쪽 값이 오른쪽 값보다 작은지 검사(Greater Than) | |
gt | > | A gt B | 왼쪽 값이 오른쪽 값보다 작은지 검사(Greater Than) |
<= | A <= B | 왼쪽 값이 오른쪽 값보다 작거나 같은지 검사(Less Than Or Equal To) | |
lte | <e; | A lte B | 왼쪽 값이 오른쪽 값보다 작거나 같은지 검사(Less Than Or Equal To) |
>= | A >= B | 왼쪽 값이 오른쪽 값보다 크거나 같은지 검사(Greater Than Or Equal To) | |
gte | >e; | A gte B | 왼쪽 값이 오른쪽 값보다 크거나 같은지 검사(Greater Than Or Equal To) |
💡 사용자의 나이를 기준으로 정보를 조회하는 SQL 쿼리를 예시로 구성하였습니다.
- 첫 번째 <if> 태그에서는 사용자의 나이가 쿼리에 입력된 나이보다 작거나 같은 모든 사용자를 조회하며, 두 번째 <if> 태그에서는 사용자의 나이가 쿼리에 입력된 나이보다 큰 모든 사용자를 조회합니다.
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age < #{age}
</if>
<if test="age != null">
WHERE age > #{age}
</if>
</select>
[더 알아보기]
💡 <와 같이 사용하는 경우도 있는데 왜 그렇게 사용하는 걸까?
- MyBatis에서는 <와 같은 특수문자를 직접 사용하면 XML 문법 오류가 발생할 수 있습니다. 그래서 안전하게 코드를 작성하기 위해 <와 같은 방식으로 이스케이프 처리를 합니다.
4) 사칙 연산자
💡 사칙 연산자
- 더하기(+), 빼기(-), 곱하기(*), 나누기(/)와 같은 기본적인 수학 연산을 수행합니다.
- MyBatis에서는 SQL 쿼리 내에서 사용할 수 있으며, 변수 또는 상수값 간의 연산에 사용됩니다.
연산자 | 비교 | 설명 |
+ | A + B | 더하기 |
- | A - B | 빼기 |
* | A * B | 곱하기 |
/ | A / B | 나누기 |
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} + 10
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} - 5
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} * 2
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} / 2
</if>
</select>
5) 비트 연산자
💡 비트 연산자
- 피 연산자를 이진수로 나타내고 이진수의 각 비트를 연산합니다.
1. 비트 OR 연산자 (|, bor) : 두 피연산자 중 어느 한쪽이라도 1일 경우, 결과는 1입니다.
2. 비트 XOR 연산자 (^, xor) : 두 피연산자가 서로 다른 값을 가질 때, 결과는 1입니다.
3. 비트 AND 연산자 (&, band) : 두 피연산자 모두 1일 경우에만, 결과는 1입니다.
연산자 | 비교 | 설명 |
bor | A bor B | 비트 OR 연산자 |
^ | A ^ B | 비트 XOR 연산자 |
xor | A xor B | 비트 XOR 연산자 |
& | A & B | 비트 AND 연산자 |
band | A band B | 비트 AND 연산자 |
💡 사용예시
- OR, XOR, AND 연산자를 사용하여 사용자의 나이에 10, 5, 2를 비트 연산한 결과를 기준으로 사용자 정보를 조회하는 SQL 쿼리를 작성하였습니다.
- age 값이 20이라고 가정하였을때
1. 이진수로 20은 10100이고 10은 01010입니다. OR 연산의 결과는 11110이며, 이는 10진수로 30입니다.
2. 이진수로 20은 10100이고 5는 00101입니다. XOR 연산의 결과는 10001이며, 이는 10진수로 17입니다.
3. 이진수로 20은 10100이고 2는 00010입니다. AND 연산의 결과는 00000이며, 이는 10진수로 0입니다.
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} | 10
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} ^ 5
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} & 2
</if>
</select>
6) 시프트 연산자
💡 시프트 연산자
- 비트를 왼쪽 또는 오른쪽으로 이동시키는 연산자입니다. 이 연산자는 주로 비트 단위로 작업할 때 사용됩니다.
1. 왼쪽 시프트 연산자 (<< 또는 shl)
- 피연산자의 비트를 왼쪽으로 이동시킵니다. 왼쪽으로 몇 비트 이동시킬지는 우측에 위치한 수에 따라 결정됩니다. 비트가 왼쪽으로 이동하면서 빈 공간은 0으로 채워집니다.
2. 오른쪽 시프트 연산자 (>> 또는 shr)
- 피연산자의 비트를 오른쪽으로 이동시켜 줍니다. 오른쪽으로 몇 비트 이동시킬지는 우측에 위치한 수에 따라 결정됩니다. 비트가 오른쪽으로 이동하면서 빈 공간은 원래의 숫자가 양수라면 0으로, 음수라면 1로 채워집니다.
3. 오른쪽 논리 시프트 연산자 (>>> 또는 ushr)
- 피연산자의 비트를 오른쪽으로 이동시키되, 빈 공간을 무조건 0으로 채워줍니다. 음수에서도 맨 왼쪽 비트를 0으로 채워주며, 이로 인해 결과는 항상 0 또는 양수가 됩니다.
연산자 | 설명 |
<<, shl | 비트 왼쪽 시프트 연산자 |
>>, shr | 비트 오른쪽 시프트 연산자 |
>>>, ushr | 비트 오른쪽 논리 시프트 연산자 |
💡 사용예시
- 사용자의 나이를 기준으로 정보를 조회하는 SQL 쿼리 예시입니다.
- <if> 태그에서는 사용자의 나이에 2, 1을 왼쪽 시프트, 오른쪽 시프트, 오른쪽 논리 시프트 연산을 수행한 결과를 기준으로 사용자 정보를 조회합니다.
- age 값이 20이라고 가정하였을 때
1. 나이를 2비트 왼쪽으로 시프트 하므로, 20 (이진수로 10100)를 왼쪽으로 2비트 시프트 하면 80 (이진수로 1010000)이 됩니다.
2. 나이를 1비트 오른쪽으로 시프트하므로, 20 (이진수로 10100)을 오른쪽으로 1비트 시프트하면 10 (이진수로 1010)이 됩니다.
3. 나이를 1비트 오른쪽으로 논리 시프트하므로, 결과는 두 번째 쿼리와 동일하게 10 (이진수로 1010)이 됩니다. 이는 오른쪽 논리 시프트에서 빈 공간이 무조건 0으로 채워지기 때문입니다.
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} << 2
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} >> 1
</if>
</select>
<!-- 사용자의 나이를 기준으로 정보를 조회합니다 -->
<select id="selectUser" resultType="userDto">
SELECT *
FROM tb_user
<if test="age != null">
WHERE age = #{age} >>> 1
</if>
</select>
오늘도 감사합니다. 🤩
반응형