MyBatis之《中篇》

事务管理器
MyBatis 有两种事务管理类型(即 type=”[JDBC|MANAGED]”):
• JDBC – 这个配置直接使用 JDBC 的提交和回滚功能。它依赖于从数据源获得连接来管理 事务的生命周期。
• MANAGED – 这个配置基本上什么都不做。它从不提交或者回滚一个连接的事务。而是让 容器(例如:Spring 或者 J2EE 应用服务器)来管理事务的生命周期 。默认情况下,它 会关闭连接,但是一些容器并不会如此,因此,如果您需要通过关闭连接来停止事务,将 属性 closeConnection 设置为false。例如:
<transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager>
这两个事务管理类型都不需要任何属性。然而它们都是类型别名,换句话说,您可以设置成 指向己实现了 TransactionFactory 接口的完整类名或者别名。
public interface TransactionFactory { void setProperties(Properties props);

Transaction newTransaction(Connection conn, boolean autoCommit); }
实例化后,任何在 XML 文件配置的属性都将传递给setProperties()方法。在您的实现中还 需要创建一个非常简单的 Transaction 接口的实现:
public interface Transaction {

Connection getConnection();

void commit() throws SQLException;

void rollback() throws SQLException;

void close() throws SQLException;

}
通过这两个接口,您能够完全自定义 MyBatis 如何来处理事务。
dataSource 元素
dataSource 元素使用标准的JDBC 数据源接口来配置 JDBC 连接对象源。
大部分MyBatis 应用都像上面例子那样配置一个数据源,但这不是必须的。需要认清的 是,只有使用了延迟加载才需要数据源。
MyBatis 内置了三种数据源类型 (如: type=”????”):
UNPOOLED – 这个类型的数据源实现只是在每次需要的时候简单地打开和关闭连接。虽然有点 慢,但是对于不需要立即响应的简单的应用来说,不失为一种好的选择。不同的数据库在性能方 面也会有所不同,因此对于一些数据库,不使用连接池时,这个配置就是比较理想的。 UNPOOLED 数据源有四个配置属性:
• driver – 指定JDBC 驱动器。
• url – 连接数据库实例的 JDBC URL。
• username –登陆数据库的用户名。
• password - 登陆数据库的密码。
• • • • defaultTransactionIsolationLevel – 指定连接的默认事务隔离级别。
另外,您也可以通过在属性前加前缀“driver”的方式,把属性传递给数据库驱动器,例 如:
• • • • driver.encoding=UTF8
这将会通过 DriverManager.getConnection(url, driverProperties) 方法,将值是 “UTF8”的属性“encoding”传递给数据库驱动器。
POOLED – 这个数据源的实现缓存了JDBC 连接对象,用于避免每次创建新的数据库连接时都初始 化和进行认证,加快程序响应。并发 WEB 应用通常通过这种做法来获得快速响应。
另外,除了上面(UNPOOLED)的属性外,对 POOLED 数据源,还有很多属性可以设置。
• poolMaximumActiveConnections – 在任何特定的时间内激活(能够被使用)的连接数 量,默认是 10。
• poolMaximumIdleConnections –在任何特定的时间内空闲的连接数。

• poolMaximumCheckoutTime – 在连接池被强行返回前,一个连接能够“检出”的总时 间。默认是 20000ms(20 秒)。
• poolTimeToWait – 这是一上比较底层的设置,如果连接占用了很长时间,能够给连接池 一个机会去打印日志,并重新尝试连接。默认是20000ms(20 秒)。
• poolPingQuery –Ping Query 是发送给数据库的 Ping 信息,测试数据库连接是否良好 和是否准备好了接受请求。默认值是“NO PING QUERY SET”,让大部分数据库都不使用 Ping,返回一个友好的错误信息(译者注:MyBatis 通过向数据执行 SQL 语句来确定与数 据库连接状况)。
• poolPingEnabled – 这是允许或者禁 ping query 的开关。如果允许,您同时也要用一 条可用的(并且应该是最高效的)SQL 语句来设置poolPingQuery 属性的值。默认是: false(即禁止)。
• poolPingConnectionsNotUsedFor – 这个属性配置执行 poolPingQuery 的间隔时间。通 常设置为与数据库连接的超时时间,来避免不必要的 pings 。默认是:0(允许所有连接 随时进行 ping 测试,当然只有poolPingEnabled 设置为true 才会生效)。
JNDI – 这个数据源的配置是为了准备与像 Spring 或应用服务器能够在外部或者内部配置数据 源的容器一起使用,然后在JNDI 上下文中引用它。这个数据源只需配置两个属性:
• • • • initial_context – 这个属性被用来从 InitialContext 中查找一个上下文。如:
initialContext.lookup(initial_context)
这个属性是可选的,如果忽略,那么数据源就会直接从InitialContext 中查找。
• • • • data_source – 这个属性是引用一个能够被找到的数据源实例的上下文路径。它会查找 根据 initial_context 从 initialContext 中搜寻返回的上下文。或者在 initial_context 没有提供的情况下直接在 InitialContext 中进行查找。
跟数据源的其它属性配置一样,可以通过在属性名前加“env.”的方式直接传递给 InitialContext。例如:
• • • • env.encoding=UTF8
这将会把属性“encoding”及它的值“UTF8”在 InitialContext 实例化的时候传递给它的构 造器。
Mappers 元素 

