根据官网上的开发指南,按照个人使用习惯,频度等整理的,没啥特别的东西。
笑着--胖胖兰学习笔记iBatis入门
一, iBatis简介
iBatis是一种数据库持续层的ORM框架。使用简单的XML配置文件将Java Bean映射成PreparedStatement的输入参数和ResultSet结果集。
在不是很复杂的情况下,我们甚至可以使用HashMap而不是Java Bean来映射PreparedStatement的输入参数和ResultSet结果集,从而节省开发时间与成本。或者,我们可以使用一些辅助工具来帮助我们通过XML配置生成对应的Java Bean.
二, iBatis工作原理,流程
iBatis使用简单的XML描述文件将Java Bean,Map实现和基本数据类型的包装类(String,Integer等)映射成JDBC的PreparedStatement的输入参数和ResultSet结果集。具体工作流程如下:
1.在sqlMapConfig的XML配置文件中进行数据库连接的配置,XML配置文件名称任意,比如sql-map-config.xml
2.在sqlMapConfig的XML配置文件中引用sqlMap的XML配置文件
<sqlMap resource="examples/sqlmap/maps/Person1.xml" />
<sqlMap url="file:///c:/config/Customer.xml " />
3.在sqlMap的XML配置文件中进行SQL文的配置,文件名称任意,比如Person1.xml
4.通过SqlMapClientBuilder生成具体的操作sqlMap配置文件中SQL文的IBATIS对象SqlMapClient
String resource = "config/ibatis/sql-map-config.xml";
Reader reader = Resources.getResourceAsReader (resource);
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
5.SqlMapClient对象提供函数,函数的参数对应替换sqlMap配置文件中的id,parameter等等属性,完成SQL文的执行。具体参照iBatis的API
public List queryForList(String statementName, Object parameterObject,
int skipResults, int maxResults)
statement:sqlMap配置中id属性,parameterObject:sqlMap配置中parameterXXX属性
iBatis的工作重点在于配置文件的做成上,尤其sqlMap配置文件的做成是我们需要重点学习的。
三, SqlMapConfig.xml
配置例子如下,各个标签的说明参考官方文档。比较容易理解,这里不做整理
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
<typeAlias alias="order" type="testdomain.Order"/>
<transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
<property name="JDBC.DefaultAutoCommit" value="true" />
<property name="Pool.MaximumActiveConnections" value="10"/><property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan" value="1"/>
<property name="Pool.PingConnectionsNotUsedFor" value="1"/>
</dataSource>
</transactionManager>
<sqlMap resource="examples/sqlmap/maps/Person.xml" />
<sqlMap url="file:///c:/config/Customer.xml " />
</sqlMapConfig>
以上,主要注意DB连接情报的配置方法,采用了Java的标准Properties文件。
<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />
然后在XML中引用properties文件中的定义。
<property name="JDBC.Driver" value="${driver}"/>
四, SqlMap.xml总体印象
较复杂的例子:
<sqlMap id=”Product”>
<cacheModel id=”productCache” type=”LRU”>
<flushInterval hours=”24”/>
<property name=”size” value=”1000” />
</cacheModel>
<typeAlias alias=”product” type=”com.ibatis.example.Product” />
<parameterMap id=”productParam” class=”product”>
<parameter property=”id”/>
</parameterMap>
<resultMap id=”productResult” class=”product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<select id=”getProduct” parameterMap=”productParam”
resultMap=”productResult” cacheModel=”product-cache”>
select * from PRODUCT where PRD_ID = ?
</select>
</sqlMap>
以上例子简化版:
<sqlMap id=”Product”>
<select id=”getProduct” parameterClass=” com.ibatis.example.Product”
resultClass=”com.ibatis.example.Product”>
Select
PRD_ID as id,
PRD_DESCRIPTION as description
From PRODUCT
Where PRD_ID = #id#
</select>
</sqlMap>
五, Statement语法,类型,及其属性和特点
1.语法
<statement
id=”statementName”
[parameterClass=”some.class.Name”]
[resultClass=”some.class.Name”]
[parameterMap=”nameOfParameterMap”]
[resultMap=”nameOfResultMap”]
[cacheModel=”nameOfCache”]
>
select * from PRODUCT where PRD_ID = [?|#propertyName#] order by [$simpleDynamic$]
</statement>
[]内为可选项,不是必须存在的。
2.Statement类型,属性,特点
六, 关于映射时输入值的匹配问题
1. 类SqlMapClient如何从SqlMap的配置文件中找到对应的SQL文
通过类函数的参数statementName与配置文件中statement配置的id相匹配
2. bean中的数据如何映射给SQL文中对应的输入参数
a. 通过参数变量名称与bean中对应属性名称相匹配
<statement id=”statementName” parameterClass=” examples.domain.Product”>
insert into PRODUCT values (#id#, #description#, #price#)
</statement>
b. 通过参数变量的出现顺序相匹配
<parameterMap id=”insert-product-param” class=”com.domain.Product”>
<parameter property=”id”/>
<parameter property=”description”/>
</parameterMap>
<statement id=”insertProduct” parameterMap=”insert-product-param”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>
3. map中的数据如何映射给SQL文中对应的输入参数
a. 通过参数变量名称与map中对应key相匹配
<statement id=”statementName” parameterClass=” java.util.Map”>
insert into PRODUCT values (#id#, #description#, #price#)
</statement>
HashMap hm = new HashMap();
hm.put(“id”,”value”);
hm.put(“description”,”value”);
hm.put(“price”,”value”);
sqlMapClient.queryForList(“statementName”, hm,…………);
4. 基本数据类型的数据如何映射给SQL文中对应的输入参数
基本数据类型与参数1对1,没啥匹配的问题。不过官方的开发指南中强调参数要写成#value#这种写法,原因不明。
<statement id=”insertProduct” parameter=”java.lang.Integer”>
select * from PRODUCT where PRD_ID = #value#
</statement>
七, 关于映射时返回值的匹配问题
1. 查询结果如何映射给bean中的对应属性
a. 通过查询结果的字段名称与bean中对应属性名称相匹配
<statement id=”getProduct” resultClass=”com.ibatis.example.Product”>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #value#
</statement>
官方的开发指南中说这种写法叫做隐式ResultMap
b. 指定查询结果的字段名称与bean中对应属性名称的映射关系
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”subCode” column=”PRD_SUB_CODE” nullValue=”-999”/>
</resultMap>
以上,数据类型通过反射与对应的属性类型自动匹配,极少数时候可能需要通过resultMap的javaType属性进行设定,参考后面关于Result Map外部形式中各个参数的说明
2. 查询结果如何设定给Map
a. 通过查询结果的字段名称与map中对应key相匹配
<resultMap id=”get-product-result” class=”java.util.HashMap”>
<result property=”id” column=”PRD_ID”/>
<result property=”code” column=”PRD_CODE”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”suggestedPrice” column=”PRD_SUGGESTED_PRICE”/>
</resultMap>
<statement id=”getProductCount” resultClass=”java.util.HashMap”>
select * from PRODUCT
</statement>
b. 指定查询结果的字段名称与bean中对应属性名称的映射关系
与bean基本相同,参考使用bean作为返回结果的写法
3. 查询结果如何映射给基本数据类型
只能指定一个返回值,名字可以随便,一般采用value,val等
<resultMap id=”get-product-result” class=”java.lang.String”>
<result property=”value” column=”PRD_DESCRIPTION”/>
</resultMap>
或者
<statement id=”getProductCount” resultClass=”java.lang.Integer”>
select count(1) as value
from PRODUCT
</statement>
八, 关于Parameter Map外部形式中各个参数的说明
<parameterMap id=”parameterMapName” [class=”com.domain.Product”]>
<parameter
property =”propertyName”
[jdbcType=”VARCHAR”]
[javaType=”string”]
[nullValue=”NUMERIC”]
[null=”-9999999”]/>
<parameter …… />
<parameter …… />
</parameterMap>
1.JdbcType
属性jdbcType用于显式地指定给本属性(property)赋值的数据库字段的数据类型。对于某些特定的操作,如果不指定字段的数据类型,某些JDBC Driver无法识别字段的数据类型。
正常情况下,只有当字段可以为NULL时才需要jdbcType属性。另一需要指定jdbcType属性的情况是字段类型为日期时间类型的情况。因为Java只有一个Date类型(java.util.Date),而大多数SQL数据库有多个-通常至少有3种。因此,需要指定字段类型是DATE还是DATETIME。
注意!当使用Oracle Driver时,如果没有给可以为NULL的字段指定jdbcType属性,当试图给这些字段赋值NULL时,会出现“Invalid column type”错误。
2.javaType
属性javaType用于显式地指定被赋值参数Java属性的类名。正常情况下,这可以通过反射从Java Bean的属性获得
3.nullValue, null
用于指定NULL的替换值。就是说,当Java Bean的属性值等于指定值时,相应的字段将赋值NULL。这个特性允许在应用中给不支持null的数据类型(即int,double,float等)赋值null。当这些数据类型的属性值匹配null值(即匹配-9999)时,NULL将代替null值写入数据库。
一个完整的例子
<parameterMap id=”insert-product-param” class=”com.domain.Product”>
<parameter
property=”id”
jdbcType=”NUMERIC”
javaType=”int”
nullValue=”-9999999”/>
<parameter
property=”description”
jdbcType=”VARCHAR”
nullValue=”NO_ENTRY”/>
</parameterMap>
<statement id=”insertProduct” parameterMap=”insert-product-param”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>
简化写法
<statement id=”insertProduct” parameterClass=”com.domain.Product”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id:NUMERIC#, #description:VARCHAR#);
</statement>
或者:
<statement id=”insertProduct” parameterClass=”com.domain.Product”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);
</statement>
九, Result Map外部形式中各个参数的说明
<resultMap id=”resultMapName” class=”some.domain.Class” [extends=”parent-resultMap”]>
<result property=”propertyName” column=”COLUMN_NAME”
[columnIndex=”1”]
[javaType=”int”]
[jdbcType=”NUMERIC”]
[nullValue=”-999999”]
[select=”someOtherStatement”]
/>
<result ……/>
<result ……/>
<result ……/>
</resultMap>
1. columnIndex
属性columnIndex是可选的,用于改善性能。属性columnIndex的值是ResultSet中用于赋值Java Bean属性的字段次序号。在99%的应用中,不太可能需要牺牲可读性来换取性能。使用columnIndex,某些JDBC Driver可以大幅提高性能,某些则没有任何效果。
2.javaType
属性javaType用于显式地指定被赋值的Java Bean属性的类型。正常情况下,这可以通过反射从Java Bean的属性获得,但对于某些映射(例如Map和XML document),框架不能通过这种方法来获知。如果没有设置javaType,同时框架也不能获知类型信息,类型将被假定为Object。
3.jdbcType,nullValue, null
同Parameter Map
4.select
属性select用于描述对象之间的关系,并自动地装入复杂类型(即用户定义的类型)属性的数据。属性select的值必须是另外一个mapped statement元素的名称。在同一个result元素中定义的数据库字段(column属性)以及property属性,将被传给相关的mapped statement作为参数。因此,字段的数据类型必须是SQL Map支持的简单数据类型。关于简单数据类型和复杂类型之间映射/关系的信息,参照后面章节更详细的讨论。
具体参考稍后关于复杂类型属性的例子
十, 复杂类型属性说明
1.关于复杂类型属性的例子
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”category” column=”PRD_CAT_ID” select=”getCategory”/>
</resultMap>
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
<result property=”id” column=”CAT_ID”/>
<result property=”description” column=”CAT_DESCRIPTION”/>
</resultMap>
<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>
select * from PRODUCT where PRD_ID = #value#
</statement>
<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>
select * from CATEGORY where CAT_ID = #value#
</statement>
避免N+1 Select(1:1)
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
<result property=”category.id” column=”CAT_ID” />
<result property=”category.description” column=”CAT_DESCRIPTION” />
</resultMap>
<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>
select *
from PRODUCT, CATEGORY
where PRD_CAT_ID=CAT_ID
and PRD_ID = #value#
</statement>
2.关于复杂类型级和属性的例子
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
<result property=”id” column=”CAT_ID”/>
<result property=”description” column=”CAT_DESCRIPTION”/>
<result property=”productList” column=”CAT_ID” select=” getProductsByCatId”/>
</resultMap>
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>
select * from CATEGORY where CAT_ID = #value#
</statement>
<statement id=”getProductsByCatId” parameterClass=”int” resultMap=”get-product-result”>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
避免N+1 Select(1:1)
暂时无解,在新版本中可能会对应
3.组合键值或多个复杂参数属性
<resultMap id=”get-order-result” class=”com.ibatis.example.Order”>
<result property=”id” column=”ORD_ID”/>
<result property=”customerId” column=”ORD_CST_ID”/>
<result property=”payments” column=”{itemId=ORD_ID, custId=ORD_CST_ID}”
select=” getOrderPayments”/>
</resultMap>
<statement id=”getOrderPayments” resultMap=”get-payment-result”>
select * from PAYMENT
where PAY_ORD_ID = #itemId#
and PAY_CST_ID = #custId#
</statement>
十一, 在查询statement中指定cacheModel属性
<cacheModel id="product-cache" type ="LRU" readOnly=”true” serialize=”false”>
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”cache-size” value=”1000” />
</cacheModel>
<statement id=”getProductList” cacheModel=”product-cache”>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
1.Serializable可读写缓存
正如您所知道的,只对当前Session有效的缓存对整体应用性能的提高作用有限。Serializable可读写缓存可以提高整体应用(而不仅仅是每个Session)的性能。这种缓存为每一个Session返回缓存对象不同的实例(复本)。因此每一个Session都可以安全修改返回的对象。不同之处在于,通常您希望从缓存中得到同一个对象,但这种情况下得到的是不同的对象。还有,每一个缓冲在Serializable缓存的对象都必须是Serializable的。这意味着不能同时使用Serializable缓存和延迟加载,因为延迟加载代理不是Serializable的。想知道如何把Serializable缓存,延迟加载和联合查询结合起来使用,最好的方法是尝试。要使用Serializable缓存,设置readOnly=“false”和serialize=“true”。缺省情况下,缓存是只读模式,不使用Serializable缓存。只读缓存不需要Serializable。
2.Type
a.type=”MEMORY”
MEMORY cache实现只认识一个<property>元素。这个名为“reference-type”属性的值必须是STRONG,SOFT和WEAK三者其一。这三个值分别对应于JVM不同的内存reference类型。
<property name=”reference-type” value=”WEAK” />
b.type=”LRU”
LRU Cache实现用“近期最少使用”原则来确定如何从Cache中清除对象。
<property name=”cache-size” value=”1000” />
c.type=”FIFO”
FIFO Cache实现用“先进先出”原则来确定如何从Cache中清除对象。
<property name=”size” value=”1000” />
d.type=” OSCACHE” 没用过,没研究过。这个不太懂,哈
OSCACHE Cache实现是OSCache2.0缓存引擎的一个Plugin。它具有高度的可配置性,分布式,高度的灵活性。
OSCACHE实现不使用property元素,而是在类路径的根路径中使用标准的oscache.properties文件进行配置。在oscache.properties文件中,您可以配置Cache的算法(和上面讨论的算法很类似),Cache的大小,持久化方法(内存,文件等)和集群方法。
要获得更详细的信息,请参考OSCache文档。OSCache及其文档可以从OpenSymphony网站上获取:
http://www.opensymphony.com/oscache/
十二, 动态Mapped Statement
<select id="dynamicGetAccountList"
cacheModel="account-cache"
resultMap="account-result"
>
select * from ACCOUNT
<isGreaterThan prepend="and" property="id" compareValue="0">
where ACC_ID = #id#
</isGreaterThan>
order by ACC_LAST_NAME
</select>
上面的例子中,根据参数bean“id”属性的不同情况,可创建两个可能的语句。如果参数“id”大于0,将创建下面的语句:
select * from ACCOUNT where ACC_ID = ?
或者,如果“id”参数小于等于0,将创建下面的语句:
select * from ACCOUNT
1.二元条件元素
二元条件元素将一个属性值和一个静态值或另一个属性值比较,如果条件为“真”,元素体的内容将被包括在查询SQL语句中。
二元条件元素的属性:
prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
property - 被比较的属性(必选)
compareProperty - 另一个用于和前者比较的属性(必选或选择compareValue)
compareValue - 用于比较的值(必选或选择compareProperty)
<isEqual>
比较属性值和静态值或另一个属性值是否相等。
<isNotEqual>
比较属性值和静态值或另一个属性值是否不相等。
<isGreaterThan>
比较属性值是否大于静态值或另一个属性值。
<isGreaterEqual>
比较属性值是否大于等于静态值或另一个属性值。
<isLessThan>
比较属性值是否小于静态值或另一个属性值。
<isLessEqual>
比较属性值是否小于等于静态值或另一个属性值。
例子:
<isLessEqual prepend=”AND” property=”age” compareValue=”18”>
ADOLESCENT = ‘TRUE’
</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)。
例子:
<isNotEmpty prepend=”AND” property=”firstName” >
FIRST_NAME=#firstName#
</isNotEmpty>
3.其他元素
Parameter Present:这些元素检查参数对象是否存在。
Parameter Present的属性:
prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
<isParameterPresent>
检查是否存在参数对象(不为null)。
<isNotParameterPresent>
检查是否不存在参数对象(参数对象为null)。
例子:
<isNotParameterPresent prepend=”AND”>
EMPLOYEE_TYPE = ‘DEFAULT’
</isNotParameterPresent>
4.Iterate:这属性遍历整个集合,并为List集合中的元素重复元素体的内容。
Iterate的属性:
prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
property - 类型为java.util.List的用于遍历的元素(必选)
open - 整个遍历内容体开始的字符串,用于定义括号(可选)
close -整个遍历内容体结束的字符串,用于定义括号(可选)
conjunction - 每次遍历内容之间的字符串,用于定义AND或OR(可选)
<iterate>
遍历类型为java.util.List的元素。
例子:
<iterate prepend=”AND” property=”userNameList”
open=”(” close=”)” conjunction=”OR”>
username=#userNameList[]#
</iterate>
注意:使用<iterate>时,在List元素名后面包括方括号[]非常重要,方括号[]将对象标记为List,以防解析器简单地将List输出成String。
一, 注意事项
1.关于特殊字符
因为SQL语句是嵌在XML文档中的,因此有些特殊的字符不能直接使用,例如大于号和小于号(<>)。幸运的是,解决的办法很简单,只需将包含特殊字符的SQL语句放在XML的CDATA区里面就可以了。例如:
<statement id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person">
<![CDATA[
SELECT *
FROM PERSON
WHERE AGE > #value#
]]>
</statement>
2.关于多个SqlMap.xml中id冲突问题
问题描述:
当sql-map-config中引用多个sqlmap.xml,多个sqlmap.xml中存在相同的statementname的时候,ibatis如何判断当前我准备使用哪一个sqlmap.xml中的statementname对应的sql语句
解决方法:
在SqlMapConfig.xml中的settings标签中存在一个属性useStatementNamespaces当这个设定为true的时候,那么iBatis通过SqlMap.xml的namespace.id来查找对应的sql文id,从而避免这个问题。
二, 其他
1.自动生成的主健
<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">
<selectKey resultClass="int" keyProperty="id" >
SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL
</selectKey>
insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)
values (#id#,#description#)
</insert>
<!— Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
insert into PRODUCT (PRD_DESCRIPTION)
values (#description#)
<selectKey resultClass="int" keyProperty="id" >
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
2.调用存储过程
<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> SELECT @@IDENTITY AS ID
十五, Sample
1.java类,生成iBatis数据库操作对象
public class MyAppSqlConfig {
private static final SqlMapClient sqlMap;
static {
try {
String resource = “com/ibatis/example/sql-map-config.xml”;
Reader reader = Resources.getResourceAsReader (resource);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException (“”);
}
}
public static getSqlMapInstance () {
return sqlMap;
}
}
2.配置文件:略
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bluesmile979/archive/2009/01/14/3776797.aspx