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> ..................
如果你想查询的地方,我们可以选择一个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)
员工POJO类
要执行读操作,让我们有一个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。此外,如果该内容开头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>
更多建议: