1. iBatis 属于半自动化框架
2. 什么场景应用iBatis
a. 由于安全原因,数据库结构部开发,无法使用Hibernate映射生成
b. 数据库方要求全部用存储过程
c. 系统数据量大,要求我们要用复杂的高效的SQL语句
3. iBatis配置
JDBC
通过传统JDBC Connection.commit/rollback实现事务支持。
JTA
使用容器提供的JTA服务实现全局事务管理。
EXTERNAL
外部事务管理,如在EJB中使用ibatis,通过EJB的部署配置即可实现自
动的事务管理机制。此时ibatis 将把所有事务委托给外部容器进行管理。
此外,通过Spring 等轻量级容器实现事务的配置化管理也是一个不错的选
择。关于结合容器实现事务管理,参见“高级特性”中的描述。
</sqlMapConfig>
4. sql 配置
sqlMap.update("updateUser",user);
5. 调用
6. 传入Map and 其它参数
7. 一对多查询
1 条本身, 10000条address 记录
如果 t_user 表中记录较少,不会有明显的影响,假设t_user 表中有十万条记录,那
么这样的操作将需要100000+1 条Select语句反复执行才能获得结果,无疑,随着记录
的增长,这样的开销将无法承受。
8. 一对多查询
9. 延迟加载
7的列子, 只有当访问address时才会真正执行
10. 动态查询
不同的查询条件, 形成不同的查询sql
11 事务管理
JDBC, JTA, 外部事务管理
基于 JTA的事务管理机制
JTA提供了跨数据库连接(或其他JTA资源)的事务管理能力。这一点是与JDBC
Transaction最大的差异。
JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC Connection
中实现。事务周期限于Connection的生命周期。同样,对于基于JDBC的ibatis事务管
理机制而言,事务管理在SqlMapClient所依托的JDBC Connection中实现,事务周期限
于SqlMapClient 的生命周期。
JTA事务管理则由JTA容器实现,JTA容器对当前加入事务的众多Connection进
行调度,实现其事务性要求。JTA的事务周期可横跨多个JDBC Connection生命周期。
同样,对于基于JTA事务的ibatis而言,JTA事务横跨可横跨多个SqlMapClient。
12. Cache
<cacheModel
id="product-cache"
type ="LRU"
readOnly="true" 如数据对象的某个属性发生了变化,则此数据对象就将被从缓存中废除,下次需要重新从数据库读取数据,构造新的数据对象。
serialize="false">
</cacheModel>
如果需要全局的数据缓存,CacheModel的serialize属性必须被设为true。否则数据
缓存只对当前Session(可简单理解为当前线程)有效,局部缓存对系统的整体性能提
升有限。
在 serialize="true"的情况下,如果有多个Session同时从Cache 中读取某个
数据对象,Cache 将为每个Session返回一个对象的复本,也就是说,每个Session 将
得到包含相同信息的不同对象实例。因而Session 可以对其从Cache 获得的数据进行
存取而无需担心多线程并发情况下的同步冲突。
Cache Type:
与hibernate类似,ibatis通过缓冲接口的插件式实现,提供了多种Cache的实现机
制可供选择:
1.MEMORY
2.LRU
3.FIFO
4.OSCACHE
13 Memory Cache
MEMORY 类型的Cache 实现,实际上是通过Java 对象引用进行。ibatis 中,其实现类
为com.ibatis.db.sqlmap.cache.memory.MemoryCacheController,MemoryCacheController 内部,
使用一个HashMap来保存当前需要缓存的数据对象的引用。
reference-type属性可以有以下几种配置:
1. STRONG
即基于传统的Java对象引用机制,除非对Cache显式清空(如到了flushInterval
设定的时间;执行了flushOnExecute所指定的方法;或代码中对Cache执行了清除
操作等),否则引用将被持续保留。
此类型的设定适用于缓存常用的数据对象,或者当前系统内存非常充裕的情况。
2. SOFT
基于SoftReference 的缓存实现,只有JVM 内存不足的时候,才会对缓冲池中的数
据对象进行回收。
此类型的设定适用于系统内存较为充裕,且系统并发量比较稳定的情况。
3. WEAK
基于WeakReference 的缓存实现,当JVM 垃圾回收时,缓存中的数据对象将被JVM
收回。
一般情况下,可以采用WEAK的MEMORY型Cache配置。
14 LRU
LRU型Cache
当Cache达到预先设定的最大容量时,ibatis会按照“最少使用”原则将使用频率最少
的对象从缓冲中清除。
<cacheModel id="userCache" type="LRU">
<flushInterval hours="24"/>
<flushOnExecute statement="updateUser"/>
<property name="size" value="1000" />
</cacheModel>
可配置的参数有:
u flushInterval
指定了多长时间清除缓存,上例中指定每24小时强行清空缓存区的所有内容。
u size
15. FIFO型Cache
先进先出型缓存,最先放入Cache中的数据将被最先废除。可配置参数与LRU型相同:
<cacheModel id="userCache" type="FIFO">
<flushInterval hours="24"/>
<flushOnExecute statement="updateUser"/>
<property name="size" value="1000" />
</cacheModel>
16. OSCache
在生产部署时,建议采用OSCache,OSCache 是得到了广泛使用的开源Cache 实现
(Hibernate 中也提供了对OSCache 的支持),它基于更加可靠高效的设计,更重要的是,
最新版本的OSCache 已经支持Cache 集群。如果系统需要部署在集群中,或者需要部署在
多机负载均衡模式的环境中以获得性能上的优势,那么OSCache在这里则是不二之选。
17 oscache.properties
2. 什么场景应用iBatis
a. 由于安全原因,数据库结构部开发,无法使用Hibernate映射生成
b. 数据库方要求全部用存储过程
c. 系统数据量大,要求我们要用复杂的高效的SQL语句
3. iBatis配置
<sqlMapConfig>
<settings
cacheModelsEnabled="true" //是否启用SqlMapClient上的缓存机
enhancementEnabled="true" //是否针对POJO启用字节码增强机制以提升 getter/setter的调用效能,避免使用Java Reflect所带来的性能开销
lazyLoadingEnabled="true" //是否启用延迟加载机制,建议设为"true"
errorTracingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver"
value="1"/>
</dataSource>
</transactionManager>
<sqlMap resource="com/ibatis/sample/User.xml"/>
JDBC
通过传统JDBC Connection.commit/rollback实现事务支持。
JTA
使用容器提供的JTA服务实现全局事务管理。
EXTERNAL
外部事务管理,如在EJB中使用ibatis,通过EJB的部署配置即可实现自
动的事务管理机制。此时ibatis 将把所有事务委托给外部容器进行管理。
此外,通过Spring 等轻量级容器实现事务的配置化管理也是一个不错的选
择。关于结合容器实现事务管理,参见“高级特性”中的描述。
</sqlMapConfig>
4. sql 配置
sqlMap.update("updateUser",user);
<update id="updateUser"
parameterClass="user"> //传入的参数的类型
<![CDATA[ //避免xml中字符与sql冲突
UPDATE t_user
SET
name=#name#,
sex=#sex#
WHERE id = #id#
]]>
</update>
5. 调用
XmlSqlMapClientBuilder xmlBuilder = new XmlSqlMapClientBuilder();
SqlMapClient sqlMap = xmlBuilder.buildSqlMap(reader);
//sqlMap系统初始化完毕,开始执行update操作
try{
sqlMap.startTransaction();
User user = new User();
user.setId(new Integer(1));
user.setName("Erica");
user.setSex(new Integer(1));
sqlMap.update("updateUser",user);
sqlMap.commitTransaction();
finally{
sqlMap.endTransaction();
}
6. 传入Map and 其它参数
<statement id="statementName"
[parameterClass="some.class.Name"]
[resultClass="some.class.Name"]
[parameterMap="nameOfParameterMap"]
[resultMap="nameOfResultMap"]
[cacheModel="nameOfCache"]
>
select * from t_user where sex = [?|#propertyName#]
order by [$simpleDynamic$ ]
</statement>
7. 一对多查询
<resultMap id="get-user-result" class="user">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="addresses" column="id"
select="User.getAddressByUserId"/>
</resultMap>
<select id="getUsers"
parameterClass="java.lang.String"
resultMap="get-user-result">
<![CDATA[
select
id,
name,
sex,
from t_user
where id = #id#
]]>
</select>
1 条本身, 10000条address 记录
如果 t_user 表中记录较少,不会有明显的影响,假设t_user 表中有十万条记录,那
么这样的操作将需要100000+1 条Select语句反复执行才能获得结果,无疑,随着记录
的增长,这样的开销将无法承受。
8. 一对多查询
<resultMap id="get-user-result" class="user">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="address" column="t_address.address"/>
<result property="zipCode" column="t_address.zipcode"/>
</resultMap>
<select id="getUsers"
parameterClass="java.lang.String"
resultMap="get-user-result">
<![CDATA[
select
from t_user,t_address
where t_user.id=t_address.user_id
]]>
</select>
9. 延迟加载
7的列子, 只有当访问address时才会真正执行
10. 动态查询
不同的查询条件, 形成不同的查询sql
<select id="getUsers"
parameterClass="user"
resultMap="get-user-result">
select
id,
name,
sex
from t_user
<dynamic prepend="WHERE">
<isNotEmpty prepend="AND" property="name">
(name like #name#)
</isNotEmpty>
<isNotEmpty prepend="AND" property="address">
(address like #address#)
</isNotEmpty>
</dynamic>
</select>
11 事务管理
JDBC, JTA, 外部事务管理
基于 JTA的事务管理机制
JTA提供了跨数据库连接(或其他JTA资源)的事务管理能力。这一点是与JDBC
Transaction最大的差异。
JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC Connection
中实现。事务周期限于Connection的生命周期。同样,对于基于JDBC的ibatis事务管
理机制而言,事务管理在SqlMapClient所依托的JDBC Connection中实现,事务周期限
于SqlMapClient 的生命周期。
JTA事务管理则由JTA容器实现,JTA容器对当前加入事务的众多Connection进
行调度,实现其事务性要求。JTA的事务周期可横跨多个JDBC Connection生命周期。
同样,对于基于JTA事务的ibatis而言,JTA事务横跨可横跨多个SqlMapClient。
12. Cache
<cacheModel
id="product-cache"
type ="LRU"
readOnly="true" 如数据对象的某个属性发生了变化,则此数据对象就将被从缓存中废除,下次需要重新从数据库读取数据,构造新的数据对象。
serialize="false">
</cacheModel>
如果需要全局的数据缓存,CacheModel的serialize属性必须被设为true。否则数据
缓存只对当前Session(可简单理解为当前线程)有效,局部缓存对系统的整体性能提
升有限。
在 serialize="true"的情况下,如果有多个Session同时从Cache 中读取某个
数据对象,Cache 将为每个Session返回一个对象的复本,也就是说,每个Session 将
得到包含相同信息的不同对象实例。因而Session 可以对其从Cache 获得的数据进行
存取而无需担心多线程并发情况下的同步冲突。
Cache Type:
与hibernate类似,ibatis通过缓冲接口的插件式实现,提供了多种Cache的实现机
制可供选择:
1.MEMORY
2.LRU
3.FIFO
4.OSCACHE
13 Memory Cache
<cacheModel id="user_cache" type="MEMORY">
<flushInterval hours="24"/>
<flushOnExecute statement="updateUser"/>
<property name="reference-type" value="WEAK" />
</cacheModel>
MEMORY 类型的Cache 实现,实际上是通过Java 对象引用进行。ibatis 中,其实现类
为com.ibatis.db.sqlmap.cache.memory.MemoryCacheController,MemoryCacheController 内部,
使用一个HashMap来保存当前需要缓存的数据对象的引用。
reference-type属性可以有以下几种配置:
1. STRONG
即基于传统的Java对象引用机制,除非对Cache显式清空(如到了flushInterval
设定的时间;执行了flushOnExecute所指定的方法;或代码中对Cache执行了清除
操作等),否则引用将被持续保留。
此类型的设定适用于缓存常用的数据对象,或者当前系统内存非常充裕的情况。
2. SOFT
基于SoftReference 的缓存实现,只有JVM 内存不足的时候,才会对缓冲池中的数
据对象进行回收。
此类型的设定适用于系统内存较为充裕,且系统并发量比较稳定的情况。
3. WEAK
基于WeakReference 的缓存实现,当JVM 垃圾回收时,缓存中的数据对象将被JVM
收回。
一般情况下,可以采用WEAK的MEMORY型Cache配置。
14 LRU
LRU型Cache
当Cache达到预先设定的最大容量时,ibatis会按照“最少使用”原则将使用频率最少
的对象从缓冲中清除。
<cacheModel id="userCache" type="LRU">
<flushInterval hours="24"/>
<flushOnExecute statement="updateUser"/>
<property name="size" value="1000" />
</cacheModel>
可配置的参数有:
u flushInterval
指定了多长时间清除缓存,上例中指定每24小时强行清空缓存区的所有内容。
u size
15. FIFO型Cache
先进先出型缓存,最先放入Cache中的数据将被最先废除。可配置参数与LRU型相同:
<cacheModel id="userCache" type="FIFO">
<flushInterval hours="24"/>
<flushOnExecute statement="updateUser"/>
<property name="size" value="1000" />
</cacheModel>
16. OSCache
在生产部署时,建议采用OSCache,OSCache 是得到了广泛使用的开源Cache 实现
(Hibernate 中也提供了对OSCache 的支持),它基于更加可靠高效的设计,更重要的是,
最新版本的OSCache 已经支持Cache 集群。如果系统需要部署在集群中,或者需要部署在
多机负载均衡模式的环境中以获得性能上的优势,那么OSCache在这里则是不二之选。
17 oscache.properties
#是否使用内存作为缓存空间
cache.memory=true
#缓存管理事件监听器,通过这个监听器可以获知当前Cache 的运行情况
cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JMSBroa
dcastingListener
#如果使用磁盘缓存(cache.memory=false),则需要指定磁盘存储接口实现
#cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.Disk
PersistenceListener
# 磁盘缓存所使用的文件存储路径
# cache.path=c:\\myapp\\cache
# 缓存调度算法,可选的有LRU,FIFO和无限缓存(UnlimitedCache)
# cache.algorithm=com.opensymphony.oscache.base.algorithm.FIFOCache
# cache.algorithm=com.opensymphony.oscache.base.algorithm.UnlimitedCache
cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache
#内存缓存的最大容量
cache.capacity=1000
# 是否限制磁盘缓存的容量
# cache.unlimited.disk=false
# 基于JMS的集群缓存同步配置
#cache.cluster.jms.topic.factory=java:comp/env/jms/TopicConnectionFactory
#cache.cluster.jms.topic.name=java:comp/env/jms/OSCacheTopic
#cache.cluster.jms.node.name=node1
# 基于JAVAGROUP的集群缓存同步配置
#cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_
ttl=32;mcast_send_buf_size=150000;mcast_recv_buf_size=80000):PING(timeout
=2000;num_initial_members=3):MERGE2(min_interval=5000;max_interval=10000
):FD_SOCK:VERIFY_SUSPECT(timeout=1500):pbcast.NAKACK(gc_lag=50;retransm
it_timeout=300,600,1200,2400,4800):pbcast.STABLE(desired_avg_gossip=20000):
UNICAST(timeout=5000):FRAG(frag_size=8096;down_thread=false;up_thread=fal
se):pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_loc
al_addr=true)
#cache.cluster.multicast.ip=231.12.21.132