1. 程式人生 > 程式設計 >Spring如何整合ibatis專案並實現dao層基類封裝

Spring如何整合ibatis專案並實現dao層基類封裝

Apache iBatis(現已遷至Google Code下發展,更名為MyBatis)是當前IT專案中使用很廣泛的一個半自動ORM框架,區別於Hibernate之類的全自動框架,iBatis對資料庫的操作擁有更加靈活的控制,對於那些經常需要呼叫本地資料庫函式自定義SQL語句,或是喜歡自己優化SQL執行效率的開發者來說,iBatis是一個非常不錯的選擇。

而得到廣泛應用的開源企業架構SpringFramework,也很好的將其進行了整合,使得iBatis在 SpringFramework中的使用更加便利、快捷。開發者所要做的就是繼承SpringFramework中提供的SqlMapClientDaoSupport類即可。下面將簡單介紹使用spring中整合的ibatis進行專案中dao層基類封裝,以方便開發。

1、SqlMapClientFactoryBean 的裝配

  SqlMapClientFactoryBean是SqlMapClientTemplate使用的基礎,如果在SpringFramework應用中沒有裝配SqlMapClientFactoryBean,那麼SqlMapClientTemplate將不可用,報空指標錯誤。其配置資訊如下:

<bean id="sqlMapClient"
  class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <!-- iBatis sqlmap config 檔案位置 -->
  <property name="configLocation">
    <value>
      /WEB-INF/classes/org/bussiness/config/ibatis/SqlMapConfig.xml
    </value>
  </property>
  <!-- 在SpringFramework配置檔案中使用的資料來源 -->
  <property name="dataSource">
    <ref local="dataSource" />
  </property>
  <!-- 如果需要讀寫Lob欄位,需要注入在SpringFramework配置檔案中配置好的Handler,這裡是Oracle的資料庫 -->
  <property name="lobHandler" ref="oracleLobHandler"/>
</bean>

2、繼承使用SqlMapClientDaoSupport類

2.1)首先定義一個IBaseDao介面提供各種場景的查詢、修改、刪除、分頁查詢的各種抽象功能方法

package org.biframework.dao.ibatis;
import com.ibatis.common.util.PaginatedList;
import java.util.List;
import org.biframework.exception.DaoException;
public abstract interface IBaseDao
{
 public abstract Object getObject(String paramString,Object paramObject)
  throws DaoException;

 @SuppressWarnings("unchecked")
 public abstract List getList(String paramString,Object paramObject)
  throws DaoException;

 public abstract PaginatedList getPgntList(String paramString1,Object paramObject,String paramString2)
  throws DaoException;

 public abstract PaginatedList getPgntList(String paramString1,String paramString2,int paramInt)
  throws DaoException;

 @SuppressWarnings("unchecked")
 public abstract List getListUseSameStmt(String paramString,Object[] paramArrayOfObject)
  throws DaoException;

 public abstract int update(String paramString,Object paramObject)
  throws DaoException;

 public abstract int transUpdateSameOpt(String paramString,Object[] paramArrayOfObject)
  throws DaoException;

 public abstract int transUpdate(Object[][] paramArrayOfObject)
  throws DaoException;
 
 @SuppressWarnings("unchecked")
 public List getList(String statementName,Object parameterObject,int skipResults,int maxResults) throws DaoException;
}

備註:該層也可以不寫

2.2)繼承使用SqlMapClientDaoSupport類並實現IBaseDao介面

package org.biframework.dao.ibatis;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.biframework.exception.DaoException;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.ibatis.common.util.PaginatedList;

public class BaseDao extends SqlMapClientDaoSupport implements IBaseDao {

  @SuppressWarnings("unused")
  private static Log log;
  protected static final int PAGE_SIZE = 15;
  @SuppressWarnings("unchecked")
  static Class class$0; /* synthetic field */

