<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    海鷗航際

    JAVA站
    posts - 11, comments - 53, trackbacks - 1, articles - 102

    ibatis初步介紹

    Posted on 2005-01-12 09:39 海天一鷗 閱讀(586) 評論(0)  編輯  收藏 所屬分類: Java數(shù)據(jù)庫技術(shù)

    ibatis初步介紹

     

    作者:CHAMPION

    ibatis初步介紹

                在開發(fā)過程中最能幫助你的是什么?是框架,一個優(yōu)秀的框架可以極大的提高你的效率。struts給了我們什么?MVC的實(shí)現(xiàn),國際化、靈活。還有很多。不過,在一個通常的WEB應(yīng)該中,是不能缺少數(shù)據(jù)庫的,而struts在這方面并沒有給我們提供什么有效的幫助。通常情況下我們做這個的時候有幾個選擇。
                
    最直接的當(dāng)然是JDBC啊,自己寫connectstatmentresultset等等的代碼,結(jié)果是累死自己。
                
    然后一種方法是EJBEJB確實(shí)是一個好東西,可惜在很多場合用不上,起碼它很煩,速度很慢
                
    還有一種選擇就是JDO及類似的東西。最著名是free的應(yīng)該是castor,hibernate等。

    現(xiàn)在我們又多了一種選擇,就是ibatis Db Layer,它的主頁是http://www.ibatis.com,為什么說它好,讓我們來看看作者自己的說明吧,使用ibatis的理由

    10、知道怎樣操作10種以上的數(shù)據(jù)庫
    9
    、可配置的caching(包括從屬)
    8
    、支持DataSource、local transaction managemen
    global transaction
    7
    、簡單的XML配置文檔

    6
    、支持Map, Collection, List和簡單類型包裝(Integer, String)
    5
    、支持JavaBeans(get/set 方法
    )
    4
    、支持復(fù)雜的對象映射(
    populating lists, complex object models)
    3
    、對象模型從不完美(不需要修改
    )
    2
    、數(shù)據(jù)模型從不完美(不需要修改
    )
    1
    、你已經(jīng)知道SQL,為什么還要學(xué)習(xí)其他東西

    另外一點(diǎn)它是100% Open Source Freeware

    下面我們就來看一看,做一個簡單的ibatis需要哪一些工作。然后一步一步深入探索它的強(qiáng)大功能。在實(shí)踐中來看它的好處在哪里。

    ibatis的網(wǎng)站上有一個它自己的petstore,在我個人看來是最簡潔的petstore了,跟struts1.0結(jié)合。應(yīng)該說是一個不錯的教程。希望大家能夠好好研究。當(dāng)然,作為入門。我們先來做一個簡單的程序。所采用的庫嘛,就仍然是用petstore的了。數(shù)據(jù)庫也是選擇Oracle(為什么選擇Oracle,很多朋友不理解,怎么不用mysql之類的呢,一個主要的原因是個人愛好,Oracle畢竟是商業(yè)數(shù)據(jù)庫,有它的強(qiáng)大之處,另外在linux下它也是免費(fèi)的,:)。廢話少說,先用jpetstore3.1提供的ddl建立一個庫吧。

    然后在eclipse里建立一個ibatisDemo的工程。加入ibatis提供的庫,建立相就的目錄??匆幌乱粋€最簡單的程序需要哪一些文件。我們選擇一個簡單表,即Category這個表的操作來演示功能

    文件路徑

    功能說明

    備注

    config\properties\petstore.properties

    可變參數(shù)配置文件,所有根據(jù)環(huán)境不同的參數(shù)都放在這里

     

    config\properties\simple\dao.xml

    dao配置文件,主要存放dao對象和數(shù)據(jù)池設(shè)置

     

    config\properties\simple\sql-map-config-storedb.xml

    真正的核心配置文件

     

    config\sqlmap\Category.xml

    存放Category的數(shù)據(jù)操作的SQL

     

    com.ewuxi.champion.exception.DaoException.java

    自定義的Exception類,不用說了吧

     

    com.ewuxi.champion.Service.java

    一個服務(wù)類,用于初始化

     

    com.ewuxi.champion.persistence.dao.DaoCommon

    Dao層的統(tǒng)一操作類,提供一些公共函數(shù)

     

    com.ewuxi.champion.persistence.dao.CategoryDb

    Category的操作類

     

    com.ewuxi.champion.persistence.vo.Category

    valueObject 值對象

     

    com.ewuxi.champion.persistence.dao.CategoryDbTest

    單元測試類

     

    下面一個一個文件詳細(xì)說明

    petstore.properties

    ##################################################################
    SIMPLE CONFIGURATION SECTION
    ##################################################################

    ## SimpleDataSource properties
    ## Use only if useSimpleConfiguration=true

    SimpleDriver=oracle.jdbc.OracleDriver
    SimpleUrl=jdbc:oracle:thin:@10.0.0.5:1521:champion
    SimpleUsername=pet
    SimplePassword=pet

     

    這個不用解釋,就是數(shù)據(jù)庫的連接串,如果你在自己的機(jī)器上運(yùn)行,當(dāng)然這些都是需要改的。

    dao.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE dao-config
    PUBLIC "-//iBATIS.com//DTD DAO Configuration 1.0//EN"
    "http://www.ibatis.com/dtd/dao.dtd">

    <dao-config>

    <context name="StoreDaoManager" default="true">
    <!-- Configure the transaction pool. -->
    <transaction-pool implementation="com.ibatis.db.dao.jdbc.SqlMapDaoTransactionPool">
    <property name="sql-map-config-file" value="properties/simple/sql-map-config-storedb.xml"/>
    </transaction-pool>

    </context>

    </dao-config>

    上面這一段也是很簡單的,連一個dao也沒有配置,也就是說,用的是默認(rèn)的Dao。其中<context name="StoreDaoManager" default="true">表示它是默認(rèn)的數(shù)據(jù)庫配置(它可以根據(jù)名字不同同時連接幾個數(shù)據(jù)庫的)

    sql-map-config-storedb.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sql-map-config
    PUBLIC "-//iBATIS.com//DTD SQL Map Config 1.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config.dtd">

    <sql-map-config>

    <properties resource="properties/petstore.properties" />

    <settings
    maxExecute="0"
    maxExecutePerConnection="0"
    maxTransactions="0"
    cacheModelsEnabled="true"
    statementCacheSize="175"
    useBeansMetaClasses="false"
    useGlobalTransactions="false" />

    <datasource name="jpestoreSimple"
    factory-class="com.ibatis.db.sqlmap.datasource.DbcpDataSourceFactory"
    default="true" >
    <property name="JDBC.Driver" value="${SimpleDriver}"/>
    <property name="JDBC.ConnectionURL" value="${SimpleUrl}"/>
    <property name="JDBC.Username" value="${SimpleUsername}"/>
    <property name="JDBC.Password" value="${SimplePassword}"/>
    <property name="Pool.MaximumActiveConnections" value="15"/>
    <property name="Pool.MaximumIdleConnections" value="15"/>
    <property name="Pool.MaximumWait" value="1000"/>
    </datasource>

    <sql-map resource="sqlmap/Category.xml" />

    </sql-map-config>

    這里真正實(shí)現(xiàn)了數(shù)據(jù)庫連接,我們使用的是dbcp的連接池。JDBC的配置大家都很熟了。${SimpleDriver}就是指的前面petstore.properties中的SimpleDriver的內(nèi)容。

    <sql-map resource="sqlmap/Category.xml" />則表示包含Category.xml這個文件。

    Category.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sql-map
    PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"
    "http://www.ibatis.com/dtd/sql-map.dtd">

    <sql-map name="Category">

    <result-map name="result" class="com.ewuxi.champion.persistence.vo.Category">
    <property name="categoryId" column="CATID" columnIndex="1" />
    <property name="name" column="NAME" columnIndex="2"/>
    <property name="description" column="DESCN" columnIndex="3"/>
    </result-map>

    <mapped-statement name="findByPrimaryKeyCategoryDao" result-map="result">
    select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#
    </mapped-statement>

    <dynamic-mapped-statement name="findCategoryDao" result-map="result">
    select CATID, NAME, DESCN from CATEGORY
    <dynamic prepend="where">
    <isNotNull prepend="and" property="categoryId" >
    CATID = #categoryId#
    </isNotNull>
    <isNotNull prepend="and" property="name" >
    NAME = #name#
    </isNotNull>
    <isNotNull prepend="and" property="description">
    DESCN = #description#
    </isNotNull>
    </dynamic>
    </dynamic-mapped-statement>


    <mapped-statement name="findCategoryDaoCount" result-class="java.lang.Integer">
    select count(1) as value from CATEGORY
    </mapped-statement>


    <!-- =============================================
    mapped-statement
    ============================================= -->

    <dynamic-mapped-statement name="updateByPrimaryKeyCategoryDao">
    update CATEGORY
    <dynamic prepend="set">
    <isNotNull prepend="," property="name" >
    NAME = #name#
    </isNotNull>
    <isNotNull prepend="," property="description">
    DESCN = #description#
    </isNotNull>
    </dynamic>
    where
    CATID =#categoryId#
    </dynamic-mapped-statement>

    <!-- =============================================
    mapped-statement
    ============================================= -->

    <mapped-statement name="deleteByPrimaryKeyCategoryDao">
    delete from CATEGORY
    where CATID =#categoryId#
    </mapped-statement>

    <!-- =============================================
    OPTIONAL EXPLICIT PARAMETER MAP
    ============================================= -->

    <parameter-map name="insert-params">
    <property name="categoryId"/>
    <property name="name" type="VARCHAR"/>
    <property name="description" type="VARCHAR"/>
    </parameter-map>

    <!-- =============================================
    MAPPED STATEMENTS - w/Explicit Parameter Map
    ============================================= -->

    <mapped-statement name="insertCategoryDao" parameter-map="insert-params" >
    insert into CATEGORY (
    CATID,NAME,DESCN)
    values (
    ?,?,?
    )
    </mapped-statement>
    </sql-map>

    上述文件就是真正的SQL所存在的地方。

    <result-map name="result" class="com.ewuxi.champion.persistence.vo.Category">
    <property name="categoryId" column="CATID" columnIndex="1" />
    <property name="name" column="NAME" columnIndex="2"/>
    <property name="description" column="DESCN" columnIndex="3"/>
    </result-map>

    這一段的內(nèi)容表示返回的對象是com.ewuxi.champion.persistence.vo.Category,也就是我們值對象。當(dāng)執(zhí)行查詢的時候,dblay會封裝出一個Category對象或者一個Categorylist集合。其中數(shù)據(jù)列CATID就對象javabeancategoryId值。name是自定義的

     

    <mapped-statement name="findByPrimaryKeyCategoryDao" result-map="result">
    select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#
    </mapped-statement>

    此處result-map="result"表示返回結(jié)果以后,就會參照前面的result來返回對象。select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#標(biāo)準(zhǔn)的SQL,只不過這一點(diǎn)CATID = #categoryId#有些不同,#categoryId#表示傳遞一個Category對象時,Dblay會自動取得categoryId的值來執(zhí)行SQL

    再來看一個

    <dynamic-mapped-statement name="updateByPrimaryKeyCategoryDao">
    update CATEGORY
    <dynamic prepend="set">
    <isNotNull prepend="," property="name" >
    NAME = #name#
    </isNotNull>
    <isNotNull prepend="," property="description">
    DESCN = #description#
    </isNotNull>
    </dynamic>
    where
    CATID =#categoryId#
    </dynamic-mapped-statement>

    這個地方就體現(xiàn)了dblayer的強(qiáng)大之處,動態(tài)SQL。平常我們經(jīng)常碰到的情況是根據(jù)不同的情況,執(zhí)行的SQL有一點(diǎn)點(diǎn)不一樣。寫在程序里,要寫不少的if then之類的,在這里,dbLayer給你一下解決了。比如在這里,我們?nèi)齻€值都是String對象,所以通過isNotNull就可以實(shí)現(xiàn)幾種不同的update了,比如,如果我只想修改DESCN這個字段,只要傳過去的Category對象只有categoryIddescription有值,就會生成update CATEGORY set DESCN = #description# where CATID =#categoryId#。同樣如果傳遞的對象只有categoryIdname有值,就會生成update CATEGORY set NAME = #name# where CATID =#categoryId#。是否很強(qiáng)大?:)

    前面這兩種,參數(shù)的傳遞方式是內(nèi)置參數(shù),也就是CATID =#categoryId#這種,大家可能不太習(xí)慣,那就看一看標(biāo)準(zhǔn)的寫法吧。

    <!-- =============================================
    OPTIONAL EXPLICIT PARAMETER MAP
    ============================================= -->

    <parameter-map name="insert-params">
    <property name="categoryId"/>
    <property name="name" type="VARCHAR"/>
    <property name="description" type="VARCHAR"/>
    </parameter-map>

    <!-- =============================================
    MAPPED STATEMENTS - w/Explicit Parameter Map
    ============================================= -->

    <mapped-statement name="insertCategoryDao" parameter-map="insert-params" >
    insert into CATEGORY (
    CATID,NAME,DESCN)
    values (
    ?,?,?
    )
    </mapped-statement>
    </sql-map>

    這里面的insert語句想來大家都很熟了吧?這個時候怎么取得參數(shù)呢?關(guān)鍵在于這里parameter-map="insert-params",表示會讀取<parameter-map name="insert-params">的設(shè)置,而這個設(shè)置也不用多解釋了吧,就是按順序,三個?分別對應(yīng)三個值。還能指明他們的數(shù)據(jù)類型。

    下面來看看Service.java


    package com.ewuxi.champion;

    import java.io.Reader;
    import java.util.Properties;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    import com.ibatis.common.resources.Resources;
    import com.ibatis.db.dao.DaoManager;

    /**
    * @author champion
    *
    * To change the template for this generated type comment go to
    * Window - Preferences - Java - Code Generation - Code and Comments
    */
    public class Service {
    static Log log = LogFactory.getLog(Service.class);
    public static void initSet() {

    try {

    String resource = null;

    resource = "properties/simple/dao.xml";
    log.info("Using SIMPLE configuration. (" + resource + ")");

    Reader reader = Resources.getResourceAsReader(resource);
    DaoManager.configure(reader);

    } catch (Exception e) {
    throw new RuntimeException(
    "Could not initialize BaseLogic. Cause: " + e);
    }
    }

    }

    一個靜態(tài)方法,從resource文件中讀出配置,最后用DaoManager.configure(reader);完成配置。

    DaoCommon

    public static Dao getDefautDao(){
    return DaoManager.getInstance().getDao("");
    }
    public static SqlMap getSqlMap(Dao c) throws DaoException {
    try {
    DaoManager daoManager = DaoManager.getInstance(c);

    if (daoManager == null) {
    daoManager = DaoManager.getInstance();
    }

    SqlMapDaoTransaction trans = (SqlMapDaoTransaction) daoManager.getLocalTransaction();
    SqlMap sqlMap = trans.getSqlMap();

    return sqlMap;
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }

    public static SqlMap getSqlMap(String c) throws DaoException {
    try {
    DaoManager daoManager = DaoManager.getInstance(c);
    SqlMapDaoTransaction trans = (SqlMapDaoTransaction) daoManager.getLocalTransaction();
    SqlMap sqlMap = trans.getSqlMap();

    return sqlMap;
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }

    三個主要的函數(shù),第一個是得到默認(rèn)的DAO對象,后兩個是根據(jù)一個dao對象或者一個參數(shù)(也就是前面<context name="StoreDaoManager" >中是name)。取得SqlMap對象,這個對象是主要的數(shù)據(jù)操作接口。

    /**
    * @throws Exception
    *
    開始事務(wù),所在session層必須使用它
    */
    public static void startTransaction() throws Exception {
    if (!DaoCommon.inTransaction()) {
    DaoManager.getInstance().startTransaction();
    }
    }

    public static boolean inTransaction() throws Exception {
    try {
    DaoManager.getInstance().getLocalTransaction();

    return true;
    } catch (Exception e) {
    return false;
    }
    }

    /**
    * @throws Exception
    *
    放棄事務(wù)
    */
    public static void rollBack() {

    try {
    DaoManager.getInstance().rollbackTransaction();
    } catch (Exception e) {
    LogFactory.getLog(DaoCommon.class).error(e, e);
    }
    }

    /**
    * @throws Exception
    *
    提交事務(wù)
    */
    public static void commit() throws Exception {
    DaoManager.getInstance().commitTransaction();
    }

    下面的一些函數(shù)是對事務(wù)的一些封裝。想必也很容易理解。

    然后讓我們來看CategoryDb的內(nèi)容

    /*
    * Created on 2003-10-11
    *
    * To change the template for this generated file go to
    * Window - Preferences - Java - Code Generation - Code and Comments
    */
    package com.ewuxi.champion.persistence.dao;

    import com.ewuxi.champion.exception.DaoException;
    import com.ewuxi.champion.persistence.vo.Category;
    import com.ibatis.db.sqlmap.SqlMap;

    /**
    * @author champion
    *
    *category
    數(shù)據(jù)庫操作對象
    */

    public class CategoryDb {

    /**
    * @param vo
    * @throws DaoException
    *
    插入一條記錄
    */
    public void insert(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    sqlMap.executeUpdate("insertCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }
    /**
    * @param vo
    * @throws DaoException
    *
    刪除一條記錄
    */
    public void delete(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    sqlMap.executeUpdate("deleteByPrimaryKeyCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }
    /**
    * @param vo
    * @throws DaoException
    *
    修改一條記錄
    */
    public void update(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    sqlMap.executeUpdate("updateByPrimaryKeyCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }
    /**
    * @param vo
    * @return
    * @throws DaoException
    *
    查找一條記錄
    */
    public Category findByPk(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    return (Category) sqlMap.executeQueryForObject("findByPrimaryKeyCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }

    }

     

    每一個函數(shù)都很類似的。關(guān)鍵就在這一句(Category) sqlMap.executeQueryForList("findByPrimaryKeyCategoryDao",vo);。看到"findByPrimaryKeyCategoryDao",這個對應(yīng)于前面Category.xml中的名字。而vo則是一個Category對象。

    最后是CategoryDbTest類,這個是我們的單元測試程序

    /*
    * Created on 2003-10-11
    *
    * To change the template for this generated file go to
    * Window - Preferences - Java - Code Generation - Code and Comments
    */
    package com.ewuxi.champion.persistence.dao;

    import com.ewuxi.champion.exception.DaoException;
    import com.ewuxi.champion.persistence.vo.Category;
    import com.ibatis.db.sqlmap.SqlMap;

    /**
    * @author champion
    *
    *category
    數(shù)據(jù)庫操作對象
    */

    public class CategoryDb {

    /**
    * @param vo
    * @throws DaoException
    *
    插入一條記錄
    */
    public void insert(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    sqlMap.executeUpdate("insertCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }
    /**
    * @param vo
    * @throws DaoException
    *
    刪除一條記錄
    */
    public void delete(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    sqlMap.executeUpdate("deleteByPrimaryKeyCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }
    /**
    * @param vo
    * @throws DaoException
    *
    修改一條記錄
    */
    public void update(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    sqlMap.executeUpdate("updateByPrimaryKeyCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }
    /**
    * @param vo
    * @return
    * @throws DaoException
    *
    查找一條記錄
    */
    public Category findByPk(Category vo) throws DaoException{
    try {
    SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
    return (Category) sqlMap.executeQueryForObject("findByPrimaryKeyCategoryDao",vo);
    } catch (Exception e) {
    throw new DaoException(e);
    }
    }

    }

    運(yùn)行結(jié)果,測試通過。原代碼全部下載

     

    主站蜘蛛池模板: 免费视频精品一区二区| 国产aⅴ无码专区亚洲av麻豆| 7777久久亚洲中文字幕蜜桃| 成人无码区免费A∨直播| 亚洲国产成人爱av在线播放| 四虎影视在线看免费观看| 国产zzjjzzjj视频全免费| 国产精品亚洲一区二区三区| 免费大香伊蕉在人线国产| 看免费毛片天天看| 国产L精品国产亚洲区久久| 一级毛片在线播放免费| 亚洲综合图色40p| 久久精品免费电影| 亚洲精品在线免费观看视频| 国产国产人免费视频成69堂| 天堂亚洲国产中文在线| 丁香花在线观看免费观看| 亚洲av无码一区二区三区四区| 免费人成视频在线观看视频| 一个人免费观看www视频| 久久久亚洲欧洲日产国码农村| 精品无码无人网站免费视频| 亚洲欧洲日本在线观看| 四虎影院永久免费观看| 国产无限免费观看黄网站| 亚洲久本草在线中文字幕| 无人在线观看免费高清视频 | 国产成人高清精品免费鸭子| 美女尿口扒开图片免费| 亚洲线精品一区二区三区| 99热免费在线观看| 亚洲熟女综合色一区二区三区 | 亚洲国产精品免费视频| 中文字幕av无码无卡免费| 青青青亚洲精品国产| 337p日本欧洲亚洲大胆裸体艺术| 最近免费mv在线电影| 国产亚洲精品欧洲在线观看| 亚洲AV无码国产精品麻豆天美| 99久久99久久精品免费看蜜桃|