iBATIS-동적 SQL

동적 SQL은 iBATIS의 매우 강력한 기능입니다. 때때로 매개 변수 개체의 상태에 따라 WHERE 절 기준을 변경해야합니다. 이러한 상황에서 iBATIS는 SQL의 재사용 성과 유연성을 향상시키기 위해 매핑 된 문 내에서 사용할 수있는 일련의 동적 SQL 태그를 제공합니다.

모든 논리는 몇 가지 추가 태그를 사용하여 .XML 파일에 저장됩니다. 다음은 SELECT 문이 두 가지 방식으로 작동하는 예입니다.

  • ID를 전달하면 해당 ID에 해당하는 모든 레코드가 반환됩니다.
  • 그렇지 않으면 직원 ID가 NULL로 설정된 모든 레코드를 반환합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">

   <select id="findByID" resultClass="Employee">
      SELECT * FROM EMPLOYEE
		
      <dynamic prepend="WHERE ">
         <isNull property="id">
            id IS NULL
         </isNull>
			
         <isNotNull property="id">
            id = #id#
         </isNotNull>
      </dynamic>
		
   </select>
</sqlMap>

다음과 같이 <isNotEmpty> 태그를 사용하여 조건을 확인할 수 있습니다. 여기서 조건은 전달 된 속성이 비어 있지 않은 경우에만 추가됩니다.

..................
<select id="findByID" resultClass="Employee">
   SELECT * FROM EMPLOYEE
	
   <dynamic prepend="WHERE ">
      <isNotEmpty property="id">
         id = #id#
      </isNotEmpty>
   </dynamic>
	
</select>
..................

Employee의 ID 및 / 또는 이름을 선택할 수있는 쿼리를 원하는 경우 SELECT 문은 다음과 같습니다.

..................
<select id="findByID" resultClass="Employee">
   SELECT * FROM EMPLOYEE
	
   <dynamic prepend="WHERE ">
      <isNotEmpty prepend="AND" property="id">
         id = #id#
      </isNotEmpty>
		
      <isNotEmpty prepend="OR" property="first_name">
         first_name = #first_name#
      </isNotEmpty>
   </dynamic>
</select>
..................

동적 SQL 예

다음 예는 동적 SQL을 사용하여 SELECT 문을 작성하는 방법을 보여줍니다. MySQL에 다음과 같은 EMPLOYEE 테이블이 있습니다.

CREATE TABLE EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

이 테이블에 다음과 같이 하나의 레코드 만 있다고 가정합니다.

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
|  1 | Zara       | Ali       |   5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

직원 POJO 클래스

읽기 작업을 수행하기 위해 다음과 같이 Employee.java에 Employee 클래스가 있습니다.

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   /* Define constructors for the Employee class. */
   public Employee() {}
  
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }

   /* Here are the method definitions */
   public int getId() {
      return id;
   }
	
   public String getFirstName() {
      return first_name;
   }
	
   public String getLastName() {
      return last_name;
   }
	
   public int getSalary() {
      return salary;
   }
	
} /* End of Employee */

Employee.xml 파일

iBATIS를 사용하여 SQL 매핑 문을 정의하려면 Employee.xml에 다음과 같이 수정 된 <select> 태그를 추가하고이 태그 정의 내에 동적 SQL SELECT 쿼리를 실행하기 위해 IbatisReadDy.java에서 사용할 "id"를 정의합니다. 데이터 베이스.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Employee">
   <select id="findByID" resultClass="Employee">
      SELECT * FROM EMPLOYEE
	
      <dynamic prepend="WHERE ">
         <isNotNull property="id">
            id = #id#
         </isNotNull>
      </dynamic>
		
   </select>
</sqlMap>

위의 SELECT 문은 두 가지 방식으로 작동합니다.

  • ID를 전달하면 해당 ID에 해당하는 레코드를 반환합니다. 그렇지 않으면 모든 레코드를 반환합니다.

IbatisReadDy.java 파일

이 파일에는 Employee 테이블에서 조건부 레코드를 읽는 응용 프로그램 수준 논리가 있습니다.

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class IbatisReadDy{
   public static void main(String[] args) throws IOException,SQLException{
   
      Reader rd=Resources.getResourceAsReader("SqlMapConfig.xml");
      SqlMapClient smc=SqlMapClientBuilder.buildSqlMapClient(rd);

      /* This would read all records from the Employee table.*/
      System.out.println("Going to read records.....");
      Employee rec = new Employee();
      rec.setId(1);

      List <Employee> ems = (List<Employee>)  
         smc.queryForList("Employee.findByID", rec);
      Employee em = null;
		
      for (Employee e : ems) {
         System.out.print("  " + e.getId());
         System.out.print("  " + e.getFirstName());
         System.out.print("  " + e.getLastName());
         System.out.print("  " + e.getSalary());
         em = e; 
         System.out.println("");
      }    
      System.out.println("Records Read Successfully ");
   }
}