现在,MyBatis 的行为属性都已经在上面的配置元素中配置好了,接下来开始定义映射SQL 语句。但首先,我们需要告诉 MyBatis 在哪里能够找到我们定义的映射 SQL 语句。在这方面, JAVA 自动发现没有提供好的方法,因此最好的方法是告诉MyBatis 在哪里能够找到这些映射文 件。您可以使用类资源路径或者URL(包括 file:/// URLs),例如:
// Using classpath relative resources <mappers>

<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

<mapper resource="org/mybatis/builder/BlogMapper.xml"/>

<mapper resource="org/mybatis/builder/PostMapper.xml"/>

</mappers>
// Using url fully qualified paths <mappers>

<mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>

<mapper url="file:///var/sqlmaps/BlogMapper.xml"/>

<mapper url="file:///var/sqlmaps/PostMapper.xml"/>

</mappers>
这些配置告诉 MyBatis 在哪里找到SQL 映射文件。而其它的更详细的信息配置在每一个SQL 映射文件里。这些将在下一章节里讨论。
SQL 映射 XML 文件

MyBatis 真正强大之处就在这些映射语句,也就是它的魔力所在。对于它的强大功能,SQL 映 射文件的配置却非常简单。如果您比较SQL 映射文件配置与JDBC 代码,您很快可以发现,使用 SQL 映射文件配置可以节省 95%的代码量。MyBatis 被创建来专注于SQL,但又给您自己的实现极 大的空间。

SQL 映射XML 文件只有一些基本的元素需要配置,并且要按照下面的顺序来定义(in the order that they should be defined):
• • • • cache –在特定的命名空间配置缓存。
• cache-ref – 引用另外一个命名空间配置的缓存.
• resultMap – 最复杂也是最强大的元素,用来描述如何从数据库结果集里加载对象。
• parameterMap – 不推荐使用! 在旧的版本里使用的映射配置,这个元素在将来可能会被 删除,因此不再进行描述。
• sql – 能够被其它语句重用的 SQL 块。
• insert –INSERT 映射语句
• update –UPDATE 映射语句
• delete –DELEETE 映射语句
• select –SELECT 映射语句
接下来的章节将会对每一个元素进行描述。

Select 元素 Select 是 MyBatis 中最常用的元素之一。除非您把数据取回来,否则把数据放在数据库是没 什么意义的,因此大部分的应用查询数据远多于修改数据。对每一次插入、修改、删除数据都可 能伴有大量的查询。这是 MyBatis 基本设计原则之一,也就是为什么把这么多的焦点和努力放在 查询和结果集映射上。对简单的查询,select 元素的配置是相当简单的,如:
<select id=”selectPerson” parameterType=”int” resultType=”hashmap”>

SELECT * FROM PERSON WHERE ID = #{id}

</select>
这条语句叫做 selectPerson,以 int 型(或者Integer 型)作为参数,并返回一个以数据库 列名作为键值的 HashMap。
注意这个参数的表示方法:#{id} 它告诉MyBatis 生成 PreparedStatement 参数。对于 JDBC,像这个参数会被标识为“?”, 然后传递给PreparedStatement,像这样:

// Similar JDBC code, NOT MyBatis… String selectPerson = “SELECT * FROM PERSON WHERE ID=?”;

PreparedStatement ps = conn.prepareStatement(selectPerson);

ps.setInt(1,id);
当然,如果单独使用JDBC 去提取这个结果集并把结果集映射到对象上的话,则需要更多的代

码,而这些,MyBatis 都已经为您做到了。关于参数和结果集映射,还有许多要学的,以后有专 门的章节来讨论。 select 语句有很多的属性允许您详细配置每一条语句。
<select
id=”selectPerson”  parameterType=”int”  parameterMap=”deprecated”  resultType=”hashmap”  resultMap=”personResultMap” flushCache=”false”  useCache=”true”  timeout=”10000”  fetchSize=”256”  statementType=”PREPARED” resultSetType=”FORWARD_ONLY” >
Insert、 update、 delete 元素 数据修改语句 insert、update 和 delete 的配置使用都非常相似:
<insert
id="insertAuthor"  parameterType="domain.blog.Author"  flushCache="true"
statementType="PREPARED"  keyProperty=""  useGeneratedKeys=""  timeout="20000">
<update
id="insertAuthor"  parameterType="domain.blog.Author"  flushCache="true"  statementType="PREPARED"  timeout="20000">
<delete
id="insertAuthor"  parameterType="domain.blog.Author"  flushCache="true"  statementType="PREPARED"  timeout="20000">
下面是一些 insert、update 和 delete 语句例子。
<insert id="insertAuthor"  parameterType="domain.blog.Author">

insert into Author (id,username,password,email,bio) values (#{id},#{username},#{password},#{email},#{bio})

</insert>
<update id="updateAuthor" parameterType="domain.blog.Author">

update Author set username = #{username}, password = #{password},email = #{email}, bio = #{bio} where id = #{id}

</update>
<delete id="deleteAuthor” parameterType="int">

delete from Author where id = #{id}

</delete>
正如您看到,insert 元素有更多一些的扩展属性及子元素,允许您使用多种方式自动生成主 键。
首先,如果您使用的数据库支持自动生成主键(如:MySQL 和 SQL Server),那么您就可以 简单地将 useGeneratedKeys 设置为”true”,然后使用 keyProperty 设置您希望自动生成主键 的字段就可以了。例如,如果上面提到的 Author 表使用一个字段自动生成主键,那么配置语句就 可以修改为:
<insert id="insertAuthor" parameterType="domain.blog.Author" useGeneratedKeys=”true” keyProperty=”id”>

insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})

