`
lixinye0123
  • 浏览: 334061 次
  • 性别: Icon_minigender_1
  • 来自: 温州
社区版块
存档分类
最新评论

iBATIS(OR)映射框架的使用

    博客分类:
  • Java
阅读更多

iBATIS 是什么?

这一节将描述 iBATIS 中的单独的 API,以及为什么您可能使用它们,并了解 iBATIS 优于其他数据库映射框架的优点。

iBATIS 框架

简言之,iBATIS 由两个单独的框架组成。可以将 Data Mapper 框架专门用于 OR 映射,OR 映射是 Java 域对象到数据库中关系表的映射。DAO 框架为应用程序提供了一个简洁一致的访问基础数据的方法。

iBATIS Data Mapper 框架 (Data Mapper)

Data Mapper 是执行 SQL 并将结果映射回对象的框架,它使您不必手工执行此操作。

Data Mapper 框架不要求使用任何特殊版本的 Java 对象。您不必实现任何接口或生成任何代码,不必为其他一些基本对象创建子类或遵循任何奇怪的惯例,也不必学习特定于该框架的辅助查询语言。

可以使用一个简单并直接的 XML 格式来定义 iBATIS 将 Java 对象映射到数据库的方式。可以直接用 SQL 定义所需的具体查询,并有选择地使用任何特定于正使用的数据库引擎的专有 SQL。此功能允许您使用您想要的方式来映射对象和执行连接。

iBATIS Data Access Objects 框架(DAO 框架)

DAO 框架的主要目标是抽象化应用程序的数据访问层和持久层的表示方式位置,使它们远离应用程序的业务逻辑。DAO 框架允许在应用程序中定义负责数据中心操作的接口。

例如,如果应用程序使用直接的 Java Database Connectivity (JDBC) 来获得持久性,则 DAO 框架的目标是抽象这些类和接口(比如 ConnectionPreparedStatementResultSet)的使用,使它们远离应用程序,并下移到持久层中。

如果应用程序出于某种原因使用 HTTP GET 和 POST 来获得和存储数据,则 DAO 框架的用途变成抽象化类(比如 HttpUrlConnection)的使用,使它们远离应用程序的业务层。然后应用程序可以使用 DAO 接口在数据上执行操作,这些接口的实现被抽象化,远离业务逻辑。这些实现可以从数据库、Web 服务或其他任何源中获得数据。

DAO 框架不依赖于 Data Mapper 框架的使用。您可以选择在一个项目中同时使用这两个框架(成对使用它们相当不错),或者也可以单独使用每个框架。这一教程系列将展示单独使用框架和一起使用框架的好处。






iBATIS 的优点

iBATIS 优于其他一些 OR 映射工具的优点是:

  • iBATIS 没有使用它自己的专用查询语言,它只使用 SQL。一些 OR 映射工具(比如 Hibernate)除了使用 SQL 之外还使用它们自己的查询语言。
  • 所有想要执行的查询和更新都是使用 SQL 编写的(并存储在 .xml 文件中)。一些人可能认为这是一个缺点,因此想把数据库从他们那里完全抽离出来,以避免需要写入任何 SQL 代码。这也正是许多开发人员喜欢 Hibernate 的一个原因。但您可能更喜欢能够在访问对象时更好地控制具体将执行哪种 SQL,而不是愿意以某种依赖于基础 OR 映射框架的方式未曾预料地为您生成它。您可以根据数据库管理员 (DBA) 的建议,或者根据关系数据库管理系统 (RDBMS) 中提供的工具所提供的访问计划或查询优化器来调优查询或其他语句。直接访问为这一层编写的 SQL 的另一个优点是可以利用数据库所提供的任何专用 SQL。
  • iBATIS 易于使用。
  • 该项目有大量文件可以证明。
  • 它没有外部依赖性。其他一些 OR 映射框架随同装载了 15 到 20 个 .jar 文件,并依赖于这些文件的特定版本来运行框架。您不需要或者也不想在开发应用程序时遇到这类头疼问题,因此使用没有任何外部依赖性的 iBATIS 实际上是一大优点。(注意,一些可选配置允许使用外部连接工具或字节代码增强之类的东西,但这些并不是必需的。)

现在是时间深入研究一些更特殊的 iBATIS 概念和语义,这些最终会将引导我们到一些编码和示例。


BATIS Data Mapper 的语义

本教程的剩余部分以近乎专有的方式查看 Data Mapper 框架(第 2 部分将深入介绍 DAO 框架)。这一小节将介绍 Data Mapper 的语义。

Mapped Statement

Data Mapper 的核心功能是围绕 Mapped Statement 进行的。Mapped Statement 可以拥有称为 Parameter Map(基本上用于数据输入)和 Result Map(数据输出)的框架。因此 Mapped Statement 实质上是一个 XML 元素,该元素包含负责执行某些操作并将输入/输出参数映射到 Java 对象的 SQL 语句。清单 3 显示了一个简单的来自 JPetStore 演示版的 SQL Mapped Statement(请参阅参考资料,获得到该下载的链接)。


清单 3. 一个简单的 SQL Mapped Statement
<select id="getUsernameList" 
resultClass="string"
parameterClass="account">
select USERNAME as value from SIGNON
</select>

清单 3 中的 Mapped Statement 负责查询 SIGNON 表中的 USERNAME 列的所有值。有几种不同类型的 Mapped Statement。正如您所看到的,此特殊 Mapped Statement 是一个 <select>。除了 <select> 之外,还可以在使用 iBATIS 框架时使用 <statement><insert><update><delete><procedure> Mapped Statement 元素。iBATIS 文档更详细地介绍了每个元素(请参阅参考资料,获得到 iBATIS 的 Web 站点的链接)。






Parameter Map 和内联参数

iBATIS 框架中的 Parameter Map 为 Mapped Statement 提供数据输入参数。Parameter Map 不常被使用并且是自发地使用(通常使用内联参数),但清单 4 显示了一个它们如何工作的示例,其中有一个来自文档的示例 Parameter Map 和 Mapped Statement。


清单 4. iBATIS 框架中的 Parameter Map
<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>

您可以看到,清单 4 中的 Mapped Statement 根据名称引用 Parameter Map,它包含两个占位符问号。(您将认识这些占位符,以 JDBC PreparedStatement 的标准占位符的形式。)它将从 Parameter Map 中获得的值按它们被定义的顺序应用于这些占位符。

清单 4 中的 Parameter Map 定义了 com.domain.Product 类的 id 属性 getId(),将它映射到使用此 Parameter Map 的任何 Mapped Statement 的第一个占位符(问号)。它继续(使用下一个参数元素)声明 com.domain.Product 类的 description 属性 getDescription(),将它映射到使用 Parameter Map 的任何 Mapped Statement 中的第二个占位符(问号)。在 parameterMap 中,parameter 元素的显示顺序与将它们应用于使用 parameterMap 的 Mapped Statement 中的占位符问号的顺序相同。

更常见的是使用内联参数映射输入参数(参见清单 5)。


清单 5. 内联参数
<statement id="insertProduct" parameterClass="com.domain.Product">
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id#, #description#);
</statement>

此语法使用 com.domain.Product 类中的 getId() 返回的值替换 #id#,而 #description#com.domain.Product 类的 getDescription() 返回的值替换。您可以查看 iBATIS 文档,了解如何指定 null 值。






Result Map

Result Map 类似于 Parameter Map,但它用于输出。Result Map 允许您定义将 Mapped Statements(通常是一些查询)映射回 Java 对象的方式。清单 6 提供了来自 iBATIS 文档的一个示例的快速查看。


清单 6. Result Map
<resultMap id="get-product-result" class="com.domain.Product">
<result property="id" column="PRD_ID"/>
<result property="description" column="PRD_DESCRIPTION"/>
</resultMap>

<statement id="getProduct" resultMap="get-product-result">
select * from PRODUCT
</statement>

您可以看到,具有 getProductid 的 Mapped Statement 明确地引用 Result Map 的授权 get-product-result,告诉 Mapped Statement 将 PRD_ID 数据库列映射到 com.domain.Product 类的 JAVAid 属性,还声明将 PRD_DESCRIPTION 数据库列映射到 com.domain.Product 类的 JAVAdescription 属性。

我总是喜欢指定我将要选择的具体列,而不是使用(比如说)SELECT * FROM






TransactionManager

Data Mapper 框架中的 TransactionManager 元素允许在给定配置的情况下按您希望的对事务服务进行配置。此元素的当前受支持类型是:

  • JDBC - JDBC 事务管理器通过 java.sql.Connection 接口的 commit()rollback() 方法内部控制事务。
  • JTA - 使用一个全局 Java Transaction API (JTA) 事务,并要求 UserTransaction 通过 Java Naming and Directory Interface (JNDI) 或其他任何方法变得可用。
  • EXTERNAL - 用户可以自己管理事务。对于必须自己以任何方式管理所有事务的非事务性数据而言,这是一个不错的选择。

此教程系列的第 3 部分将更详细地查看这些事务。

配置 Derby 和 iBATIS

这一节将介绍设置基本 Derby 和 iBATIS 配置并使其运行需要做的所有事情。(正如前面所提到的,本教程将介绍 Data Mapper 框架并保存 Data Access Object 配置,将它们用于第 2 部分。)

JAR 文件

将 Apache Derby 和 iBATIS 放在一起使用的最重要的一件事是减少依赖性。在这里,您所需要的东西是运行 Derby 的 derby.jar 文件,以及 ibatis-common-2.jar 和 ibatis-sqlmap-2.jar 文件。(如果正在使用 DAO 框架,那么还需要 ibatis-dao-2.jar 文件,但本教程中没有介绍该文件。)

注意,如果想利用 iBATIS 的一些额外的功能,比如字节代码增强或集中式/分布式缓存,那么还需要包含 iBATIS 使用的库(在这里分别是 CGLIB 和 OS Cache)。这些额外的组件通常是不必要的。






配置文件

iBATIS 很少要求设置配置文件并运行它们。Data Mapper 框架需要一个 XML 配置文件(通常称为 sql-map-config.xml),该文件定义了与事务管理有关的项,以及如何连接到数据库。指定包含 Mapped Statements、Result Map 等事项的 .xml 文件列表也是在这里进行的。快速浏览一下将在本教程的简单示例中使用的 sql-map-config.xml 文件(参见清单 7)。


清单 7. sql-map-config.xml
<!DOCTYPE sqlMapConfig PUBLIC
"-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="properties/database.properties"/>

<settings cacheModelsEnabled="true" enhancementEnabled="false"
maxSessions="64" maxTransactions="8" maxRequests="128"/>

<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property value="${driver}" name="JDBC.Driver"/>
<property value="${url}" name="JDBC.ConnectionURL"/>
<property value="${username}" name="JDBC.Username"/>
<property value="${password}" name="JDBC.Password"/>
<property value="15" name="Pool.MaximumActiveConnections"/>
<property value="15" name="Pool.MaximumIdleConnections"/>
<property value="1000" name="Pool.MaximumWait"/>
</dataSource>
</transactionManager>

<sqlMap resource="net/humandoing/invoicing/domain/sql/Sequence.xml"/>
<sqlMap resource="net/humandoing/invoicing/domain/sql/Product.xml"/>
</sqlMapConfig>

清单 7 中,只有一个描述映射的 .xml 文件,在这里该文件是 Product.xml。通常,将在几个文件中定义此信息,然后每个域对象大致分到一个 .xml 文件。此外,要注意 XML 文件引用数据库属性文件的方式,该文件包含如何连接到数据库的信息。清单 8 显示了一个示例 database.properties 文件。


清单 8. 一个 database.properties 文件
####################################
# Database Connectivity Properties
####################################

driver=org.apache.derby.jdbc.EmbeddedDriver
url=jdbc:derby:c:/temp/ibatis
username=
password=


在这里,只提供了 iBATIS 的嵌入式 Derby 驱动程序的完全限定名称以及一个有效的 JDBC URL。不需要指定用户名和口令,因为在这个示例中没有涉及安全性。

除了清单 7 中的配置文件外,Data Mapper 框架惟一需要的是任何一种为描述数据库查询以及对象与数据库之间的映射方式而定义的 .xml 文件。接下来的小节将讨论用于示例应用程序的 Product.xml 文件。

尽管在本教程中不会使用到,但 DAO 框架仍然需要一个简单的 .xml 配置文件(通常称为 dao.xml),并包含一个项列表,这些项类似于 Data Mapper 配置中的那些项。这一节中包含一些事务管理信息以及 DAO 接口与实现所组成的对的列表(本教程系列的第 2 部分将更详细地讨论这些)。






为 Derby 设置 iBATIS

因为将使用 Derby 的嵌入式模式,且 iBATIS 抽象了所有数据库访问,所以只需要向正确的驱动程序和正确的数据库 URL 提供 iBATIS 即可。iBATIS 启动数据库,然后在任何对 iBATIS 框架进行特定于数据库的调用时提供对数据库的访问。

完成这一简单设置之后,就为使用 Data Mapper 框架构建一个简单的示例应用程序做好了准备。

测试 Derby 和 iBATIS

当您完成本教程系列的第 1 部分中的操作时,将在第 2 部分和第 3 部分中使用 JPetStore 应用程序。JPetStore 应用程序是一个示例 iBATIS 应用程序,可以从 iBATIS 框架中下载它。如果想获得一些额外的知识或想了解一下 iBATIS,可从 iBATIS 的 Web 站点下载它(请参阅参考资料 来获得链接)。

现在,您已经了解了 iBATIS 的一些基础知识和它的一些概念,因此可以在一个小的示例中好好运用一下。在这一节中,将创建一个简单的 Product 类和一个 Sequence 类。可以将 Sequence 类用作定义产品的惟一键的主键生成器。接下来将带领您一个示例组件接一个示例组件地进行查看,在这一小节的最后,会将这些示例组件组合在一起。

定义对象

首先,定义您想一直用于数据的 Java 对象。这里没什么特别之处,因为 iBATIS 不要求扩展任何超类或实现任何接口。清单 9 定义了 Sequence 类。


清单 9. Sequence 类
public class Sequence {
private String sequenceName;
private int nextId;

public Sequence(String sequenceName, int nextId) {
this.nextId = nextId;
this.sequenceName = sequenceName;
}

public Sequence() {
}

public int getNextId() {
return nextId;
}

public void setNextId(int nextId) {
this.nextId = nextId;
}

public String getSequenceName() {
return sequenceName;
}

public void setSequenceName(String sequenceName) {
this.sequenceName = sequenceName;
}
}

清单 10 显示了 Product 类。


清单 10. Product 类
public class Product {
private int productId;
private String productName;
private String productDesc;
private int quantity;

public Product(int productId, String productName,
String productDesc,int quantity) {
this.productDesc = productDesc;
this.productId = productId;
this.productName = productName;
this.quantity = quantity;
}

public Product() {
}

public int getProductId() {
return productId;
}

public void setProductId(int productId) {
this.productId = productId;
}

public String getProductName() {
return productName;
}

public void setProductName(String productName) {
this.productName = productName;
}
//...
}

正如您可以看到的,这两个类都只是具有 getter/setter 方法和少数成员的普通 JavaBeans。因为想要这些映射到数据库的某些表的类,所以现在要定义一些数据库表。






定义表

您需要一个表来存储产品,还需要一个从中获得产品并增加产品序列的另一个表,可将该序列用作主键。清单 11 显示了 Derby 很友好地为您维护的数据模型。


清单 11. 数据模型
CREATE TABLE SEQUENCE
(
SEQUENCE_NAME VARCHAR(32) NOT NULL,
NEXT_ID INTEGER NOT NULL,
CONSTRAINT SEQ_PK PRIMARY KEY (SEQUENCE_NAME)
);

CREATE TABLE PRODUCT (
PRODUCT_ID INTEGER,
PRODUCT_NAME VARCHAR(128),
PRODUCT_DESC VARCHAR(512),
QUANTITY INTEGER,
CONSTRAINT PROD_PK PRIMARY KEY (PRODUCT_ID)
);


INSERT INTO SEQUENCE (SEQUENCE_NAME, NEXT_ID)
VALUES ('ProductSeq', 1000);

现在有了一个 SEQUENCE 表,可从该表中选择产品并增加产品序列,生成 PRODUCT 表的主键。您已经在 SEQUENCE 表中插入了一行,并且将从产品序列 1000 开始操作。您还有一个 PRODUCT 表,该表包含描述某一产品的一些典型属性(但并没有包含所有属性)的少数列。






创建 SQL Map

现在需要创建描述您想要在 ProductSequence 对象上执行的数据库操作的 SQL Map。这些数据库操作通常包括插入、查询、更新和删除。

清单 12 显示了用于 Product 类的 SQL Map。


清单 12. 用于 Product 类的 SQL Map
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Product">

<typeAlias alias="product"
type="net.humandoing.invoicing.domain.Product"/>

<resultMap id="productResult" class="product">
<result property="productId" column="PRODUCT_ID"/>
<result property="productName" column="PRODUCT_NAME"/>
<result property="productDesc" column="PRODUCT_DESC"/>
<result property="quantity" column="QUANTITY"/>
</resultMap>

<update id="updateProduct" parameterClass="product">
update PRODUCT set PRODUCT_NAME = #productName#,
PRODUCT_DESC = #productDesc#,
QUANTITY = #quantity# where
PRODUCT_ID = #productId#
</update>

<select id="getProduct" resultMap="productResult"
parameterClass="product">
select PRODUCT_ID, PRODUCT_NAME, PRODUCT_DESC, QUANTITY
from PRODUCT where PRODUCT_ID = #productId#
</select>

<insert id="insertProduct" parameterClass="product">
insert into PRODUCT (product_id, product_name, product_desc, quantity)
values (#productId#, #productName#, #productDesc#, #quantity#)
</insert>

</sqlMap>

注意 typeAlias 元素。它只允许通过更短的别名(在这里是 product)而不是完全限定类名称来引用类。

清单 12 中还可以看到有一个 resultMap 元素,该元素描述您想要将通过执行某一查询获得的将 ResultSet 映射到 Product 对象的方式。这一特殊的 resultMap 将数据库中的 PRODUCT_ID 列映射到 Product 类的 productId 属性,并将数据库中的 PRODUCT_NAME 列映射到 Product 类的 productName 属性,依此类推。

现在来快速查看一下用于 Sequence 类的 SQL Map,如清单 13 中所示。


清单 13. 用于 Sequence 类的 SQL Map
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="Sequence">

<typeAlias alias="sequence"
type="net.humandoing.invoicing.domain.Sequence"/>

<resultMap id="sequenceResult" class="sequence">
<result property="sequenceName" column="SEQUENCE_NAME"/>
<result property="nextId" column="NEXT_ID"/>
</resultMap>

<select id="getSequence" resultMap="sequenceResult"
parameterClass="sequence">
select SEQUENCE_NAME, NEXT_ID from SEQUENCE
where SEQUENCE_NAME = #sequenceName#
</select>

<update id="updateSequence" parameterClass="sequence">
update SEQUENCE set NEXT_ID = #nextId#
where SEQUENCE_NAME = #sequenceName#
</update>

</sqlMap>

这里有两个 Mapped Statement:一个用来获得序列,一个用来更新序列。还有一个 resultMap 元素,该元素描述如何将 SEQUENCE 表列映射到 Sequence Java 对象。






测试代码

为了让一切顺利,所有测试都作为 Ant build 文件的少数目标包含在内。因此可以通过执行这些目标来运行测试。在运行测试之前,要查看一下 sql-map-config.xml 文件,该文件将初始化 Data Mapper 框架,以便使用其 sql-map-config.xml 文件(参见清单 14)。


清单 14. sql-map-config.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="properties/database.properties"/>

<settings cacheModelsEnabled="true" enhancementEnabled="false"
maxSessions="64" maxTransactions="8" maxRequests="128"/>

<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property value="${driver}" name="JDBC.Driver"/>
<property value="${url}" name="JDBC.ConnectionURL"/>
<property value="${username}" name="JDBC.Username"/>
<property value="${password}" name="JDBC.Password"/>
<property value="15" name="Pool.MaximumActiveConnections"/>
<property value="15" name="Pool.MaximumIdleConnections"/>
<property value="1000" name="Pool.MaximumWait"/>
</dataSource>
</transactionManager>

<sqlMap resource="net/humandoing/invoicing/domain/sql/Sequence.xml"/>
<sqlMap resource="net/humandoing/invoicing/domain/sql/Product.xml"/>

</sqlMapConfig>

该配置简单而又直接。iBATIS 文档有少数一些例外示例,该文档更详细地描述了配置元素。主要需要注意的是,您将从位于 properties/database.properties(相对于类路径的根路径)的文件中获得数据库连接信息,还要注意的是通知 Data Mapper 您将加载两个不同的 SQL Map:SequenceProduct

清单 15 显示了获得已启动的 Data Mapper 框架所需的少数几行 Java 源代码(从 Test 类中获得)。注意,大多数代码由异常处理组成。


清单 15. 获得已启动的 Data Mapper 框架所涉及的 Java 源代码
private static SqlMapClient dataMapper = null;
//...

Reader reader = null;
try {
reader = Resources.getResourceAsReader(
"net/humandoing/invoicing/domain/sql/sql-map-config.xml");
dataMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (Exception e) {
e.printStackTrace();
}

清单 15 中一些重要的位是用粗体显示的。Reader 只是一个使用 Resources 实用程序类的 java.io.Reader,它使文件更易于为您所用,该实用程序类是随 iBATIS 一起提供的,用于从类路径中获得 sql-map-config.xml。

SqlMapClient 实例用于长期存在的对象(可能用于应用程序的整个生命周期),因此可能需要一个用于此实例的某个地方的静态初始化器 (static initializer),然后允许通过静态 getInstance() 方法类型或通过将实例绑定到 JNDI 中来访问该实例。

现在来查看来自与 Data Mapper 框架进行交互的 Test 类的其他少数代码片段,然后查看一些屏幕捕获,其中包括来自 Ant 测试目标的输出。

以下是一个用于 Sequence 的查询:

Sequence sequence = new Sequence("ProductSeq", -1);
sequence = (Sequence)
dataMapper.queryForObject("getSequence", sequence);


这就是该查询,它使用序列名 ProductSeq 创建了一个 Sequence 对象。如果您记得 Mapped Statement getSequence(来自 Sequence.xml 文件),那么或许您会记得 SELECT 语句在 SEQUENCE_NAME 的基础上执行了一个查询。在这种情况下,iBATIS 框架将接管控制权,对 Derby 数据库执行以下 SQL 语句:

select SEQUENCE_NAME, NEXT_ID from SEQUENCE
where SEQUENCE_NAME = "ProductSeq"


在执行上述代码之后,您可能想保留返回的序列值,因为要用它作为 Derby 数据库中创建的新产品的主键。或许您还想通过增加 NEXT_ID 列来更新序列(参见清单 16)。


清单 16. 增加 NEXT_ID 列
int nextId = sequence.getNextId();

//Update the sequence by incrementing the NEXT_ID
//column.
sequence.setNextId(sequence.getNextId() + 1);
dataMapper.update("updateSequence", sequence);

在这里,已经将下一个有效 ID 保存到 nextId 变量中,然后增加该值并请求 Data Mapper 框架更新 Derby 中的记录。现在要创建一个产品,如清单 17 中所示。


清单 17. 创建一个产品
Product product = new Product(nextId, 
"iBATIS Sandwich",
"A Yummy Sandwich",
24);

product = (Product) dataMapper.insert("insertProduct", product);


瞧!现在有了一个也保存在该数据库中的产品。最后但非最不重要的是,执行一个查询确保该产品保存在数据库中。毕竟编程人员都是一些怀疑论者。任何易于使用的数据映射框架几乎都是看起来很好,但实际并非如此。

Product queryProd = new Product();
queryProd.setProductId(nextId);
queryProd = (Product) dataMapper.queryForObject("getProduct", queryProd);


在此查询中,创建了一个新的 Product 对象并设置 productId(将它设置为刚才插入的产品的值)。然后继续请求 Data Mapper 框架使用 getProduct 的 ID 执行 Mapped Statement,它返回一个完全填充的 Product 对象,该对象是从 Derby 数据库中查询获得的。

现在来快速查看如何可以自己运行这些测试中的一些测试。





运行测试

要做的第一件事是创建 Derby 数据库中需要的表。该示例中包含一个用于该操作的 Ant 目标。在终端窗口或 IDE 中运行 ant create-database(确保当前目录位于项目的根目录上),您将获得与图 1 中所示输出类似的东西。


图 1. 来自 create-database 目标的 Ant 输出
来自 create-database 目标的 Ant 输出

BUILD SUCCESSFUL —— 这是每个人都喜欢看到的。现在已经创建好了表,可以快速查询 PRODUCT 表,查看里面是否有东西。运行 ant get-products,它将查询 Derby 数据库的 PRODUCT 表中的所有行。您应该接收到一些类似图 2 中所示的输出。


图 2. 来自 get-products 目标的 Ant 输出
来自 get-products 目标的 Ant 输出

在这里所能看到的就是数据库中没有任何产品;可以看到一些列标题,但没有产品。现在运行一个测试,该测试获得一个 Sequence、更新它、创建一个 Product 并随后查询该产品。用于此操作的 Ant 目标是 ant run-test图 3 中显示了结果。


图 3. 来自 run-test 目标的 Ant 输出
来自 run-test 目标的 Ant 输出

您已经查询了名为 ProductSeqSequence,它有一个来自数据库的为 1000 的 NEXT_ID。然后您可以创建一个 Product图 3 中看到的输出是在已将产品插入数据库之后使用 Data Mapper 框架查询该产品所获得的结果。您可以根据自己的需要多次运行 ant run-test 目标。它会继续将 iBATIS Sandwiches 插入 Derby 数据库并继续增加序列。

最后,通过再次运行 ant get-products 目标并查询数据库来获得所有产品行,可以打消您的疑虑。可以在图 4 中查看结果。


图 4. 插入某一产品后来自 get-products 目标的输出
插入某一产品后来自 get-products 目标的输出

图 4 中可以看到,已经通过 iBATIS Data Mapper 框架将 iBATIS Sandwich 成功添加到 Derby 数据库中。


分享到:
评论

相关推荐

    ibatis and和or联合查询 .doc

    ibatis是一个支持普通SQL查询、存储过程以及高级映射的优秀开源数据访问框架。ibatis消除了几乎所有的JDBC对象操作,提供了一个简单的基本API,它通过XML或注解进行配置,将接口及Java的POJOs(Plain Old Java ...

    ibatis总结 ibatis ibatis ibatis ibatis

    - 避免在`WHERE`子句中使用多个条件或`OR`操作符,而是应该使用`IN`操作符或者`UNION ALL`合并多个查询。 3. Struts、Spring与Ibatis的集成: - Struts作为MVC框架,主要负责视图与控制器的交互。在项目中,`...

    myBatis or ibatis 神器

    标题中的“myBatis or ibatis 神器”指的是两个知名的Java持久层框架——myBatis和iBatis。这两个框架在Java开发中扮演着重要角色,它们简化了数据库操作,让开发者能够更加专注于业务逻辑,而不是底层的SQL查询。 ...

    Spring与iBATIS的集成

    他们也阐明了怎样取得你已编写的SQL语句及把他们映射给iBATIS使用的Bean。最后,还讨论了iBATIS的优缺点,及为什么是这样的一种方式,即所谓的“在完全OR与JDBC之间的一个幽雅的折衷。” &lt;br&gt;就象Developer's ...

    ibatis使用例子,源代码

    标题"ibatis使用例子,源代码"表明这是一个关于iBATIS(一个持久层框架)的实际应用示例,其中包含了可以运行的源代码。这可能是一个简单的项目,旨在帮助开发者理解如何在实际开发中使用iBATIS进行对象关系映射...

    ibatis中iterate的例子

    在Java Web开发中,iBatis(现在称为MyBatis)是一个流行的持久层框架,它提供了灵活的SQL映射机制,使得数据库操作更加便捷。在iBatis中,`&lt;iterate&gt;`标签是一个非常实用的功能,它允许我们处理集合数据,如数组、...

    ibatis Guide

    #### OR映射 ibatis支持多种对象关系映射方式,包括: - **一对多关联**:通过配置文件中的`collection`元素,将一个对象映射到多个相关对象。 - **一对一关联**:通过`association`元素,将一个对象映射到另一个...

    iBatis文档\ibatis.doc

    总结来说,iBatis是一个强大且灵活的持久层框架,它通过XML配置和Java代码实现了数据库操作的封装,提供了丰富的映射方式和事务管理策略,使得开发人员能更高效地进行数据库交互。无论是简单还是复杂的数据库操作,...

    ibatis.doc

    在对象关系映射(OR映射)上,iBATIS允许开发者在XML映射文件中定义POJO(Plain Old Java Object)与数据库表之间的映射关系。这样,Java对象的属性可以直接映射到SQL语句的占位符,反之亦然。 iBATIS的高级特性...

    ibatis2.0开发指南 ibatis开发必备

    7. **OR映射(Object-Relational Mapping)**: - iBATIS实现对象关系映射,将Java对象与数据库表的行对应起来。 - 映射规则通过`&lt;resultMap&gt;`定义,可以处理复杂的数据结构,如嵌套结果集。 8. **iBATIS高级特性...

    iBatis2.0文档

    - **外部事务管理**:当 iBatis 与其他框架一起使用时,可以使用外部事务管理器。 #### 八、缓存机制 - **MEMORY 类型缓存与 WeakReference**:MEMORY 类型缓存使用 WeakReference 来存储缓存项,以避免内存泄漏。 ...

    iBATIS 2.0 开发指南

    相较于其他 ORM(对象关系映射)框架如 Hibernate 和 Apache OJB 的“一站式”解决方案,iBATIS 提供了一种“半自动化”的 ORM 实现,允许开发者更加灵活地控制 SQL 语句的编写和执行。 #### 重要特点 - **“半...

    ibatis 开发指南

    ibatis支持多种OR映射策略,包括: - **一对多关联**:通过外键关联实现,通常使用嵌套结果或嵌套查询的方式。 - **一对一关联**:同样可以通过外键关联实现,也可以通过主键关联。 - **延迟加载**:为了提高性能,...

    ibatis_教程_详解.doc

    OR映射(Object-Relational Mapping)是Ibatis的核心特性,它将数据库表记录映射到Java对象,反之亦然。Ibatis通过标签定义映射规则,可以处理复杂的列与字段的对应关系。 在高级特性中,Ibatis支持数据关联,分为...

    ibatis_开发指南

    8. OR映射 - 对象关系映射(ORM)是iBATIS的核心特性之一,它将Java对象与数据库中的表进行映射,简化数据库操作。 9. iBATIS高级特性 - 包括数据关联(一对多、一对一)、延迟加载、动态映射、事务管理和缓存策略...

Global site tag (gtag.js) - Google Analytics