컴파일 및 실행

위에서 언급 한 소프트웨어를 컴파일하고 실행하는 단계는 다음과 같습니다. 컴파일 및 실행을 진행하기 전에 PATH 및 CLASSPATH를 적절하게 설정했는지 확인하십시오.

  • 위와 같이 Employee.xml을 만듭니다.
  • 위와 같이 Employee.java를 생성하고 컴파일합니다.
  • 위와 같이 IbatisReadDy.java를 생성하고 컴파일합니다.
  • IbatisReadDy 바이너리를 실행하여 프로그램을 실행하십시오.

다음 결과를 얻고 EMPLOYEE 테이블에서 레코드를 읽습니다.

Going to read records.....
   1  Zara  Ali  5000
Record Reads Successfully

위의 예를 통과하여 시도하십시오. nullas smc.queryForList ( "Employee.findByID", null) .

iBATIS OGNL 표현식

iBATIS는 대부분의 다른 요소를 제거하기 위해 강력한 OGNL 기반 표현식을 제공합니다.

  • if 문
  • 선택,시기, 그렇지 않으면
  • where 문
  • foreach 문

if 문

동적 SQL에서 수행하는 가장 일반적인 작업은 조건부로 where 절의 일부를 포함하는 것입니다. 예를 들면-

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.
	
   <if test="title != null">
      AND title like #{title}
   </if>
	
</select>

이 명령문은 선택적 텍스트 검색 유형의 기능을 제공합니다. 제목없이 전달하면 모든 활성 블로그가 반환됩니다. 그러나 제목을 전달하면 주어진 제목이있는 제목을 찾습니다.like 질환.

여러 개를 포함 할 수 있습니다. if 다음과 같은 조건-

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.
	
   <if test="title != null">
      AND title like #{title}
   </if>
	
   <if test="author != null">
      AND author like #{author}
   </if>
	
</select>

선택,시기 및 기타 진술

iBATIS는 chooseJava의 switch 문과 유사한 요소입니다. 여러 옵션 중 하나만 선택하는 데 도움이됩니다.

다음 예제는 제목이 제공되는 경우 제목으로 만 검색하고 제공되는 경우 작성자로만 검색합니다. 둘 다 제공되지 않으면 추천 블로그 만 반환합니다.

<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
   WHERE state = 'ACTIVE.
	
   <choose>
      <when test="title != null">
         AND title like #{title}
      </when>
		
      <when test="author != null and author.name != null">
         AND author like #{author}
      </when>
		
      <otherwise>
         AND featured = 1
      </otherwise>
   </choose>
	
</select>

Where 문

조건이 충족되지 않으면 어떻게되는지 이전 예제를 살펴보십시오. 당신은 다음과 같은 SQL로 끝날 것입니다-

SELECT * FROM BLOG
WHERE

이것은 실패 할 것이지만 iBATIS는 하나의 간단한 변경으로 간단한 솔루션을 가지고 있으며 모든 것이 잘 작동합니다.

<select id="findActiveBlogLike" parameterType="Blog" resultType="Blog">
   SELECT * FROM BLOG
	
   <where>
      <if test="state != null">
         state = #{state}
      </if>
		
      <if test="title != null">
         AND title like #{title}
      </if>
		
      <if test="author != null>
         AND author like #{author}
      </if>
   </where>
	
</select>

그만큼 where요소 는 포함하는 태그가 콘텐츠를 반환하는 경우에만 WHERE를 삽입합니다 . 또한 해당 콘텐츠가 AND 또는 OR로 시작 하면 제거해야합니다.

foreach 문

foreach 요소를 사용하면 컬렉션을 지정하고 요소 본문 내에서 사용할 수있는 항목 및 인덱스 변수를 선언 할 수 있습니다.

또한 열기 및 닫기 문자열을 지정하고 반복 사이에 배치 할 구분 기호를 추가 할 수 있습니다. 당신은 만들 수 있습니다IN 다음과 같은 조건-

<select id="selectPostIn" resultType="domain.blog.Post">
   SELECT *
   FROM POST P
   WHERE ID in
	
   <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
      #{item}
   </foreach>
	
</select>