2011年(264)
分类: Java
2011-07-31 21:51:39
开发指南教程
POJO = pure old java object or plain ordinary java object
or what ever.
PO = persisent object 持久对象
就是说在一些Object/Relation Mapping工具中,能够做到维护数据库表记录的persisent object完全是一个符合Java Bean规范的纯Java对象,没有增加别的属性和方法。
持久对象PO(Persistent Object)在代码上肯定和POJO不同,起码PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。而ORM追求的目标就是要PO在使用上尽量和POJO一致,对于程序员来说,他们可以把PO当做POJO来用,而感觉不到PO的存在。
一、ibatis的配置
cacheModelsEnabled="false" 是否启用SqlMapClient上的缓存机制建议true
enhancementEnabled="true" 是否针对POJO启用字节码增强机制以提升getter/sette的调用效能,避免使用JAVA反射所带来的性能开销建议true
lazyLoadingEnabled="true" 是否启用延迟加载机制,建议设为"true"
maxRequests="128" 最大并发请求数(Statement并发数)
maxSessions="64" 最大Session 数。即当前最大允许的并发SqlMapClient数。maxSessions设定必须介于maxTransactions和maxRequests之间
maxTransactions="16" 最大并发事务数
useStatementNamespaces="false" 是否使用Statement命名空间。这里的命名空间指的是映射文件中,sqlMap节点的namespace属性
errorTracingEnabled 是否启用错误日志,在开发期间建议设为"true"以方便调试
/>
2. transactionManager节点
目前提供三种选择
Ø JDBC 传统的JDBC实现事务支持
Ø JTA 使用容器提供的JTA服务实现全局事务管理
Ø EXTERNAL 外部事务管理 如在EJB中使用ibatis通过EJB的部署即可实现自动的事务管理机制。
从属于transactionManager节点用于设定运行期使用的DataSource属性。
其中type有这几个
Ø SIMPLE
SIMPLE是ibatis内置的dataSource实现,其中实现了一个简单的数据库连接池机制, 对应ibatis 实现类为com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory
Ø DBCP
基于Apache DBCP 连接池组件实现的DataSource 封装,当无容器提供DataSource 服务时,建议使用该选项,对应类 com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。
Ø JNDI
使用J2EE 容器提供的DataSource 实现,DataSource 将通过指定的JNDI Name 从容器中获取com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory。
数据库联接池中,连接被某个任务所允许占用的最大时间,如果超过这个时间限定,连接将被强
制收回。(毫秒)
当线程试图从连接池中获取连接时,连接池中无可用连接可供使用,此时线程将进入等待状态,
直到池中出现空闲连接。此参数设定了线程所允许等待的最长时间。(毫秒)
定义JDBC驱动
数据库连接状态检测语句。某些数据库在连接在某段时间持续处于空闲状态时会将其断开。而连接池管理器将通过此语句检测池中连接是否可用。
是否允许检测连接状态。
数据库连接池可维持的最大容量。
value="jdbc:mysql://xxxxxx/hsfsa?useUnicode=true&characterEncoding=GBK&autoReconnect=true"
/> 数据库URL 配置完了之后看看SqlMapClient基本操作示例 SQLMapClient基本操作示例 例1:实现数据写入操作(插入、更新、删除) sqlMap.startTransaction(); Product product = new Product(); product.setId (1); product.setDescription (“Shih Tzu”); int rows = sqlMap.insert (“insertProduct”, product); sqlMap.commitTransaction(); 例2:数据查询 sqlMap.startTransaction(); Integer key = new Integer (1); Product product =
(Product)sqlMap.queryForObject (“getProduct”, key); sqlMap.commitTransaction(); 例三:在指定对象中存放查询结果 sqlMap.startTransaction(); Customer customer = new Customer(); sqlMap.queryForObject(“getCust”,
parameterObject, customer); sqlMap.queryForObject(“getAddr”, parameterObject,
customer); sqlMap.commitTransaction(); 例四:执行批量查询 sqlMap.startTransaction(); List list = sqlMap.queryForList
(“getProductList”, null); sqlMap.commitTransaction(); 批量查询返回List值 例5:关于AutoCommit //没有预先执行startTransaction时,默认为auto_commit模式 int rows = sqlMap.insert (“insertProduct”, product); 例六:查询指定范围内的数据 sqlMap.startTransaction(); List list = sqlMap.queryForList
(“getProductList”, null, 0, 40); sqlMap.commitTransaction(); 例七:结合RowHandler进行查询 public class MyRowHandler implements
RowHandler { public void handleRow (Object object, List list) throws SQLException { Product product = (Product)
object; product.setQuantity (10000); sqlMap.update (“updateProduct”, product); } } sqlMap.startTransaction(); RowHandler rowHandler = new MyRowHandler(); List list = sqlMap.queryForList
(“getProductList”, null, rowHandler); sqlMap.commitTransaction(); 例8:分页查询 PaginatedList list = sqlMap.queryForPaginatedList (“getProductList”, null, 10); list.nextPage(); list.previousPage(); 例9:基于Map的批量查询 sqlMap.startTransaction(); Map map = sqlMap.queryForMap (“getProductList”, null, “productCode”); sqlMap.commitTransaction(); Product p = (Product) map.get(“EST-93”); 相应的SQL语句映射的配置文件 Ø cacheModel节点 定义了本映射文件中使用的Cache机制: <cacheModel id="userCache" type="LRU"> <flushInterval hours="24"/> l flushInterval : 设定缓存有效期,如果超过此设定值,则将此CacheModel的缓存清空。 <flushOnExecute statement="updateUser"/> l flushOnExecute: 指定执行特定Statement时,将缓存清空。如updateUser操作将更新数据库中的用户信息,这将导致缓存中的数据对象与数据库中的实际数据发生偏差,因此必须将缓存清空以避免脏数据的出现。表示执行哪个ID的时候清空缓存的如果有多个怎么办? <property name="size" value="1000"
/> l size: 本CacheModel中最大容纳的数据对象数量。 cacheModel> 这里面定义了一个cache之后就可以在语句里面进行声明了 <select id="getUser" parameterClass="java.lang.String" resultClass="user" cacheModel="userCache"> 这表明对通过id为"getUser"的Select statement获取的数据,使用cacheModel "userCache"进行缓存。之后如果程序再次用此Statement进行数据查询,即直接从缓存中读取查询结果,而无需再去数据库查询。 写的语句 <delete id="statementName" [parameterClass="some.class.Name"] [parameterMap="nameOfParameterMap"] > delete from t_user where id = [?|#propertyName#] delete> parameterClass 参数类。指定了参数的完整类名(包括包路径)。可通过别名避免每次重复书写冗长的类名。 resultClass 结果类。指定结果类型的完整类名(包括包路径)可通过别名避免每次重复书写冗长的类名。 parameterMap 参数映射,需结合parameterMap节点对映射关系加以定义。对于存储过程之外的statement而言,建议使用parameterClass作为参数配置方式,一方面避免了参数映射配置工作,另一方面其性能表现也更加出色。 resultMap 结果映射,需结合resultMap节点对映射关系加以定义。 cacheModel statement对应的Cache模块。 对于返回结果而言,如果是select语句,建议也采用resultClass进行定义 高级应用篇 延迟加载 所谓的延迟加载(Lazy Loading)机制。即当真正需要数据的时候,才加载数据。延迟加载机制能为我们的系统性能带来极大的提升。 动态映射 在复杂查询过程中,我们常常需要根据用户的选择决定查询条件,这里发生变化的并不只是SQL 中的参数,包括Select 语句中所包括的字段和限定条件,都可能发生变化。 ibatis引入了动态映射机制,即在statement定义中,根据不同的查询参数,设定对应的SQL语句。《参数不同可以实现动态的SQL语句》 <select id="getUsers" parameterClass="user" resultMap="get-user-result"> select id, name, *** 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> 可以看出这个其实是一个动态拼结出来的SQL语句了! 这样,我们通过在statement 定义中引入dynamic 节点,很简单的实现了SQL 判定子句的动态生成,对于复杂的组合查询而言,这将带来极大的便利。 <isNotEmpty prepend="AND" property="name"> ( name=#name# <isNotEmpty prepend="AND" property="address"> address=#address# isNotEmpty> ) isNotEmpty> 事务管理 基于JDBC的事务管理机制 对于多条SQL 组合而成的一个JDBC 事务操作而言,必须使用 startTransaction、commit和endTransaction操作以实现整体事务的原子性。 try{ sqlMap =
xmlBuilder.buildSqlMap(reader); sqlMap.startTransaction();//开始事务提交 User user = new User(); user.setId(new Integer(1)); user.setName("Erica"); user.set***(new Integer(0)); sqlMap.update("User.updateUser", user); User user2 = new User(); user2.setId(new Integer(2)); user2.setName("Kevin"); user2.set***(new Integer(1)); sqlMap.update("User.updateUser", user2); sqlMap.commitTransaction();//提交事务 }finally{ sqlMap.endTransaction(); }