iBATIS - SQL động

SQL động là một tính năng rất mạnh của iBATIS. Đôi khi bạn phải thay đổi tiêu chí mệnh đề WHERE dựa trên trạng thái của đối tượng tham số của bạn. Trong những tình huống như vậy, iBATIS cung cấp một tập hợp các thẻ SQL động có thể được sử dụng trong các câu lệnh được ánh xạ để nâng cao khả năng tái sử dụng và tính linh hoạt của SQL.

Tất cả logic được đưa vào tệp .XML bằng cách sử dụng một số thẻ bổ sung. Sau đây là một ví dụ trong đó câu lệnh SELECT sẽ hoạt động theo hai cách:

  • Nếu bạn chuyển một ID, thì nó sẽ trả về tất cả các bản ghi tương ứng với ID đó.
  • Nếu không, nó sẽ trả về tất cả các bản ghi nơi ID nhân viên được đặt thành 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>

Bạn có thể kiểm tra một điều kiện bằng thẻ <isNotEmpty> như sau. Ở đây, một điều kiện sẽ chỉ được thêm vào khi một thuộc tính được truyền không trống.

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

Nếu bạn muốn một truy vấn trong đó chúng tôi có thể chọn một id và / hoặc tên của một Nhân viên, câu lệnh SELECT của bạn sẽ như sau:

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

Ví dụ về SQL động

Ví dụ sau đây cho thấy cách bạn có thể viết câu lệnh SELECT với SQL động. Hãy xem xét, chúng ta có bảng EMPLOYEE sau trong MySQL:

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

Giả sử bảng này chỉ có một bản ghi như sau:

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

Lớp POJO nhân viên

Để thực hiện thao tác đọc, hãy để chúng ta có một lớp Employee trong Employee.java như sau:

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

Tệp Employee.xml

Để xác định câu lệnh ánh xạ SQL bằng iBATIS, chúng tôi sẽ thêm thẻ <select> đã sửa đổi sau đây vào Employee.xml và bên trong định nghĩa thẻ này, chúng tôi sẽ xác định một "id" sẽ được sử dụng trong IbatisReadDy.java để thực hiện truy vấn CHỌN SQL động trên cơ sở dữ liệu.

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

Câu lệnh SELECT ở trên sẽ hoạt động theo hai cách:

  • Nếu bạn chuyển một ID, thì nó sẽ trả về các bản ghi tương ứng với ID đó. Ngược lại, nó trả về tất cả các bản ghi.

Tệp IbatisReadDy.java

Tệp này có logic mức ứng dụng để đọc các bản ghi có điều kiện từ bảng Nhân viên -

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 ");
   }
}

Biên dịch và Chạy

Dưới đây là các bước để biên dịch và chạy phần mềm nói trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiến hành biên dịch và thực thi.

  • Tạo Employee.xml như hình trên.
  • Tạo Employee.java như hình trên và biên dịch nó.
  • Tạo IbatisReadDy.java như hình trên và biên dịch nó.
  • Thực thi nhị phân IbatisReadDy để chạy chương trình.

Bạn sẽ nhận được kết quả sau và một bản ghi sẽ được đọc từ bảng EMPLOYEE.

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

Hãy thử ví dụ trên bằng cách chuyển nulldưới dạng smc.queryForList ("Employee.findByID", null) .

iBATIS OGNL Biểu thức

iBATIS cung cấp các biểu thức dựa trên OGNL mạnh mẽ để loại bỏ hầu hết các yếu tố khác.

  • nếu Tuyên bố
  • chọn, khi nào, nếu không thì Tuyên bố
  • Tuyên bố ở đâu
  • Tuyên bố foreach

Câu lệnh if

Điều phổ biến nhất cần làm trong SQL động là bao gồm có điều kiện một phần của mệnh đề where. Ví dụ -

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

Câu lệnh này cung cấp một loại chức năng tìm kiếm văn bản tùy chọn. Nếu bạn vượt qua không có tiêu đề, thì tất cả các Blog đang hoạt động sẽ được trả lại. Nhưng nếu bạn vượt qua một tiêu đề, nó sẽ tìm kiếm một tiêu đề vớilike tình trạng.

Bạn có thể bao gồm nhiều if điều kiện như sau -

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

Các câu lệnh chọn, khi nào và nếu không

iBATIS cung cấp một choosephần tử tương tự như câu lệnh switch của Java. Nó giúp chỉ chọn một trường hợp trong số nhiều lựa chọn.

Ví dụ sau sẽ chỉ tìm kiếm theo tiêu đề nếu được cung cấp, sau đó chỉ theo tác giả nếu được cung cấp. Nếu cả hai đều không được cung cấp, nó chỉ trả về các blog nổi bật -

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

Tuyên bố về nơi

Hãy xem các ví dụ trước của chúng tôi để xem điều gì sẽ xảy ra nếu không có điều kiện nào được đáp ứng. Bạn sẽ kết thúc với một SQL trông như thế này -

SELECT * FROM BLOG
WHERE

Điều này sẽ không thành công, nhưng iBATIS có một giải pháp đơn giản với một thay đổi đơn giản, mọi thứ đều hoạt động tốt -

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

Các wherephần tử chỉ chèn WHERE khi các thẻ chứa trả về bất kỳ nội dung nào. Hơn nữa, nếu nội dung đó bắt đầu bằng hoặc HOẶC, nó sẽ biết loại bỏ nội dung đó.

Tuyên bố foreach

Phần tử foreach cho phép bạn chỉ định một tập hợp và khai báo các biến mục và chỉ mục có thể được sử dụng bên trong phần thân của phần tử.

Nó cũng cho phép bạn chỉ định chuỗi mở và đóng, đồng thời thêm dấu phân tách để đặt giữa các lần lặp. Bạn có thể xây dựng mộtIN điều kiện như sau -

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