iBATIS-動的SQL

動的SQLはiBATISの非常に強力な機能です。パラメータオブジェクトの状態に基づいて、WHERE句の基準を変更しなければならない場合があります。このような状況では、iBATISは、マップされたステートメント内で使用できる一連の動的SQLタグを提供して、SQLの再利用性と柔軟性を強化します。

すべてのロジックは、いくつかの追加タグを使用して.XMLファイルに配置されます。以下は、SELECTステートメントが2つの方法で機能する例です。

  • 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>
..................

従業員の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)
);

このテーブルには、次のように1つのレコードしかないと仮定します。

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>タグを追加し、このタグ定義内に、動的SQLSELECTクエリを実行するために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ステートメントは2つの方法で機能します-

  • 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)

iBATISOGNL式

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ステートメントに似た要素。多くのオプションから1つのケースのみを選択するのに役立ちます。

次の例では、タイトルが提供されている場合はタイトルのみで検索し、提供されている場合は著者のみで検索します。どちらも提供されていない場合は、注目のブログのみが返されます-

<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には1つの簡単な変更を加えた簡単なソリューションがあり、すべてが正常に機能します-

<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>