<?xml version="1.0" encoding="UTF-8" ?>
<!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="db.properties">
<settings cacheModelsEnabled="false" enhancementEnabled="true"
lazyLoadingEnabled="false" errorTracingEnabled="true"
useStatementNamespaces="true" />
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}" />
<property name="JDBC.ConnectionURL" value="${url}" />
<property name="JDBC.Username" value="${user}" />
<property name="JDBC.Password" value="${pword}" />
</dataSource>
</transactionManager>
<sqlMap resource="sqlmap/ts/TS_TEST.xml" />
</sqlMapConfig>
db.properties
drive=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
user=test
pword=1
TS_TEST.xml
<sqlMap namespace="TS_STUDENT">
<typeAlias alias="student"
type="com.ts.entity.student" />
<resultMap id = "testMap" class="student">
<result column="ID" property="id" jdbcType="Integer" />
<result column="NAME" property="name" jdbcType="VARCHAR" />
<result column="FLAG" property="flag" jdbcType="CHAR" />
<result column="BIRTH" property="birth" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="getStudentCondition">
<isNotNull prepend ="And" property="id">
id like '%'||#id:VARCHAR#||'%'
</isNotNull>
<isNotNull prepend ="And" property="tabStatus">
<isEqual property="tabStatus" compareValue="yes">
flag='1'
</isEqual>
<isEqual property="tabStatus" compareValue="no">
flag='0'
</isEqual>
</isNotNull>
</sql>
<select id="queryStu" resultMap="testMap" parameterClass="String" >
select * from student where 1=1
<include refid="getStudentCondition">
</select>
<!-- 批量删除对象的时候,iterate不要property属性 -->
<delete id="delStud" parameterClass="java.util.List">
delete FROM STUDENT WHERE ID IN
<iterate conjunction="," open="(" close=")">
#idList[]#
</iterate>
</delete>
<!-- Iterate的使用,根据多个匹配条件查询,类似in(a,b,c)-->
<select id="selectByIterate" parameterClass="java.util.List" resultClass="testMap">
SELECT * FROM STUDENT WHERE 1=1
<isNotNull prepend="AND" property="beanList">
<iterate property="beanList" conjunction="or" open="(" close=")">
(id=#beanList[].id# and name=#beanList[].name#)
</iterate>
</isNotNull>
<isNotNull prepend="AND" property="birth">
<![CDATA[
birth < #birth:TIMESTAMP#
]]>
</isNotNull>
</select>
<!--批量修改对象,iterate必须包括property属性-->
<update id="updateStuIterate" parameterClass="student">
update student set name=#name:varchar# where id in
<iterate property="list" conjunction="," open="(" close=")">
#list[]#
</iterate>
</update>
</sqlMap>
可以通过使用动态SQL来组织灵活性更大的更通用的SQL,这样极大减少了编码量,是iBatis应用的第二大亮点。
比如:一个动态的where条件
<dynamic prepend="where">
<isNotEmpty prepend="and" property="$$$$$">
$name like '%'|| #$name# ||'%'
</isNotEmpty>
<isGreaterThan prepend="and" property="$$$$$" compareValue="$$$number">
$code like '%'|| #$code# ||'%'
</isGreaterThan>
</dynamic>
isNotNull: Checks if a property is not null.
isNotEmpty: Checks to see if the value of a Collection, String or String.valueOf()property is not null and not empty (“” or size() < 1).
ibatIS的分页显示
<sql id="pageSqlStart">
SELECT * FROM(SELECT T.*, ROWNUM RN FROM (
</sql>
<sql id="pageSqlEnd">
) T WHERE
<![CDATA[
Rownum <= #endRow# ) WHERE RN >=#startRow#
]]>
</sql>
<select id="getStudent" parameterClass="conditionVo"
resultMap="testMap">
<include refid="pageSqlStart" />
select * from student
<include refid="pageSqlEnd" />
</select>
SqlMapConfig.xml中参数设置:
lazyLoadingEnabled:延迟加载,是一种只加载必要信息而推迟加载其他未明确请求的数据的技术;
cacheModelsEnabled: 数据高速缓存,基于近期使用过的数据往往很快又会被用到的假设,将近期使用过的数据保存在内存中;
enhancementEnabled:指定是否使用cglib中那些已优化的类来提高延迟加载的性能;
useStatementNamespace:告诉ibatiS,在引用已映射语句时,是否需要使用限定名;
transactionManager元素中dataSource的值:
simple:简单的数据源工厂,配置那种内置有简单连接池的数据源,因此除了实际的JDBC驱动程序之外,该数据源工厂所需的其他东西都包含在ibatiS中;
dbcp:用于使用Jakarta Commons数据库连接池实现;
jndi:允许ibatiS共享通过jndi定位的基于容器的数据源
批处理执行更新、删除等操作:
public void deleteInfo(final List list, final String type) {
this.getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
executor.startBatch();
for (int i = 0; i < list.size(); i++) {
Student stu = (Student) list.get(i);
/**
* type:0:删除;1:恢复
*/
if ("0".equals(type)) {
stu.setDelStatus("1");
executor.update("TEST.updateStu", stu);
} else if ("1".equals(type)) {
stu.setDelStatus("0");
executor.update("TEST.updateStu", stu);
} else {
executor.delete("TEST.deleteStu", stu);
}
}
executor.executeBatch();
return null;
}
});
}
ibatis缓存
1、sqlMapConfig.xml中配置
1.SqlMapConfig.xml中
<settings
cacheModelsEnabled="true" //设置为true
enhancementEnabled="true"
lazyLoadingEnabled="true"
.............
/>
2、配置具体的sqlMap.xml
<cacheModel id="baby-cache" type="LRU" readOnly="false"
serialize="true">
<flushInterval hours="24" />
<flushOnExecute statement="getBabyByParams" />
// 如果在sqlMapConfig里面设置了useStatementNamespaces="true",需要带上namespace,
// 如<flushOnExecute statement="Product.getBabyByParams"/>
<property value="600" name="size" />
</cacheModel>
<select id="getBabyByParams" resultMap="baby-Result" cacheModel="baby-cache">
select * from Baby
<dynamic prepend="where">
<isPropertyAvailable property="name" prepend="and">
name = #name#
</isPropertyAvailable>
<isPropertyAvailable property="sex" prepend="and">
sex =
#sex,jdbcType=VARCHAR,javaType=com.yajun.enumdemo.SexEnum#
</isPropertyAvailable>
<isPropertyAvailable property="BirthdayBondStart"
prepend="and">
<![CDATA[
birthday >= cast(#BirthdayBondStart# as datetime)
]]>
</isPropertyAvailable>
<isPropertyAvailable property="BirthdayBondEnd"
prepend="and">
<![CDATA[
birthday <= cast(#BirthdayBondEnd# as datetime)
]]>
</isPropertyAvailable>
<isPropertyAvailable property="hobby" prepend="and">
hobby like '%'||#hobby#||'%'
</isPropertyAvailable>
</dynamic>
</select>
id: cacheModel的id.
type: cache的类型. ibatis目前提供了LRU,MEMORY,FIFO,OSCACHE这四种.
FIFO: com.ibatis.sqlmap.engine.cache.fifo.FifoCacheController
FIFO Cache 实现用“先进先出”原则来确定如何从 Cache 中清除对象。当 Cache 溢出时,最先进入 Cache 的对象将从 Cache 中清除。
对于短时间内持续引用特定的查询而后很可能不再使用的情况,FIFO Cache 是很好的选择
LRU: com.ibatis.sqlmap.engine.cache.fifo.LruCacheController
实现用“近期最少使用”原则来确定如何从 Cache 中清除对象。当 Cache溢出时,最近最少使用的对象将被从 Cache 中清除。使用这种方法,如果一个
特定的对象总是被使用,它将保留在 Cache 中,而且被清除的可能性最小。对于在较长的期间内,某些用户经常使用某些特定对象的情况(例如,在
PaginatedList 和常用的查询关键字结果集中翻页) ,LRU Cache 是一个不错的选择。
MEMORY: com.ibatis.sqlmap.engine.cache.fifo.MemoryCacheController
MEMORY高速缓存是一种基于引用的高速缓存。MEMORY高速缓存模型对于那些更关注内存的管理策略而不是对象的访问策略的应用程序而言是完美
的。有了STRONG、SOFT、WEAK这三种引用类型,就可以确定哪些结果应该比其他结果保留更长的时间。
- OSCACHE: com.ibatis.sqlmap.engine.cache.fifo.OSCacheController
当然,你也可以自己来实现Cache, 你需要做的是让你的Cache类 implements com.ibatis.sqlmap.engine.cache.CacheController.
readOnly: 是否只读. 默认为true, 只读.
serialize: 是否从Cache中读取同一个对象,还是对象的副本.
只有在readOnly=false才有效.
因为Cache是只读的,那么为不同session返回的对象肯定是一个.
只有在Cache是可读写的时候,才需要为每个session返回对象的副本.
flushInterval: Cache刷新间隔. 可以配置hours,minutes,seconds,milliseconds.
注: 不是说,间隔时间到了,在Cache的statement会自己刷新,而是说,在间隔时间过了后,下次的查询
将不会从Cache中直接去值,而会用SQL去查.也就是: 如果,间隔时间过了,还没有Cache对应的statement执行
的话,那么Cache中就会一直是旧的,不用担心Cache数据是旧的,因为下次的查询将会直接从SQL查询,而非Cache,查询的结果也会去更新Cache的值.
flushOnExecute: 当这些statement被执行了,那么下次的查询将会通过SQL去查,同时用查询结果更新Cache.
注: 和flushInterval的刷新一样,不是主动刷新,而是由下次查询来触发被动刷新.
在一个cacheModel中可以指定多个flushOnExecute.
property: 这是针对cacheModel的额外的一些属性配置.不同type的cacheModel将会有自己专有的一些property配置.
FIFO: <property name="size" value="100" />
LRU: <property name="cache-size" value="100" />
MEMORY: <property name="reference-type" value="WEAK" />