@Author: cjcj cj.yangjun@gmail.com <c-j.iteye.com>
两种设计思想:
1、数据库操作与业务操作分开
2、业务操作进行调用DB层时是面向OO的
两种模型:
什么叫模型?
对于DBA来说,表就是他的模型,定义了字段名、类型、主外键关系;
对于程序员来说,Entity就是他的模型,定义了变量名、类型、对象关系;
1、“贫血”模型(大家都这样叫,也就这样叫了)
就是 “数据”的Entity;
2、“充血”模型
就是 “数据”+“行为”的Entity;
也是目前流行的hibernate的思想。
现实中一些项目做法:
1、static方式,纯JDBC,纯sql
2、JavaBean方式,部分JDBC
3、Hibernate方式,业务层面向OO
讨论最多的应该是方式3,但是我感觉频繁的创建很多DAO是很繁琐的。所以想寻索到一种更好的方法。
iBATIS项目思想:
1、sql语句与代码分离
2、select语句where条件可写死在xml或在代码中指定
3、运用IOC的构造sqlMapClient和targetType成员属性
IBATIS框架涉及的文件
IBATIS配置文件(XML)
1、配置缓存 setting
2、配置连接和连接池 transactionManager
3、配置sqlMap资源 sqlMap
如:对于容器没有提供连接池的情况,配置一个DBCP连接池
IBATIS MAP文件(XML)
<parameterMap id=”parameterMapName” [class=”com.domain.Product”]> <parameter property =”propertyName” [jdbcType=”VARCHAR”] [javaType=”string”] [nullValue=”NUMERIC”] [null=”-9999999”]/> <parameter …… /> <parameter …… /> </parameterMap> <resultMap id=”resultMapName” class=”some.domain.Class” [extends=”parent-resultMap”]> <result property=”propertyName” column=”COLUMN_NAME” [columnIndex=”1”] [javaType=”int”] [jdbcType=”NUMERIC”] [nullValue=”-999999”] [select=”someOtherStatement”] /> <result ……/> <result ……/> <result ……/> </resultMap>
对于复杂查询1:1的情况,有两种查询方式:延迟加载VS联合查询。
如果您要缓存查询结果,则使用子查询(而不是联合查询)来缓存查询结果。
对于复杂查询1:M or M:N的情况,2.x目前还没有更好的解决方案,只能采用“延迟加载”
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”> <result property=”id” column=”CAT_ID”/> <result property=”productList” column=”CAT_ID” select=”getProductsByCatId”/> </resultMap> <resultMap id=”get-product-result” class=”com.ibatis.example.Product”> <result property=”id” column=”PRD_ID”/> </resultMap> <statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”> select * from CATEGORY where CAT_ID = #value# </statement> <statement id=”getProductsByCatId” parameterClass=”int” resultMap=”get-product-result”> select * from PRODUCT where PRD_CAT_ID = #value# </statement>
对于多个参数属性
IBATIS的client实例
IBATIS提供的数据库操作实例是sqlMapClient,里面包括了query,update,delete的方法,还有transaction,datasource(DBCP);sqlMapClient实例的query方法是用ThreadLocal保证线程安全。
IBATIS的事务管理
因为IBATIS本身只是轻封装了JDBC,所以事务也是JDBC本身控制的。运用事务很简单,只需要获得sqlMapClient实例调用相应方法就可以了,如下:
sqlMap=new MapClientConfigLoader(SqlMapClientSingleton.sqlMapConfig).loadSMC();
sqlMap.startTransaction();
// 事务操作,在同一个Session里
sqlMap.endTransaction();
IBATIS的Cache
采用简单查询缓存;
采用Hibernate 等的两级缓存
对象缓存(Object Cache),将对象像库表记录一样,按主键进行缓存,相当于建立一个简单的内存数据库;
查询缓存(Query Cache),但它只缓存结果集的主键,因此 cache.value 空间消耗大大减少。
Some public websites that utilize IBatis
1up.com - Gaming community
http://www.1up.com
Abebooks.com - Worlds largest online marketplace for books
http://www.abebooks.com
AccesStream.com - Open Source Identity and Access Management Suite
http://www.accesstream.com
BullionVault.com - Online gold trading
http://www.bullionvault.com
www.druckdiskont.at -
Online print portal (Web To Print)
http://www.druckdiskont.at
Fiskars - Consumer products manufacturer
http://www.fiskars.com
GalMarley.com - Gold prices, facts, figures and charts
http://www.galmarley.com
GAPay - General Agent Payment System
http://www.gapay.com.
Ideal Financial Services
http://www.idealfsi.com ....
于是也简单查了下IBATIS的Cache源码;
- 三种模式
/**
* Constant for weak caching
* This cache model is probably the best choice in most cases. It will increase
* performance for popular results, but it will absolutely release the memory to
* be used in allocating other objects, assuming that the results are not currently
* in use.
*/
public final static MemoryCacheLevel WEAK;
/**
* Constant for soft caching.
* This cache model will reduce the likelihood of running out of memory in case the
* results are not currently in use and the memory is needed for other objects.
* However, this is not the most aggressive cache-model in that regard. Hence,
* memory still might be allocated and unavailable for more important objects.
*/
public final static MemoryCacheLevel SOFT;
/**
* Constant for strong caching.
* This cache model will guarantee that the results stay in memory until the cache
* is explicitly flushed. This is ideal for results that are:
* <ol>
* <li>very small</li>
* <li>absolutely static</li>
* <li>used very often</li>
* </ol>
* The advantage is that performance will be very good for this particular query.
* The disadvantage is that if the memory used by these results is needed, then it
* will not be released to make room for other objects (possibly more important
* objects).
*/
public final static MemoryCacheLevel STRONG;
- 4种策略
FIFO
LRU
MEMORY
OS
研究dao-zone项目中...
疑难杂症:
1:classNotFound, 找不到Resource类的问题,用户会出现打成JAR包的时候无法找到IBATIS的类错误;
解决:这个属于ECLIPSE打包的问题,在你的JAR所在目录下新建LIB文件夹,并在工程MANIFEST.MF修改如下:
Manifest-Version: 1.0
Main-Class: com.hp.CcdMain
Class-Path: lib/ibatis-common-2.jar lib/ibatis-sqlmap-2.jar lib/log4j.jar lib/commons-dbcp-1.2.2.jar lib/mysql-connector-java-5.1.8-bin.jar lib/commons-pool-1.5.2.jar
Class-Path为第三方JAR包的路径
2:Cause: com.ibatis.common.xml.NodeletException: Error parsing XML. Cause: org.xml.sax.SAXParseException: Element "sqlMap" requires additional elements.异常问题
解决:IBATIS支持JRE1.4,刚开始我怀疑是JRE版本的问题,不是,这类问题大多数跟IBATIS的XML配置文件有关;
sqlMap必须要有<sqlMap>和<statement>标签,否则IBATIS将报错
3:SqlMapConfig.xml加载外部资源文件相对路径问题:
提供了两种方式:resource和url
今天实验下url好像不能用相对路径如 .. ,只能用绝对路径,郁闷了,如<properties url="file:///G:/SRC/testccd/config.properties" />