Developer/Spring eGov4.0 (Java11, Tomcat9)

SpringBoot-MyBatis, 동적 쿼리 생성을 위한 XML 태그 끝내기 !

단님 2024. 10. 29. 13:10
728x90
MyBatis의 XML 태그

 

MyBatis에서는 동적 SQL을 작성하기 위해 다양한 xml 태그를 제공한다.

조건문 또는 반복문 또는 여러 SQL문을 유연하게 구성할 수 있도록 도와준다.

각 태그에 대해 알아보자.

 

앞선 MyBatis 환경설정 및 xml구성 , springBoot 구조이해

생성후 xml 파일의 구성

1. <mapper>태그는 쿼리를 정의하는 태그다.
2.namespace와 인터페이스 패키지 이름과 정확하게 일치해야한다.
3.속성_ id : 사용할 메서드 명 
4.속성_ resultType : 리턴타입에 대한 명시. 위치를 src/main/java 이후의 경로를 명시한다.   
5.select 태그 경우 리턴타입을 명시한다.
6.insert,update,delete 태그는 리턴타입을 명시하지 않아도 되며 , 리턴이 int형으로 실행갯수를 반환한다. 

 


기본 CRUD 태그
select All tag
  <select id="selectList" resultType="com.example.demo02.domain.MemberDTO">
  select * from member
  </select>

 

select one tag
  <select id="selectOne" resultType="com.example.demo02.domain.MemberDTO">
  select * from member where id=#{id}
  </select>

id=dto.getID()-> #{id}

 

