iBATIS SQL Maps(二)
来源:互联网 发布:淘宝哪个店买李宁正品 编辑:程序博客网 时间:2024/06/05 15:13
让我们重回到车辆管理系统和张三的故事中。
在 iBATIS SQL Maps 的世界里也存在 one-to-many、 many-to-one 的关系,想必你已经对这些概念驾轻就熟了。好!还是每个People 对应多条 AutoInfo 信息。
本系列文章第一部分提到过 iBATIS SQL Maps的映射文件个数可以人为设定,但是,把一组有共性的操作放在一起是首选策略。下面我们看看为张三首次买车所生成的映射文件是怎样的:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
" http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="AutoMag">
<insert id="insertPeople" parameterClass="bo.People">
<![CDATA[
insert into people (name, address) values (#name#, #address#)
]]>
<selectKey resultClass="java.lang.Integer" keyProperty="id">
<![CDATA[
select last_insert_id();
]]>
</selectKey>
</insert>
<insert id="insertAutoInfo" parameterClass="bo.AutoInfo">
<![CDATA[
insert into auto_info (license_plate, owner_no) VALUES (#licensePlate#, #ownerNo.id#)
]]>
</insert>
</sqlMap>
sqlMap
sqlMap 元素拥有属性 namespace="…" ,定义了该 XML 文件命名空间。如果你在配置文件SqlMapConfig.xml 中指定了settings 元素的属性 useStatementNamespaces="true" ,那么就可以按照命名空间的方式访问Mapped statement ,比如namespace=" AutoMag" ,相应 Java 代码: sqlMap.insert("AutoMag.insertPeople",people)。这样做是为了防止不同映射文件中出现同名 Mapped statement而产生冲突。什么是 Mapped statement?
Mapped statement
iBATIS SQL Maps 的核心概念就是Mapped statement !Mapped Statement 可以使用任意的SQL 语句,利用 POJO 、 原始变量 及其 Wrapper Class作为输入( parameter class)和输出( result class)。
Mapped Statement 包含以下几种类型:
insert 对应数据库的insert 操作,该操作返回本次操作插入记录的主键值。
select 对应数据库的select 操作,该操作返回特定的POJO 或 对象。
update 对应数据库的update 操作,该操作返回被更新的记录个数。
delete 对应数据库的delete 操作,该操作返回被删除的记录个数。
procedure 对应数据库存储过程。
statement 类型最为通用,可以代替以上所有的类型。但由于缺乏操作直观性故不推荐。
insert id="insertPeople" parameterClass="bo.People"
定义了 insert类型的 Mapped Statement。属性 id="insertPeople"定义操作名称, parameterClass="bo.People"定义传入参数为 People对象实例,框架可确保其属性持久化到数据库相应字段中。由于 SQL 语句会包含 “<>”这样的符号,容易和 XML 产生冲突,放进 <![CDATA[…… ]]> 区域就可避免。insert into people (name, address) values (#name#, #address#), 是一条普通的SQL 语句, “#name# 、 #address#”利用 Java 反射机制访问People 对象实例的相应属性。
selectKey resultClass="java.lang.Integer" keyProperty="id"
iBATIS SQL Maps 通过 <insert> 元素的子元素 <selectKey> 来支持主键自动生成。 resultClass="java.lang.Integer" 定义返回对象为int 的 Wrapper Class 。keyProperty="id" 定义了主键名称。本例是MySQL 主键生成方式,参考官方文档,MySQL 的主键生成无需人为来控制,也就是说可不使用<selectKey> 而由数据库自动处理。但我测试发现,在执行insert 操作以后,程序没有返回本次操作插入记录的主键值。在官方论坛上也有很多用户提出这样的疑惑,作者的答复是:这和 JDBC Driver 有关系。不可能把驱动一一测试吧?一劳永逸的办法是使用 <selectKey> 元素。以下是 Oracle 和 SQL Server主键生成方法:
< !- Oracle ->
<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 ->
<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>
insert into auto_info (license_plate, owner_no) VALUES (#licensePlate#, #ownerNo.id#)
在插入了 people记录后,要为 auto_info插入记录。基本原则和之前遇到过的一样,只是 ” owner_no” 这个字段值由AutoInfo 对象属性 ” ownerNo” 获得,该属性类型为People 。这是由于我沿用了Hibernate 产生的 POJO ,如果你愿意,完全可以把 ” ownerNo” 替换为Integer 类型。
编程中几个关键对象
com.ibatis.common.resources.Resources 对象负责从XML 得到 java.io.Reader 抽象类的实例,供工厂方法调用。
com.ibatis.sqlmap.client.SqlMapClientBuilder构造 SqlMapClient 实例。
com.ibatis.sqlmap.client.SqlMapClient 是 iBATIS SQL Maps 核心组件,可以说我们的编程工作都是围绕着它展开。
形成的 one-to-many保存如下:
package test;
import java.io.Reader;
import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;
import bo.*;
public class AutoMag {
private Reader reader;
private SqlMapClient sqlMap;
private String resource = "SqlMapConfig.xml";
public void insertPeople() throws Exception{
try{
reader = Resources.getResourceAsReader(resource);
sqlMap=SqlMapClientBuilder.buildSqlMapClient(reader);
sqlMap.startTransaction();
People people=new People();
people.setName("张三");
people.setAddress("中国");
sqlMap.insert("insertPeople",people);
AutoInfo autoInfo=new AutoInfo();
autoInfo.setLicensePlate("A00001");
autoInfo.setOwnerNo(people);
sqlMap.insert("insertAutoInfo",autoInfo);
sqlMap.commitTransaction();
}finally{
sqlMap.endTransaction();
}
}
}
程序和 Hibernate写法差不多,我感觉甚至比 Hibernate更简单。我可以显示的进行 insert操作,符合传统 JDBC 编程习惯。 iBATIS SQL Maps 支持自动事务处理,可以不用写明 startTransaction 、 commitTransaction 。但如果 People insert 操作成功,而 AutoInfo insert 操作失败,就破坏了两次 insert 操作的原子性。最后 endTransaction 包含异常情况下的回滚事务和关闭连接池连接两种功能。
请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处:http://www.blogjava.net/rosen
- iBATIS SQL Maps(二)
- iBATIS SQL Maps(二)
- iBATIS SQL Maps(二)
- iBATIS SQL Maps(一)
- iBATIS SQL Maps(三)
- iBATIS SQL Maps(四)
- iBATIS SQL Maps(一)
- iBATIS SQL Maps(一)
- iBATIS SQL Maps(三)
- iBATIS SQL Maps(一)
- iBATIS SQL Maps(三)
- iBATIS SQL Maps(一)
- iBATIS SQL Maps(四)
- iBATIS SQL Maps入门教程
- iBATIS SQL Maps-入门教程
- iBATIS SQL Maps 入门教程
- iBatis SQL Maps详解
- iBATIS SQL Maps之Mapped Statements。
- Ubuntu 下Sublime Text 2 输入中文解决方法
- nginx php file not found 错误
- iBATIS SQL Maps(三)
- sub- 如substring简写sub
- iBATIS SQL Maps(一)
- iBATIS SQL Maps(二)
- iBATIS SQL Maps(四)
- asderwsde,寻找其中的一个子字符串比如sde的个数
- Hibernate、iBATIS 与 BLOB
- fopen
- partition
- 函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移(快慢指针)
- OpenWRT
- subversion 访问被拒绝