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数据库中创建存储过程:
DELIMITER $$ DROP PROCEDURE IF EXISTS `testdb`.`getEmp` $$ CREATE PROCEDURE `testdb`.`getEmp`(IN empid INT)BEGIN SELECT * FROM EMPLOYEE WHERE ID = empid;END $$ DELIMITER;
此表有如下两条记录:
mysql>select*from EMPLOYEE; +----+| id | first_name | last_name | salary | +----+|1|Zara|Ali|5000||2|Roma|Ali|3000|
Employee POJO 类:
使用iBATIS的结果映射,需要修改Employee.java文件。因此,让我们保持它,因为它已经在前一章中使用过。
public class Employee{ privateint id; private String first_name; privateString last_name; privateint salary; /* Define constructors for the Employee class. */ publicEmployee(){} publicEmployee(String fname,String lname,int salary){ this.first_name = fname;this.last_name = lname;this.salary = salary; } /* Here are the required method definitions */ publicint getId(){return id;} publicvoid setId(int id){this.id = id;} publicString getFirstName(){return first_name;} publicvoid setFirstName(String fname){this.first_name = fname;} publicString getLastName(){return last_name;} publicvoid setlastName(String lname){this.last_name = lname;} publicint getSalary(){return salary;} publicvoid setSalary(int salary){this.salary = salary;} }/* End of Employee */
Employee.xml 文件:
<?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"> parameterClass:可以采取一个值作为字符串,整型,浮点型,double或根据要求任何类的对象。 此例中,我们通过Employee对象作为参数而调用SqlMap类的insert方法。 如果数据库表使用IDENTITY,AUTO_INCREMENT或串行列或已定义的SEQUENCE/GENERATOR, 可使用<selectKey>元素在<insert>语句中使用或返回数据库生成的值,此处为使用序列作为插入数据的id值 <!-- Perform Insert Operation --> <insertid="insert"parameterClass="Employee"> INSERT INTO EMPLOYEE(first_name, last_name, salary) values (#first_name#, #last_name#, #salary#) <selectKeyresultClass="int"keyProperty="id"> select last_insert_id() as id </selectKey> </insert> <!-- Perform Delete Operation --> <deleteid="delete"parameterClass="int"> DELETE FROM EMPLOYEE WHERE id = #id# </delete> <!-- Perform Update Operation --> <updateid="update"parameterClass="Employee"> UPDATE EMPLOYEE SET first_name = #first_name# WHERE id = #id# </update> <!-- Perform Read Operation 查询结果用Employee类封装--> <selectid="getAll"resultClass="Employee"> SELECT * FROM EMPLOYEE </select> <!-- Using ResultMap 查询结果用ResultMap封装--> resultMap的元素是在iBATIS的最重要和最强大的元素。您可以通过使用iBATIS的结果映射减少高达90%的JDBC编码, 在某些情况下,可以让你做JDBC不支持的事情 <resultMapid="result"class="Employee"> <resultproperty="id"column="id"/> <resultproperty="first_name"column="first_name"/> <resultproperty="last_name"column="last_name"/> <resultproperty="salary"column="salary"/> </resultMap> <selectid="useResultMap"resultMap="result"> SELECT * FROM EMPLOYEE WHERE id=#id# </select> 使用存储过程查询: <!-- To call stored procedure. 调用数据库中创建的存储过程SQL语句--> <parameterMapid="getEmpInfoCall"class="map"> <parameterproperty="acctID"jdbcType="INT"javaType="java.lang.Integer"mode="IN"/> </parameterMap> <procedureid="getEmpInfo" parameterMap="getEmpInfoCall"resultClass="Employee"> { call getEmp( #acctID# ) } </procedure> 动态SQL查询: 动态查询是iBatis一个非常强大的功能。有时你已经改变WHERE子句条件的基础上你的参数对象的状态。 在这种情况下的iBATIS提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的动态SQL标签。 所有的逻辑是使用一些额外的标签放在:XML文件。下面是一个例子,其中的SELECT语句将努力在两个方面: 如果想传递一个ID,然后它会返回所有与该ID的记录,否则,将返回所有雇员ID为NULL的记录。 <selectid="findByID"resultClass="Employee"> SELECT * FROM EMPLOYEE <dynamicprepend="WHERE "> <isNullproperty="id">id IS NULL</isNull> <isNotNullproperty="id">id = #id#</isNotNull> </dynamic> </select> 可以使用<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> iBATIS OGNL 表达式:iBATIS的提供了强大的基于OGNL的表达式来消除其他元素。
if 语句
choose, when, otherwise 语句
where 语句
foreach 语句
if 语句:最常见的事情在动态SQL是有条件地包括一个where子句的一部分。例如:
这条语句会提供功能的可选的文本搜索类型。如果没有传递title,那么所有激活的博客将被退回。但是,如果传递一个标题,它会寻找标题以like 给定的条件。
<selectid="findActiveBlogWithTitleLike"parameterType="Blog"resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<if test="title != null">AND title like #{title}</if>
<iftest="author != null">AND author like #{author}</if>
</select>
choose, when, otherwise 语句:iBATIS提供了一个选择的元素,它类似于Java的switch语句。这有助于选择很多种情况。
<selectid="findActiveBlogWithTitleLike"parameterType="Blog"resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<choose>
<when test="title != null">AND title like #{title}</when>
<whentest="author != null and author.name != null">AND author like #{author}</when>
<otherwise>AND featured = 1</otherwise>
</choose>
</select>
where 语句 :
where元素知道只有插入WHERE ,如果有一个由含标签返回的任何内容。此外,如果该内容开头AND或OR,它知道剥离其关闭
<selectid="findActiveBlogLike"parameterType="Blog"resultType="Blog">
SELECT * FROM BLOG
<where>
<iftest="state != null">state = #{state}</if>
<iftest="title != null">AND title like #{title}</if>
<iftest="author != null>AND author like #{author}</if>
</where>
</select>
foreach 语句:
foreach元素是非常强大的,并允许你指定一个集合,声明可以在元素的体内可用于项目和索引变量。
它也允许你指定打开和关闭的字符串,并添加一个分隔符放置在迭代之间。可以建立一个IN条件如下:
<selectid="selectPostIn"resultType="domain.blog.Post">
SELECT * FROM POST P
WHERE ID in
<foreachitem="item"index="index"collection="list"
open="("separator=","close=")"> #{item}
</foreach>
</select>
</sqlMap>
IbatisResultMap.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 IbatisResultMap{ publicstaticvoid main(String[] args)throwsIOException,SQLException{ //调用工具类Resources加载Ibatis配置文件SqlMapConfig.xml(包含employee.xml文件) Reader rd =Resources.getResourceAsReader("SqlMapConfig.xml"); //调用Ibatis的接口获取SQL数据操作实例对象SqlMapClient SqlMapClient smc =SqlMapClientBuilder.buildSqlMapClient(rd); 增: Employee em =newEmployee("Zara","Ali",5000); smc.insert("Employee.insert", em); 删: int id =1; smc.delete("Employee.delete", id ); 改: Employee rec =newEmployee(); rec.setId(1); rec.setFirstName("Roma"); smc.update("Employee.update", rec ); 查: List<Employee> ems =(List<Employee>)smc.queryForList("Employee.getAll",null); int id =1; Employee e =(Employee)smc.queryForObject("Employee.useResultMap", id); //调用存储过程查询 Employee e =(Employee)smc.queryForObject("Employee.getEmpInfo", id); //动态查询 Employee rec =newEmployee(); rec.setId(1);List<Employee> ems =(List<Employee>)smc.queryForList("Employee.findByID", rec); } }
动态的对条件语句的拼接:
<!-- 动态条件查询语句组合开始 --> <sql id="sql_delete"> delete </sql> <sql id="sql_count"> select count(*) </sql> <sql id="sql_select"> select * </sql> <sql id="sql_where"> from DeviceInfo <dynamic prepend="where"> <!-- 不为空就执行 如果传过来的参数中不带有id这个参数那么将不会执行此条,会往下执行--> <isNotEmpty prepend="and" property="id"> id = #id# </isNotEmpty> <isNotEmpty prepend="and" property="deviceId"> deviceId = #deviceId# </isNotEmpty> <isNotEmpty prepend="and" property="displayModeId"> displayModeId = #displayModeId# </isNotEmpty> <isNotEmpty prepend="and" property="statuId"> statuId = #statuId# </isNotEmpty> <isNotEmpty prepend="and" property="manageId"> manageId = #manageId# </isNotEmpty> <isNotEmpty prepend="and" property="projectId"> projectId = #projectId# </isNotEmpty> <isNotEmpty prepend="and" property="creater"> creater = #creater# </isNotEmpty> <isNotEmpty prepend="and" property="createTime"> createTime = #createTime# </isNotEmpty> <isNotEmpty prepend="and" property="updater"> updater = #updater# </isNotEmpty> <isNotEmpty prepend="and" property="updateTime"> updateTime = #updateTime# </isNotEmpty> </dynamic> </sql> <!-- end --> <select id="selectDeviceByWhere" resultClass="DeviceInfo" parameterClass="Map"> <!-- 拼接SQL语句 最后组合SQL语句--> <include refid="sql_select"/> <include refid="sql_where"/> </select> <delete id="deleteByWhere" parameterClass="Map"> <include refid="sql_delete"/> <include refid="sql_where"/> </delete>
上面的代码中如果parameterClass传递过来的Map参数中,没有某一项条件所需要的参数那么久会生成不同的SQL语句。
如:
public void deleteById(int id) { if (id != 0) { map.put("id", id); getSqlMapClientTemplate().delete("deleteByWhere", map); } else { System.out.println("delete error"); } }
其他属性:
1、二元条件元素的属性:
prepend - 可被覆盖的 SQL 语句组成部分,添加在语句的前面(可选)
property - 被比较的属性(必选)
compareProperty - 另一个用于和前者比较的属性(必选或选择 compareValue)
compareValue - 用于比较的值(必选或选择 compareProperty)
<isEqual> 比较属性值和静态值或另一个属性值是否相等。
<isNotEqual> 比较属性值和静态值或另一个属性值是否不相等。
<isGreaterThan> 比较属性值是否大于静态值或另一个属性值。
<isGreaterEqual> 比较属性值是否大于等于静态值或另一个属性值。
<isLessThan> 比较属性值是否小于静态值或另一个属性值。
<isLessEqual> 比较属性值是否小于等于静态值或另一个属性值。
2、一元条件元素的属性:
prepend - 可被覆盖的 SQL 语句组成部分,添加在语句的前面(可选)
property - 被比较的属性(必选)
<isPropertyAvailable> 检查是否存在该属性(存在 parameter bean 的属性) 。
<isNotPropertyAvailable> 检查是否不存在该属性(不存在 parameter bean 的属性) 。
<isNull> 检查属性是否为 null。
<isNotNull> 检查属性是否不为 null。
<isEmpty> 检查 Collection.size()的值,属性的 String 或 String.valueOf()值,
是否为 null或空( “”或size() < 1) 。
<isNotEmpty> 检查 Collection.size()的值,属性的 String 或 String.valueOf()值,
是否不为 null 或不为空( “”或 size() > 0)。
3、Iterate:这属性遍历整个集合,并为 List 集合中的元素重复元素体的内容。
Iterate 的属性:
prepend - 可被覆盖的 SQL 语句组成部分,添加在语句的前面(可选)
property - 类型为 java.util.List 的用于遍历的元素(必选)
open - 整个遍历内容体开始的字符串,用于定义括号(可选)
close -整个遍历内容体结束的字符串,用于定义括号(可选)
conjunction - 每次遍历内容之间的字符串,用于定义 AND 或 OR(可选)
<iterate> 遍历类型为 java.util.List的元素。
根据参数值的比较拼接SQL:
<isEqual prepend="and" property="delType" compareValue="1"> ID=#id# </isEqual> <isEqual prepend="and" property="delType" compareValue="2"> NAME=#name# </isEqual> <isEqual prepend="and" property="delType" compareValue="3"> TYPE=#type# </isEqual>