转载

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

下面的例子将展示如何编写SELECT语句中使用动态SQL。考虑,我们已经在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 | |  2 | Roma       | Ali       |   3000 | |  3 | Noha       | Ali       |   7000 | +----+------------+-----------+--------+ 3 row in set (0.00 sec)

Employee 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>标记和这个标签定义,我们将定义一个“id”,这将被用于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,然后将相应的编号(二)返回的记录,否则将返回所有记录。

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的表达式来消除其他元素。

  • if 语句

  • choose, when, otherwise 语句

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

这条语句会提供功能的可选的文本搜索类型。如果没有传递title,那么所有激活的博客将被退回。但是,如果传递一个标题,它会寻找标题以like 给定的条件。 

可以包括多个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>    <if test="author != null">       AND author like #{author}    </if> </select>

choose, when, otherwise 语句:

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>
   
正文到此结束
Loading...