目录:
一、iBatis简介
二、iBatis基础操作演示
三、如何搭建Spring+iBatis集成开发环境
四、Spring+iBatis的CRUD数据操作实现
五、iBatis高级应用
六、Spring+iBatis方案优点
我们的目标是:能够熟练运用当前流行的java开源框架:iBatis,掌握iBatis与Spring框架的集成方式。
DAO 模式就是在业务逻辑层和持久化存储层之间引入了新的抽象层。业务对象通过数据访问对象访问关系型数据库(数据源)。抽象层简化了应用程序代码增强了灵活性。试想一下哪天改变了数据源,比如更换为其他数据库厂商的产品,只需要修改数据访问对象,并且对业务对象的影响也是最小的。
iBatis简介(一)
采用JDBC实现DAO设计模式的缺点:
代码重复:正如 EmployeeDAOImpl 类列出的,代码重复是基于 JDBC 的传统数据库访问的主要问题。反复书写代码明显违反了基本的 OO 代码复用原则。对于项目开销、时间和消耗都有着明显的不利因素。
耦合:DAO 代码非常紧密的和 JDBC 接口以及核心集合类型耦合在一起。这点可以从每个 DAO 类导入语句的数目体现。
资源泄漏:进入 EmployeeDAOImpl 类的设计,所有 DAO 方法都必须释放已获取的数据库资源的控制权,比如 connection、statements 以及结果集。这样做是很危险的,因为一名没有经验的程序员可以很容易的绕开这些程序块。结果资源将流失,最终导致系统当机。
错误捕获:JDBC 驱动通过抛出 SQLException 报告所有的错误情况。SQLException 是 checked exception。因此开发者被迫处理它——即使无法从大部分异常中恢复,这样也就导致了混乱的代码。此外,从 SQLException 对象获取错误代码和消息是数据库供应商特定的,因此不可能编写灵活的 DAO 错误消息代码。
脆弱的代码:在基于 JDBC 的 DAO 中,为 statement 对象绑定变量的设置,以及获取数据使用的结果集 getter 方法是频繁用到的两个任务。如果 SQL 语句中的列数改变了,或者列的位置改变了,代码将不得不再经过严格的反复修改、测试然后部署。
package com.anduo.ssi.domain;
public class UserVO {
/**
* This field was generated by Apache iBATIS ibator.
* This field corresponds to the database column user.userid
*
* @ibatorgenerated Tue Mar 27 19:50:47 CST 2012
*/
private Integer userid;
/**
* This field was generated by Apache iBATIS ibator.
* This field corresponds to the database column user.username
*
* @ibatorgenerated Tue Mar 27 19:50:47 CST 2012
*/
private String username;
/**
* <p>Discription:[构造器方法描述]</p>
* @coustructor 方法.
*/
public UserVO()
{
}
public UserVO(String username)
{
this.username = username;
}
/**
* This method was generated by Apache iBATIS ibator.
* This method returns the value of the database column user.userid
*
* @return the value of user.userid
*
* @ibatorgenerated Tue Mar 27 19:50:47 CST 2012
*/
public Integer getUserid() {
return userid;
}
/**
* This method was generated by Apache iBATIS ibator.
* This method sets the value of the database column user.userid
*
* @param userid the value for user.userid
*
* @ibatorgenerated Tue Mar 27 19:50:47 CST 2012
*/
public void setUserid(Integer userid) {
this.userid = userid;
}
/**
* This method was generated by Apache iBATIS ibator.
* This method returns the value of the database column user.username
*
* @return the value of user.username
*
* @ibatorgenerated Tue Mar 27 19:50:47 CST 2012
*/
public String getUsername() {
return username;
}
/**
* This method was generated by Apache iBATIS ibator.
* This method sets the value of the database column user.username
*
* @param username the value for user.username
*
* @ibatorgenerated Tue Mar 27 19:50:47 CST 2012
*/
public void setUsername(String username) {
this.username = username == null ? null : username.trim();
}
}
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" > <sqlMap namespace="USER"> <typeAlias alias="user" type="com.anduo.ssi.domain.UserVO" /> <resultMap id="user" class="com.anduo.ssi.domain.UserVO"> <!-- WARNING - This element is automatically generated by Apache iBATIS ibator, do not modify. This element was generated on Tue Mar 27 19:50:47 CST 2012. --> <result column="userid" property="userid" jdbcType="INTEGER" /> <result column="username" property="username" jdbcType="VARCHAR" /> </resultMap> <!-- 新增 --> <insert id="insert" parameterClass="user"> INSERT INTO USER(USERNAME) VALUES(#username#) </insert> <!-- 删除 --> <delete id="delete" parameterClass="user"> DELETE FROM USER T WHERE T.USERID = #userid# </delete> <!-- 更新 --> <update id="update" parameterClass="user"> UPDATE USER <dynamic prepend="SET"> <isNotNull prepend="," property="username"> USERNAME=#USERNAME# </isNotNull> <isNotNull prepend="," property="password"> PASSWORD=#PASSWORD# </isNotNull> </dynamic> WHERE ID=#ID# </update> <!-- 查询全部 --> <select id="selectAllUserInfo" resultClass="user"> SELECT T.USERID,T.USERNAME FROM USER T </select> <!-- 根据ID查询 --> <select id="selectUserInfoById" resultClass="user"> SELECT T.USERID,T.USERNAME FROM USER T WHERE T.USERID=#userid# </select> <!-- 动态查询 --> <select id="dynamicSelectUserInfo" resultClass="user"> SELECT T.USERID,T.USERNAME FROM USER T <dynamic prepend="WHERE"> <isNotEmpty prepend="AND" property="userid"> T.USERID = #userid# </isNotEmpty> <isNotEmpty prepend="AND" property="username"> T.USERNAME LIKE '%$username$%' </isNotEmpty> </dynamic> </select> </sqlMap>
package com.anduo.ssi.dao;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.ibatis.sqlmap.client.SqlMapExecutor;
import com.anduo.ssi.common.exception.BaseDataAccessException;
public abstract class BaseDAO<E> extends SqlMapClientDaoSupport implements DAO<E>{
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param parameter
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
@SuppressWarnings("unchecked")
public List<E> getDataList(String statement, Object parameter) throws BaseDataAccessException {
List<E> result = null;
try{
result = getSqlMapClientTemplate().queryForList(statement, parameter);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param parameter
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
@SuppressWarnings("unchecked")
public E getData(String statement, Object parameter) throws BaseDataAccessException {
E result = null;
try{
result = (E) getSqlMapClientTemplate().queryForObject(statement, parameter);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param parameter
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public int getDataCount(String statement, Object parameter) throws BaseDataAccessException {
Integer result= null;
try{
result = (Integer) getSqlMapClientTemplate().queryForObject(statement, parameter);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param data
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public int updateData(String statement, E data) throws BaseDataAccessException {
Integer result= null;
try{
result = getSqlMapClientTemplate().update(statement, data);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param map
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public int updateData(String statement, Map<String, Object> map) throws BaseDataAccessException {
Integer result= null;
try{
result = getSqlMapClientTemplate().update(statement, map);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param data
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public Object insertData(String statement, E data) throws BaseDataAccessException {
Object result = null;
try{
result = getSqlMapClientTemplate().insert(statement, data);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param map
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public Object insertData(String statement, Map<String, Object> map) throws BaseDataAccessException {
Object result = null;
try{
result = getSqlMapClientTemplate().update(statement, map);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param data
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public int deleteDate(String statement, String data) throws BaseDataAccessException{
Integer result = null;
try{
result = getSqlMapClientTemplate().delete(statement, data);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param map
* @return
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public int deleteDate(String statement, Map<String, Object> map) throws BaseDataAccessException{
Integer result = null;
try{
result = getSqlMapClientTemplate().delete(statement, map);
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
return result;
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param map
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public void executeBatch(final String statement, final Map<String, E> map) throws BaseDataAccessException {
try{
getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
executor.startBatch();
for (Object o : map.keySet()) {
executor.update(statement, map.get(o));
}
executor.executeBatch();
return null;
}
});
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
}
/**
* <p>Discription:[方法功能中文描述]</p>
* @param statement
* @param list
* @throws BaseDataAccessException
* @author:[安多]
* @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public void executeBatch(final String statement, final List<?> list) throws BaseDataAccessException {
try{
getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
executor.startBatch();
for (Object o : list) {
executor.update(statement, o);
}
executor.executeBatch();
return null;
}
});
}catch(DataAccessException e){
throw new BaseDataAccessException(e);
}
}
}
package com.anduo.ssi.dao.impl;
import com.anduo.ssi.dao.BaseDAO;
import com.anduo.ssi.dao.UserDAO;
import com.anduo.ssi.domain.UserVO;
/**
* <p>Description: [描述该类概要功能介绍]</p>
* @author
* @version $Revision$
*/
public class UserDAOImpl extends BaseDAO<UserVO> implements UserDAO
{
}