一个 SQL Map XML 映射文件可以包含任意多个 Mapped Statement, Parameter Map 和 Result Map. 按照它们之间的逻辑关系 , 为您的应用合理地组织 Mapped Statement, Parameter Map 和 Result Map.
一 typeAlias 节点
<typeAlias> 节点让您为一个通常较长的、全限定类名指定一个较短的别名 .
<typeAlias alias=”shortname” type=”com.long.class.path.Class”/>
例如:
<typeAlias alias="user" type="com.ibatis.db.User"/>
二 Mapped Statements
SQL Map 的核心概念是 Mapped Statement. 否 Mapped Statement 可以使用任意的 SQL 语句 , 并拥有 Parameter Map( 输入 ) 和 Result Map( 输出 ). 如果是简单情况 , Mapped Statement 可以使用 JAVA 类来作为 Parameter 和 Result. Mapped Statement 也可以使用缓存模型 , 在内存中缓存常用的数据 . Mapped Statement 的结构如下所示 :
<statement id =”statementName”
[parameterClass=”some.class.Name”]
[resultclass=”some.class.Name”]
[parameterMap=”nameOfParameterMap”]
[resultMap=”nameOfResultMap”]
[cacheModel=”nameOfCache”] >
Select * from t_user where id =[?|#propertyName#]
order by [$simpleDynamic$]
</statement>
在上面的表达式中 , 括号 [] 里的部分是可选的属性 , 并具在某些情况下只有特定的组合才是合法的 .
1)Statements节点
<statement> 节点是个通用声明,可以用于任何类型的 SQL 语句。通常,使用具体的 statement 类型是个好主意。具体 statement 类型提供了更直观的 XML DTD ,并拥有某些<statement>节点没有的特性.下表总结了statement类型及其属性和特性:
Statement 类型 |
属性 |
子元素 |
方法 |
<statement>
|
id parameterClass resultClass parameterMap resultMap cacheModel xmlResultName
|
所有的动态元素
|
insert update delete 所有的查询方法
|
<insert>
|
id parameterClass parameterMap
|
所有的动态元素 <selectKey>
|
insert update delete
|
<update>
|
id parameterClass parameterMap
|
所有的动态元素
|
Insert Update delete
|
<delete>
|
id parameterClass resultClass parameterMap resultMap cacheModel
|
所有的动态元素
|
所有的查询方法
|
<select>
|
id parameterClass resultClass parameterMap resultMap cacheModel
|
所有的动态元素
|
所有的查询方法
|
<procedure>
|
id parameterClass resultClass parameterMap resultMap xmlResultName
|
所有的动态元素
|
insert update delete 所有的查询方法
|
2)Sql 语句
SQL 显然是 Mapped Statement 中最重要的部分 , 可以使用对于数据库和 JDBC DRIVER 合法的任意 SQL 语句 . 只要在 JDBC DRIVER 支持 , 可能使用任意的函数 , 甚至是多条语句 . 因为 SQL 语句是嵌在 XML 文档中的 , 因此有些特殊的字符不能直接使用 , 例如大于号和小于号 (<>). 幸运的是 , 解决的办法很简单 , 只需将包含特殊字符的 SQL 语句放在 XML 的 CDATA 区里面就可以了 . 例如 :
- <statement id = "getUserArrayById" parameterClass="int"
- resultClass="user">
- <![CDATA[
- SELECT * FROM T_USER WHERE id > #value#
- group by id
- ]]>
- </statement>
<statement id = "getUserArrayById" parameterClass="int" resultClass="user"> <![CDATA[ SELECT * FROM T_USER WHERE id > #value# group by id ]]> </statement>
在 DAO 里
实现如下:
- public List<User> findUserArrayById (Integer userId) throws Exception {
- init();
- List<User> list = sqlMap.queryForList("getUserArrayById", userId);
- return list;
- }
public List<User> findUserArrayById (Integer userId) throws Exception { init(); List<User> list = sqlMap.queryForList("getUserArrayById", userId); return list; }
3) 自动生成主键
很多数据库支持自动生成主键的数据类型 . 不地这通常 ( 并不总是 ) 是个私有的特性 .SQL MAP 通过 <insert> 的子节点 <selectKey> 来支持自动生成的键值 . 它同时支持预生成 ( 如 Oracle ) 和后生成两种类型 ( 如 MS-SQL server, My sql ). 下面是几个例子 .
要实现自动生成主键有两个部分的内容:
1. 建表时,将 id 定义为主键并且加上 ” auto_increment” 设置为自动增加 .
例如 :
create table ibatis_db.t_user(id int(6)
PRIMARY KEY auto_increment not null,
name varchar(15) not null, sex int(1) not null);
2 . User.xml 文件中
将
- <insert id="insertUser" parameterClass="user">
- INSERT INTO t_user(id,name,sex) VALUES(#id#,#name#,#sex#)
- </insert>
<insert id="insertUser" parameterClass="user"> INSERT INTO t_user(id,name,sex) VALUES(#id#,#name#,#sex#) </insert>
修改为:
- <!-- Oracle SEQUENCE -->
- <insert id="insertUser-ORACLE" parameterClass="user">
- <selectKey resultClass="int" keyProperty="id" type="pre">
- <![CDATA[
- SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL
- ]]>
- </selectKey>
- <![CDATA[
- INSERT INTO t_user(id,name,sex)VALUES(#id#,#name#,#sex#)
- ]]>
- </insert>
<!-- Oracle SEQUENCE --> <insert id="insertUser-ORACLE" parameterClass="user"> <selectKey resultClass="int" keyProperty="id" type="pre"> <![CDATA[ SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL ]]> </selectKey> <![CDATA[ INSERT INTO t_user(id,name,sex)VALUES(#id#,#name#,#sex#) ]]> </insert>
4) 存储过程
SQL MAP 通过 <procedure> 节点支持存储过程 . 下面的例子说明如何使用具有输出参数的存储过程 .
- <parameterMap id="swapParameters" class="map">
- <parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
- <parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
- </parameterMap>
- <procedure id="swapEmailAddresses" parameterMap="swapParameters">
- {call swap_email_address(?,?)}
- </procedure>
<parameterMap id="swapParameters" class="map"> <parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/> <parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/> </parameterMap> <procedure id="swapEmailAddresses" parameterMap="swapParameters"> {call swap_email_address(?,?)} </procedure>
5)<statement> 的子节点的属性
1.parameterClass
- <statement id="statementName" parameterClass="user">
- INSERT INTO t_user VALUES(#id#,#name#,#sex#)
- </statement>
<statement id="statementName" parameterClass="user"> INSERT INTO t_user VALUES(#id#,#name#,#sex#) </statement>
2.parameterMap
- <parameterMap id ="insert-user-param" class="user">
- <parameter property="id" />
- <parameter property="name" />
- <parameter property="sex" />
- </parameterMap>
- <statement id = "insertUser" parameterMap="insert-user-param">
- INSERT INTO T_USER (id,name, sex) VALUES (?,?,?)
- lt;/statement>
<parameterMap id ="insert-user-param" class="user"> <parameter property="id" /> <parameter property="name" /> <parameter property="sex" /> </parameterMap> <statement id = "insertUser" parameterMap="insert-user-param"> INSERT INTO T_USER (id,name, sex) VALUES (?,?,?) </statement>
3.resultClass
- <statement id="getUser" parameterClass="String" resultClass="user">
- SELECT id,
- name,
- sex
- FROM t_user
- WHERE name =#value#
- </statement>
<statement id="getUser" parameterClass="String" resultClass="user"> SELECT id, name, sex FROM t_user WHERE name =#value# </statement>
4.resultMap
- <resultMap id="get-user-result" class="user">
- <result property="id" column="id"/>
- <result property="name" column="name"/>
- <result property="sex" column="sex"/>
- </resultMap>
- <statement id ="getUserList" resultMap="get-user-result">
- select * from t_user
- </statement>
<resultMap id="get-user-result" class="user"> <result property="id" column="id"/> <result property="name" column="name"/> <result property="sex" column="sex"/> </resultMap> <statement id ="getUserList" resultMap="get-user-result"> select * from t_user </statement>
5.cacheModel
cacheModel 的属性值等于指定的 cacheModel 元素的 name 属性值 . 属性 cacheModel 定义查询 mapped statement 的缓存 . 每一个查询 mapped statement 可以使用不同或相同的
- <cacheModel id="user-cache" type="LRU">
- <flushInterval hours="24"/>
- <flushOnExecute statement="insertUser"/>
- <flushOnExecute statement="updateUser"/>
- <flushOnExecute statement="deleteUser"/>
- <property name="size" value="1000"/>
- </cacheModel>
- <statement id ="getUserList" cacheModel="user-cache">
- SELECT * FROM t_user
- </statement>
<cacheModel id="user-cache" type="LRU"> <flushInterval hours="24"/> <flushOnExecute statement="insertUser"/> <flushOnExecute statement="updateUser"/> <flushOnExecute statement="deleteUser"/> <property name="size" value="1000"/> </cacheModel> <statement id ="getUserList" cacheModel="user-cache"> SELECT * FROM t_user </statement>
上面的例子中 , 每 24 小时刷新一次 , 或当更新的操作发生时刷新 .
6.xmlResultName
当直接把查询结果映射成 XML document 时 , 属性 xmlReesultName 的值等于 XML document 根节点的名称 . 例如 :
- <select id="getUserById" parameterClass="int" resultClass="xml" xmlResultName="user">
- SELECT id ,
- name ,
- sex
- FROM t_user
- WHERE id =#value#
- </select>
<select id="getUserById" parameterClass="int" resultClass="xml" xmlResultName="user"> SELECT id , name , sex FROM t_user WHERE id =#value# </select>
调用如下 :
String str = (String) sqlMap.queryForObject("getUserById", id);
上面的查询结果将产生一个 XML document, 结构如下 :
- <?xml version="1.0" encoding="UTF-8" standalone="no"?><user><id>1</id><name>user001</name><sex>0</sex></user>
<?xml version="1.0" encoding="UTF-8" standalone="no"?><user><id>1</id><name>user001</name><sex>0</sex></user>