iBATIS的动态SQL

2018-12-09 11:01 更新

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

如果你想查询的地方,我们可以选择一个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语句。想想,我们有以下EMPLOYEE表中的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)
);

让我们假设这个表只有一个记录如下 -

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

员工PO​​JO类

要执行读操作,让我们有一个Employee类Employee.java如下 -

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这个标签定义标记内,我们将定义将在IbatisReadDy.java用于上执行动态SQL SELECT查询的“身份证”数据库。

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

传递的smc.queryForList(“Employee.findByID”,NULL)尝试上面的例子。

iBATIS的OGNL表达式

iBATIS的提供基于强大的OGNL表达式来消除其他元素。

  • 如果声明
  • 选择的时候,否则声明
  • 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>

这种说法提供了功能一个可选的文本搜索类型。如果你没有冠军擦肩而过,那么所有激活的博客被返回。但是,如果你传递一个标题,它会寻找与给定的条件下一个冠军。

您可以包括多个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的提供了一个选择元素,它类似于Java的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。此外,如果该内容开头ANDOR,它知道剥离其关闭。

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>

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号