  public BaseDao() {
  }
  /*
  使用spring中整合的ibatis實現資料的查詢、修改、刪除
  1)當請求引數被封裝為一個普通物件,查詢結果為List集合:
  使用queryForList返回List 原始碼方法如下:getSqlMapClientTemplate(),獲取SqlMapClientTemplate物件,
  引數說明:a、statementName sql宣告;b、parameterObject請求引數物件 queryForList方法原始碼如下
  public List queryForList(String statementName,Object parameterObject)
   throws DataAccessException
   {
    executeWithListResult(new SqlMapClientCallback()
    {
     private final String val$statementName;
     private final Object val$parameterObject;
     public Object doInSqlMapClient(SqlMapExecutor executor)
      throws SQLException
     {
      return executor.queryForList(this.val$statementName,this.val$parameterObject);
     }
    });
   }
  */
  @SuppressWarnings("unchecked")
  public List getList(String statementName,Object parameterObject)
      throws DaoException {
    List list = getSqlMapClientTemplate().queryForList(statementName,parameterObject);
    return list;
  }
  
  /*
  2)當請求引數被封裝為一個數組物件時:
    即使用陣列存放多個傳參物件(obj1、obj2...)而後使用相同sql,進行多次查詢,將多次查詢的結果list1、list2...放到結果集List中)
  使用queryForList返回List 封裝的方法如下:
  */
  @SuppressWarnings("unchecked")
  public List getListUseSameStmt(String statementName,Object objectParam[])
      throws DaoException {
    List list = null;
    List temp = null;
    if (statementName == null || objectParam == null|| objectParam.length == 0){
      return list;
    }else{
      for (int i = 0; i < objectParam.length; i++) {
        if (list == null){
          list = new ArrayList();
          temp = getSqlMapClientTemplate().queryForList(statementName,objectParam[i]);
        }  
        if (temp != null){
          list.addAll(temp);
        }  
      }
    }
    return list;
  }

  /*
  3)當請求引數被封裝為一個普通物件,查詢結果為Object物件
  */
  @SuppressWarnings("unchecked")
  public Object getObject(String statementName,Object parameterObject)
      throws DaoException {
    Object result = null;
    List list = getSqlMapClientTemplate().queryForList(statementName,parameterObject);
    if (list != null && list.size() > 0){
      result = list.get(0);
    }
    return result;
  }
  
  /*
  4)ibatis-common-2.jar、使用ibatis自身封裝的PaginatedList工具類進行分頁查詢,每頁15條資料。
  public PaginatedList queryForPaginatedList(String statementName,int pageSize)
  throws DataAccessException
   {
    if (((this.sqlMapClient instanceof ExtendedSqlMapClient)) && (((ExtendedSqlMapClient)this.sqlMapClient).getDelegate().getTxManager() == null)) {
     throw new InvalidDataAccessApiUsageException("SqlMapClient needs to have DataSource to allow for lazy loading - specify SqlMapClientFactoryBean's 'dataSource' property");
    }
    (PaginatedList)execute(new SqlMapClientCallback()
    {
     private final String val$statementName;
     private final Object val$parameterObject;
     private final int val$pageSize;
     
     public Object doInSqlMapClient(SqlMapExecutor executor)
      throws SQLException
     {
      return executor.queryForPaginatedList(this.val$statementName,this.val$parameterObject,this.val$pageSize);
     }
    });
   }
  */
  public PaginatedList getPgntList(String statementName,String pageDirection) throws DaoException {
    PaginatedList list = getSqlMapClientTemplate().queryForPaginatedList(
        statementName,parameterObject,15);
    if ("next".equals(pageDirection))
      list.nextPage();
    else if ("previous".equals(pageDirection))
      list.previousPage();
    else if ("first".equals(pageDirection))
      list.isFirstPage();
    else if ("last".equals(pageDirection))
      list.isLastPage();
    return list;
  }