insert (int로 실행 갯수 반환)
  <insert id="insert">
  insert into member values(#{id},#{password},#{name},#{age},#{jno},#{info},#{point},#{birthday},#{rid},#{uploadfile})
  </insert>

 

update (int로 실행 갯수 반환)
  <update id="update">
  update member set name=#{name}, age=#{age} ,jno=#{jno}, info=#{info}, point=#{point}, birthday=#{birthday} , rid =#{rid} , uploadfile = #{uploadfile} where id=#{id}
  </update>

 

delete ( int로 실행 갯수 반환)
  <delete id="delete">
  	delete from member where id=#{id}
  </delete>

 


#{ } 와 ${ }의 구분
#{ } 
매개변수를 안전하게 바인딩.
주로 변수값을 SQL 조건에 사용할 때 사용된다.
<select id="selectOne" resultType="com.example.demo02.domain.MemberDTO">
    select * from member where id=#{id}
</select>

#{id} : parameter 로 전달된 dto 의 id 라는 컬럼의 value 가 전달됨
-> getId() 로 처리함, Map의 경우 키값이 id 인 값을 찾음.

 

${ }
SQL 구문에 매개변수를 직접 치환할 때 사용하며 , 컬럼이름, 테이블 등 동적 구문을 만들때 주로 사용.
SQL 인젝션에 취약할 수 있으므로 변수 값에는 사용하지 않는 것이 좋다. 
<when test="searchType !=null and keyword!=null">
    and ${searchType} like #{keyValue}
</when>

 

${searchType} : 필드를 표현 (매개변수로 전달된 객체의 id 컬럼의 값을 table의 컬럼으로 인식하고 적용함)

 

CDATA
XML에서는 <,>등 비교연산자의 경우 XML규칙상 에러 나기 때문에,
이 기호를 연산자로 인식하도록 하기 위해서는 SQL문을 CDATA로 묶어 주어야 한다.
<![CDATA[ SELECT * FROM table WHERE jno < 5 ]]>

 


변수를 바인딩하자
bind tag

변수를 새롭게 바인딩하여 SQL구문에서 사용할 수있도록 한다.

값에 특정 연산이나 변형이 필요한 경우 유용하다.

<select id="searchMembers" resultType="Member">
    <bind name="pattern" value="'%' + keyword + '%'" />
    SELECT * FROM members
    WHERE name LIKE #{pattern}
</select>

keword라는 변수값 앞뒤에 %가 추가되어 name 필드에 대해 검색이 가능하다.

쌍따옴표 안의 문자열을 표시하기 위해 작은 따옴표를 사용하여 결합시킨다.

 


조건문 태그
if tag

특정 조건이 true일때 해당 SQL 구문을 실행한다.

<select id="selectMembers" resultType="Member">
    SELECT * FROM members
    WHERE 1 = 1
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

age 가 null 이 아닐때 실행되는 조건문.

 

choose , when , otherwise tag

if / else if / else 와 같은 역할을 하며 , 조건 선택문이다.

여러 조건중 하나만 선택하여 실행 할 수 있다.

choose로 상위 태그를 만든후 when , otherwise를 사용

<select id="selectMembersByStatus" resultType="Member">
    SELECT * FROM members
    WHERE 1 = 1
    <choose>
        <when test="status == 'active'">
            AND is_active = 1
        </when>
        <when test="status == 'inactive'">
            AND is_active = 0
        </when>
        <otherwise>
            AND is_active IS NOT NULL
        </otherwise>
    </choose>
</select>

status 가 active 라면 , AND is_active = 1

status 가 inactive 라면 , AND is_active = 0

status 가 다른 문자열이라면 , AND is_active is not null 이 추가된다

 

 

where tag

where 조건을 동적으로 생성하도록 도와주는 태그

where 태그는 자동으로 첫번째 and 를 생략하고 필요한 경우에만 where 구문을 추가한다.

<select id="selectMembersByDynamicConditions" resultType="Member">
    SELECT * FROM members
    <where>
        <if test="name != null">name = #{name}</if>
        <if test="age != null">AND age = #{age}</if>
        <if test="status != null">AND status = #{status}</if>
    </where>
</select>

 

 

 


 

반복문 태그
foreach tag

 

리스트나 배열과 같은 반복가능한 형태의 컬랙션을 반복하여 SQL 구문을 생성할 때 사용한다.

in 조건이나 여러값을 동적으로 설정할 때 유용하다.

  • 배열을 사용할 경우
<select id="selectMembersByIds" resultType="Member">
    SELECT * FROM members
    WHERE id IN
    <foreach collection="idList" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

idList라는 배열을 이용하여 value를 돌리는 케이스다.

예를들어 idList = [1,2,3] 이라면 , where id in(1,2,3)으로 생성된다.

 

  • Map을 사용할 경우
<foreach collection="mapName" item="value" index="key" open="(" separator="," close=")">
    #{key} = #{value}
</foreach>

item 속성에 맵의 키 - 값쌍중 하나의 값을 반복적으로 이용할 이름을 지정한다

collection : 사용할 맵의 이름
index : 각 항목의 를 나타내는 변수명
item : 반복시 각 항목의 을 나타내는 변수명
open,seperator,close : 쿼리 앞 뒤의 구문과 반복 구문간의 구분자 설정

 

 


업데이트문 태그
set tag

update 문에서 사용되는 태그로 , 여러 필드를 조건에 따라 업데이트 할 때 유용하다.

자동으로 쉼표 관리를 도와준다.

<update id="updateMember" parameterType="Member">
    UPDATE members
    <set>
        <if test="name != null">name = #{name},</if>
        <if test="age != null">age = #{age},</if>
        <if test="status != null">status = #{status}</if>
    </set>
    WHERE id = #{id}
</update>

name , age , status 중 값이 null이 아닌것만 업데이트된다.

마지막 쉼표는 자동으로 관리된다.

 


자동 생성되는 키값을 사용해보자
AUTO_INCREMENT

selectKey tag

mybatis 에서 자동 생성되는 키값을 사용해야하는 경우 활용되는 태그.

주로 insert문에서 사용되며 , 데이터베이스에서 자동으로 생성되는 기본키 primary key 값을 받아와

다른 필드나 쿼리에서 사용할 수 있도록 한다.

주요 기능과 속성
자동 증가 키 : 데이터베이스에서 자동으로 증가시키는 기본 키값을 사용할 때 , selectKey를 통해 방금 삽입한 레코드의 키값을 가져온다.
사전 / 사후 처리 : selectKey의 order 속성을 통해 기본 키값을 삽입전 또는 삽입후에 가져올 수 있다.
키 값을 변수로 바인딩 : keyProperty 속성에 지정한 변수명에 키값을 바인딩하여 이후에 사용 가능할 수 있도록 설정한다.

keyProperty : 자동 생성된 키값을 저장할 변수의 이름 지정
resultType : 반환되는 키의 데이터 타입 , 보통 int , long , String등이 사용됨.
order : before 와 after 중에 하나를 지정하며 , insert 문 실행 전이나 후에 키값을 조회할지 결정한다.

 

  • insert 에 키값을 지정하는 경우
<insert id="insertMember" parameterType="Member">
    <selectKey keyProperty="id" resultType="int" order="BEFORE">
        SELECT COALESCE(MAX(id), 0) + 1 FROM members
    </selectKey>
    INSERT INTO members (id, name, age)
    VALUES (#{id}, #{name}, #{age})
</insert>

selectKey를통해 member의 id중 가장 큰값에서 1을 더한후 id 라는 keyProperty 로 지정한 변수(id)로 바인딩.

이후 바인딩된 id를 사용하여 insert를 진행.

 

  • insert 에 키값을 지정하는 경우
<insert id="insertMember" parameterType="Member" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO members (name, age)
    VALUES (#{name}, #{age})
</insert>

useGeneratedKeys="true" keyProperty="id" 를 사용하여

insert 이후에 id라는 변수에 값이 할당됨으로 , 자동으로 증가된 키값을 할당받을 수 있다.

MyBatis에서 INSERT 문을 사용해 데이터를 삽입할 때 기본 키인 id가 자동 증가(AUTO_INCREMENT) 설정이 되어 있다면, id 값을 직접 바인딩하지 않아도 된다.

즉, 데이터베이스가 자동으로 id 값을 생성해주기 때문에 개발자가 id 필드를 굳이 명시적으로 다룰 필요는 없다.

  • 방금 삽입된 레코드의 id가 필요한 경우

id 값이 다른 연산에서 즉시 필요할 수 있다.

예를 들어, 새로 삽입된 회원의 id를 로그에 기록하거나 다른 테이블과 연관 지어야 하는 경우가 있다.

  • 다른 테이블에 id를 사용해 연관된 데이터를 추가해야 하는 경우

예를 들어, members 테이블에 새로운 회원을 추가한 후, 해당 id를 참조하는 member_details 테이블에 관련 데이터를 추가하는 경우가 있다.

 

 

 


공통되는 쿼리를 모듈화하자
sql , include tag

공통으로 사용할 SQL구문을 다른 쿼리에 삽입할 때 유용하다.

코드의 중복을 줄일 수 있다.

<!-- 공통 검색 조건 정의 -->
<sql id="searchCondition">
    <if test="name != null">AND name = #{name}</if>
    <if test="age != null">AND age = #{age}</if>
</sql>

<!-- 쿼리에서 include로 호출 -->
<select id="selectMembersWithCondition" resultType="Member">
    SELECT * FROM members
    WHERE 1=1
    <include refid="searchCondition" />
</select>

 

sql 태그의 id 속성 : 해당 sql 태그를 부르기 위한 고유 id
include 태그의 refid 속성 : sql 태그의 고유 id를 참조하여 sql문을 삽입.