6. 开发指南 iBATIS SQL Maps Page 6 of 62
安装 SQL Maps
安装 SQL Maps 很简单,只要把相关的 JAR 文件复制到类路径下即可。类路径或者是
JVM 启动是指定的类路径(java 命令参数),或者是 Web 应用中的/WEB-INF/lib 目录。Java
类路径的详尽讨论超出了本文的范围,如果您是 Java 的初学者,请参考以下的资源:
http://java.sun.com/j2se/1.4/docs/tooldocs/win32/classpath.html
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html
http://java.sun.com/j2se/1.4.2/docs/
安装 iBatis 需要在类路径下放置以下 JAR 文件:
文件名 描述 是否必需
ibatis-common.jar IBATIS 公用的工具类 是
ibatis-sqlmap.jar IBATIS SQL Maps 框架 是
ibatis-dao.jar IBATIS DAO 框架 否
JAR 文件和依赖性
如果一个框架依赖于太多的 JAR 文件,就很难与其他的应用和框架集成。IBATIS 2.0
的一个主要的关注点是管理并降低 JAR 文件的依赖性。因此,如果您用的是 JDK1.4,IBATIS
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
7. 开发指南 iBATIS SQL Maps Page 7 of 62
仅仅依赖于 Jakarta Commons Logging 框架。可选的 JAR 文件放在发布版的/lib/optional 目录
下。它们根据功能来分类。下面列表总结了何时需要使用可选 JAR 类库。
描述 何时使用 目录
1.4 以前 JDK 版本支持 如果您使用的 JDK 版本低于 /lib/optional/jdbc
1.4,并且您的应用服务器不 /lib/optional/jta
提供这些 JAR 文件,您将需 /lib/optional/xml
要这些可选的 JAR 文件
IBATIS 的向后兼容 如果您使用旧的 IBATIS 1.x) /lib/optional/compatibility
(
DAO 框架,或旧的 SQL Maps
(1.x)
运行时字节码增强 如果您需要使用 CGLIB2.0 字 /lib/optional/enhancement
节码增强来提高 lazy loading
和 reflection 的性能
DataSource 实现 如果您使用 Jakarta DBCP 连 /lib/optional/dbcp
接池
分布式缓存 如果您使用 OSCache 来支持 /lib/optional/caching
集中或分布式缓存
Log4J 日志 如果您需要使用 Log4J /lib/optional/logging
从 1.x 版本升级
是否应该升级
判断您是否需要升级的最好办法是尝试它。下面是几种升级的方法。
1. 版本 2.0 几乎完全保持和 1.x 版本的向后兼容,因此某些情况下只需用新的 JAR 文
件替代旧的即可。这个升级方法带来的好处最少,但最简单。您无需修改 XML 文
件或 Java 代码,但会存在某些不兼容的问题。
2. 第二种方法是把 1.x 的 XML 文件转换成 2.0 规范,但仍使用 1.x 的 Java API。除了
XML 映射文件存在着细微的不兼容之处外,这是个安全的方法。SQL Map 框架包
括了用来转换 XML 映射文件的 ANT Task(参见下节)。
3. 第三种方法是转换 XML 文件(和第二种方法相同)和 Java 代码。因为没有转换
Java 代码的工具,必须手工进行。
4. 第四种方法是不必升级。如果您升级有困难,可以让应用继续使用 1.x 版本。让旧
应用继续使用 1.x 版,在新应用中使用 2.0 版是个不错的主意。
转换XML配置文件(从1.x到2.0)
框架的 2.0 版本包含了一个可以在 ANT 构建环境中使用的 XML 文件转换器。虽然转换
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
8. 开发指南 iBATIS SQL Maps Page 8 of 62
XML 配置文件是可选的,但将 1.x 的配置文件转换成 2.0 仍然是个好主意。你几乎不会遇到
不兼容的文件,并且还可以使用 2.0 版本新的特性(即使您继续使用 1.x 的 Java API)
。
XML 配置文件转换器在 build.xml 文件中的例子如下:
<taskdef name="convertSqlMaps"
classname="com.ibatis.db.sqlmap.upgrade.ConvertTask"
classpathref="classpath"/>
<target name="convert">
<convertSqlMaps todir="D:/targetDirectory/" overwrite="true">
<fileset dir="D/sourceDirectory/">
<include name="**/maps/*.xml"/>
</fileset>
</convertSqlMaps>
</target>
就像您看到的一样,它和 Ant 的 copy task 很相似。事实上它就是 Ant 的 copy task 类的
子类,因此您可以用这个 task 完成任何 copy task 的功能(详细信息请参考 Ant 的 Copy task
文档)
使用新的JAR文件
要升级到 2.0,最好删除 iBatis 原有旧的 JAR 文件及其依赖 JAR 类库,并用新的 JAR
文件替代。但要主要不要删除其他组件或框架还需要的文件。请参考上节关于 JAR 类库及
其依赖性的讨论。
下表总结了旧文件及其相应的新文件。
旧文件 新文件
ibatis-db.jar ibatis-common.jar(必需)
1.2.9b 以后的版本, 这个文件被分拆成一下 3 ibatis-sqlmap.jar(必需)
个文件 ibatis-dao.jar(可选)
ibatis-common.jar
ibatis-dao.jar
ibatis-sqlmap.jar
commons-logging.jar commons-logging-1-0-3.jar(必需)
commons-logging-api.jar commons-collection-2-1.jar(可选)
commons-collection.jar commons-dbcp-1-1.jar(可选)
commons-dbcp.jar commons-pool-1-1.jar(可选)
commons-pool.jar oscache-2-0-1.jar(可选)
oscache.jar jta-1-0-1a.jar(可选)
jta.jar jdbc2_0-stdext.jar(可选)
jdbc2_0-stdext.jar xercesImpl-2-4-0.jar(可选)
xercesImpl.jar xmlParserAPIs-2-4-0.jar(可选)
xmlParserAPIs.jar xalan-2-5-2.jar(可选)
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
9. 开发指南 iBATIS SQL Maps Page 9 of 62
jdom.jar log4j-1.2.8.jar(可选)
cglib-full-2-0-rc2.jar(可选)
本文余下部分将介绍如何使用 SQL Maps 框架。
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
10. 开发指南 iBATIS SQL Maps Page 10 of 62
SQL Map XML 配置文件
SQL Map 使用 XML 配置文件统一配置不同的属性,包括 DataSource 的详细配置信息,
SQL Map 和其他可选属性,如线程管理等。以下是 SQL Map 配置文件的一个例子:
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">
<!-- Always ensure to use the correct XML header as above! -->
<sqlMapConfig>
<!-- The properties (name=value) in the file specified here can be used placeholders in this
config file (e.g. “${driver}”. The file is relative to the classpath and is completely optional. -->
<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />
<!-- These settings control SqlMapClient configuration details, primarily to do with transaction
management. They are all optional (more detail later in this document). -->
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
<!-- Type aliases allow you to use a shorter name for long fully qualified class names. -->
<typeAlias alias="order" type="testdomain.Order"/>
<!-- Configure a datasource to use with this SQL Map using SimpleDataSource.
Notice the use of the properties from the above resource -->
<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"/>
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
11. 开发指南 iBATIS SQL Maps Page 11 of 62
<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>
<!-- Identify all SQL Map XML files to be loaded by this SQL map. Notice the paths
are relative to the classpath. For now, we only have one… -->
<sqlMap resource="examples/sqlmap/maps/Person.xml" />
</sqlMapConfig>
以下详细讨论 SQL Map 配置文件的各组成部分。
<properties>元素
SQL Map 配置文件拥有唯一的<properties>元素,用于在配置文件中使用标准的 Java 属
性文件(name=value)。这样做后,在属性文件中定义的属性可以作为变量在 SQL Map 配
置文件及其包含的所有 SQL Map 映射文件中引用。例如,如果属性文件中包含属性:
driver=org.hsqldb.jdbcDriver
SQL Map 配 置 文 件 及 其 每 个 映 射 文 件 都 可 以 使 用 占 位 符 ${driver} 来 代 表 值
org.hsqldb.jdbcDriver。例如:
<property name="JDBC.Driver" value="${driver}"/>
这个元素在开发,测试和部署各阶段都很有用。它可以使在多个不同的环境中重新配置
应用和使用自动生成工具(如 ANT)变得容易。属性文件可以从类路径中加载(使用 resource
熟悉),也可以从合法的 URL 中加载(使用 url 属性)。例如,要加载固定路径的属性文件,
使用:
<properties url=”file:///c:/config/my.properties” />
<setting>元素
<setting>元素用于配置和优化 SqlMapClient 实例的各选项。<setting>元素本身及其所有
的属性都是可选的。下表列出了<setting>元素支持的属性及其功能:
maxRequests 同时执行 SQL 语句的最大线程数。大于这个值的线
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
53. 开发指南 iBATIS SQL Maps Page 53 of 62
例子5:自动提交
//当没调用 startTransaction 的情况下,statements 会自动提交。
//没必要 commit/rollback。
int rows = sqlMap.insert (“insertProduct”, product);
例子6:用结果集边界查询成对象List(select)
sqlMap.startTransaction();
List list = sqlMap.queryForList (“getProductList”, null, 0, 40);
sqlMap.commitTransaction();
例子7:用RowHandler执行查询(select)
public class MyRowHandler implements RowHandler {
public void handleRow (Object object, List list) throws SQLException {
Product product = (Product) object;
product.setQuantity (10000);
sqlMap.update (“updateProduct”, product);
// Optionally you could add the result object to the list.
// The list is returned from the queryForList() method.
}
}
sqlMap.startTransaction();
RowHandler rowHandler = new MyRowHandler();
List list = sqlMap.queryForList (“getProductList”, null, rowHandler);
sqlMap.commitTransaction();
例子8:查询成Paginated List(select)
PaginatedList list =
sqlMap.queryForPaginatedList (“getProductList”, null, 10);
list.nextPage();
list.previousPage();
例子9:查询成Map(select)
sqlMap.startTransaction();
Map map = sqlMap.queryForMap (“getProductList”, null, “productCode”);
sqlMap.commitTransaction();
Product p = (Product) map.get(“EST-93”);
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
54. 开发指南 iBATIS SQL Maps Page 54 of 62
用 Jakarta Commons Logging 记录 SQL
Map 日志
SQL Map 框架使用 Jakarta Commons Logging(JCL)记录日志信息。JCL 使用独立于具
体实现的方式提供日志服务。您可以“plug-in”包括 Log4J 和 JDK1.4 Loging API 等不同的
日志服务实现。Jakarta Commons Logging,Log4J 和 JDK1.4 Logging API 的详细规范超出了
本文档的范围。但是下面的例子可以提供一个开始使用它们的起点。如果您想知道得更多,
可以参考下面的 URL:
Jakarta Commons Logging
• http://jakarta.apache.org/commons/logging/index.html
Log4J
• http://jakarta.apache.org/log4j/docs/index.html
JDK 1.4 Logging API
• http://java.sun.com/j2se/1.4.1/docs/guide/util/logging/
配置日志服务
配 置 Commons Logging 日 志 服 务 非 常 简 单 , 只 需 加 入 几 个 配 置 文 件 ( 例 如
log4j.properties)和 JAR 文件(例如 log4j.jar)即可。下面的配置例子使用 Log4J 作为日志
服务的实现。分为两个步骤:
第一步:添加 Log4J JAR 文件
因为要使用 Log4J,我们要确保应用能使用它的 JAR 文件。记住,Commons Logging
是一个抽象的 API,并不提高日志的实现。因此,要使用 Log4J,必须将它的 JAR 文件加入
应用的类路径中。您可以从上面的 URL 下载 Log4J。对于 Web 应用,可以将 log4.jar 添加
到 WEB-INF/lib 目录下,或对于独立的应用,可以在 JVM 的-classpath 启动参数中添加。
第二步:配置 Log4J
配置 Log4J 也很简单。象 Commons Logging 一样,将配置文件添加到类路径的根目录
中(即,不要放在 package 里)。这个配置文件是 log4j.properties,例子如下:
log4j.properties
1 # Global logging configuration
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
61. 开发指南 iBATIS SQL Maps Page 61 of 62
态时会将其断开。而连接池管理器将
通过此语句检测池中连接是否可用。
它对性能的影响较大,应小心使用。
检测语句应该是一个最简化的无逻辑
SQL,如:select 1 from dual
Pool.PingEnabled 否 false 是否允许检测连接状态
Pool.PingConnectionsOlderThan 否 0 对持续连接时间超过设定值(毫秒)
的连接进行检测
Pool.PingConnectionsNotUsedFor 否 0 对空闲超过设定值(毫秒)的连接进
行检测
Driver.* 否 N/A 某些 JDBC 驱动程序支持别的配置参
数。为了给驱动程序发送这些参数,
可以在参数名前面加上“Driver.”前
缀。
例如,如果驱动程序支持配置参数
“ compressionEnabled ” 您 可 以 在
,
SimpleDataSource 把 它 设 置 为
“Driver.compressionEnabled=true”
使用 SimpleDataSource 类的例子:
DataSource dataSource = new SimpleDataSource(props); //properties usually loaded from a file
Connection conn = dataSource.getConnection();
//…..database queries and updates
conn.commit();
conn.close(); //connections retrieved from SimpleDataSource will return to the pool when closed
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译
62. 开发指南 iBATIS SQL Maps Page 62 of 62
ScriptRunner (com.ibatis.common.jdbc.*)
ScriptRunner 类用于执行 SQL 语句,例如创建数据库 schema,或插入缺省或测试数据
等。从下面的例子可以认识到它的易用性:
例子脚本:initialize-db.sql
-- Creating Tables – Double hyphens are comment lines
CREATE TABLE SIGNON (USERNAME VARCHAR NOT NULL, PASSWORD VARCHAR
NOT
NULL, UNIQUE(USERNAME));
-- Creating Indexes
CREATE UNIQUE INDEX PK_SIGNON ON SIGNON(USERNAME);
-- Creating Test Data
INSERT INTO SIGNON VALUES('username','password');
例子 1:使用现成的数据库连接
Connection conn = getConnection(); //some method to get a Connection
ScriptRunner runner = new ScriptRunner ();
runner.runScript(conn,
Resources.getResourceAsReader("com/some/resource/path/initialize.sql"));
conn.close();
例子 2:使用新的数据库连接
ScriptRunner runner = new ScriptRunner (“com.some.Driver”, “jdbc:url://db”, “login”,
“password”);
runner.runScript(conn, new FileReader("/usr/local/db/scripts/ initialize-db.sql"));
例子 3:使用新创建的数据库连接
Properties props = getProperties (); // some properties from somewhere
ScriptRunner runner = new ScriptRunner (props);
runner.runScript(conn, new FileReader("/usr/local/db/scripts/ initialize-db.sql"));
上面例子的属性文件必须包含以下属性:
driver=org.hsqldb.jdbcDriver
url=jdbc:hsqldb:.
username=dba
password=whatever
stopOnError=true
还有一些您可能会用到的方法:
// if you want the script runner to stop running after a single error
scriptRunner.setStopOnError (true);
// if you want to log output to somewhere other than System.out
scriptRunner.setLogWriter (new PrintWriter(…));
http://www.ibatis.com Clinton Begin 著 刘涛(toleu@21cn.com) 译