  /*
  4)自己指定分頁查詢的數量
  */
  public PaginatedList getPgntList(String statementName,String pageDirection,int pageSize)
      throws DaoException {
    PaginatedList list = getSqlMapClientTemplate().queryForPaginatedList(
        statementName,pageSize);
    if ("next".equals(pageDirection)) {
      System.out.println("下一頁");
      list.nextPage();
    } else if ("previous".equals(pageDirection)) {
      System.out.println("上一頁");
      list.previousPage();
    } else if ("first".equals(pageDirection)) {
      System.out.println("首頁");
      list.isFirstPage();
    } else if ("last".equals(pageDirection)) {
      System.out.println("末頁");
      list.isLastPage();
    }
    return list;
  }
  
  /*
  5)該方法暫時未理解其主要是處於何種場景使用
  */
  public int update(String statementName,Object parameterObject)
  throws DataAccessException
   {
    Integer result = (Integer)execute(new SqlMapClientCallback()
    {
     private final String val$statementName;
     private final Object val$parameterObject;
     public Object doInSqlMapClient(SqlMapExecutor executor)
      throws SQLException
     {
      return new Integer(executor.update(this.val$statementName,this.val$parameterObject));
     }
    });
    return result.intValue();
   }  
  */
  public int transUpdate(Object statementAndparameter[][])
      throws DaoException {
    Object statements[] = statementAndparameter[0];
    Object parameters[] = statementAndparameter[1];
    int result = 0;
    for (int i = 0; i < statements.length; i++) {
      String name = (String) statements[i];
      Object param = parameters[i];
      result += getSqlMapClientTemplate().update(name,param);
    }
    return result;
  }

  /*
  6)請求引數被封裝為一個數組物件,返回結果為成功更新的記錄數使用spring封裝的update方法進行更新操作
  */
  public int transUpdateSameOpt(String statementName,Object objectParam[])
      throws DaoException {
    int result = 0;
    if (statementName == null || objectParam == null
        || objectParam.length == 0)
      return result;
    for (int i = 0; i < objectParam.length; i++)
      result += getSqlMapClientTemplate().update(statementName,objectParam[i]);
    return result;
  }
  /*
  7)請求引數被封裝為一個普通物件,返回結果為成功更新的記錄數
  */
  public int update(String statementName,Object parameterObject)
      throws DaoException {
    int result = getSqlMapClientTemplate().update(statementName,parameterObject);
    return result;
  }

  static {
    log = LogFactory.getLog(org.biframework.dao.ibatis.BaseDao.class);
  }
  
  /*
  8)請求引數被封裝為一個普通物件,並對查詢的結果記錄指定跳躍數和最大結果集
  */
  @SuppressWarnings("unchecked")
  public List getList(String statementName,int maxResults) throws DaoException {
    return getSqlMapClientTemplate().queryForList(statementName,skipResults,maxResults);
  }
}

3、進行dao層配置,並進行查詢等操作

3.1)所有的dao層都繼承BaseDao類

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.biframework.dao.ibatis.BaseDao;
import org.biframework.exception.DaoException;
import org.bussiness.product.detailquery.bo.StPolicyBean;

public class StPolicyDao extends BaseDao {
  protected static Log log = LogFactory.getLog(StPolicyDao.class);
  
  @SuppressWarnings("unchecked")
  public List getStPerm(StPBean param) throws DaoException{
    return super.getList("getShortPrem",param);
  }

  public Object getStPermCount(StPBean param) throws DaoException{
    return super.getObject("getShortPremCount",param);
  }
  }
}

3.2)進行dao裝配 detailQuery-applicationContext.xml

<bean id="nstpDao" class="org.bussiness.product.detailquery.dao.NstPolicyDao">
  <property name="dataSource">
    <ref bean="dataSource" />
  </property>
  <property name="sqlMapClient">
    <ref bean="sqlMapClient" />
  </property>
</bean>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。