</insert>
MyBatis 还有另外一种方式为不支持自动生成主键的数据库及 JDBC 驱动来生成键值。 下面展示一个能够随机生成ID 的例子(也许您不会这么做,这仅仅是演示 MyBatis 的功 能):
<insert id="insertAuthor" parameterType="domain.blog.Author">

<selectKey keyProperty="id" resultType="int" order="BEFORE">

select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1 </selectKey> insert into Author (id, username, password, email,bio, favourite_section) values (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR} ) 

</insert>
在上面的例子中,selectKey 语句首先会执行,Author 表的 ID 首先会被设值,然后才会调用 insert 语句。这相当于在您的数据库中自动生成键值,不需要编写复杂的 java 代码。
selectKey 元素描述如下:
<selectKey keyProperty="id" resultType="int"order="BEFORE" statementType="PREPARED">
参数(Parameters)

在前面的语句中,我们可以看到一些例子中简单的参数(用于代入 SQL 语句中的可替换变 量,如#{id})。参数是 MyBatis 中非常强大的配置属性,基本上,90%的情况都会用到,如:
<select id=”selectUsers” parameterType=”int” resultType=”User”>

select id, username, password from users where id = #{id}

</select>
上面的例子演示了一个非常简单的命名参数映射,parameterType 被设置为“int”。参数可 以设置为任何类型。像基本数据类型或者像Integer 和 String 这样的简单的数据对象,(因为没 有相关属性)将使用全部参数值。而如果传递的是复杂对象(一般是指JavaBean),那情况就有 所不同。

resultMap 元素

resultMap元素是MyBatis中最重要最强大的元素。与使用JDBC从结果集获取数据相比,它可 以省掉90%的代码,也可以允许您做一些JDBC不支持的事。事实上,要写一个类似于连结映射 (join mapping)这样复杂的交互代码,可能需要上千行的代码。设计ResultMaps 的目的,就是 只使用简单的配置语句而不需要详细地处理结果集映射,对更复杂的语句除了使用一些必须的语 句描述以外,就不需要其它的处理了。 您可能已经看到过这样简单映射语句,它并没有使用 resultMap,例如:
<select id=”selectUsers” parameterType=”int” resultType=”hashmap”>

select id, username, hashedPassword from some_table where id = #{id}

</sql>
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值