1. <bdo id="8zfej"></bdo>
    <li id="8zfej"><meter id="8zfej"><th id="8zfej"></th></meter></li>

    南京中博教育

    全國咨詢電話:15195455103

    三分鐘了解中博教育
    當前位置:南京中博教育 > 學習園地 > 編程技巧

    ibatis技術文檔

    來源:南京中博教育張府園校區? ? ? 作者:IT教育 ? ??

    ibatis一詞來源于“internet”和“abatis”的組合,是一個由Clinton Begin在2001年發起的開放源代碼項目。初側重于密碼軟件的開發,現在是一個基于Java的持久層框架。 將“Internet”中象征

    ibatis介紹
    ibatis簡介:
     ibatis一詞來源于“internet”和“abatis”的組合,是一個由Clinton Begin在2001年發起的開放源代碼項目。初側重于密碼軟件的開發,現在是一個基于Java的持久層框架。
     將“Internet”中象征性的“i”和abatis中的“batis”組合所以暗示了抵御Internet的意思。
     相對Hibernate和Apache OJB等“一站式”ORM解決方案而言,ibatis 是一種“半 自動化”的ORM實現。
     ibatis需要手寫sql語句,也可以生成一部分,Hibernate則基本上可以自動生成,偶爾會寫一些Hql。同樣的需求, ibatis的工作量比Hibernate要大很多。類似的,如果涉及到數據庫字段的修改,Hibernate修改的地方很少,而ibatis要把那些sql mapping的地方一一修改。
     可維護性方面,ibatis更好一些。因為 iBatis 的 sql 都保存到單獨的文件中。而 Hibernate 在有些情況下可能會在 java 代碼中保sql/hql。
     如果你開發一個新系統,希望完全控制對象模型,進行數據庫設計,那么Hibernate是一個好的選擇;如果你工作在一個很古老的數據庫系統上,數據庫設計非常糟糕,你又沒有權利去改變數據庫設計,那么iBATIS更合適一些。
     因為ibatis是以SQL的方式開發,所以ibatis自身是不能動態生成表的,當然可以把SQL預先寫入xml中,但是這種方式在開發中使用率并不高,并且以后不斷的建表會比較繁瑣,所以通常情況下,我們需要首先創建表,然后再使用ibatis來操作數據,在這方面,就沒有hibernate建表那么容易。
     
    ibatis簡單入門
    ibatis快速開發:
     創建一個java項目,然后導入驅動包到lib文件夾下面,我們需要的驅動包有ibatis-2.3.4.726.jar和classes12.jar,然后添加一個SqlMapConfig.xml到src下面,在此xml中寫入以下內容:
    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE sqlMapConfig     
        PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
        "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

    <sqlMapConfig>

      <transactionManager type="JDBC" commitRequired="false">
        <dataSource type="SIMPLE">
          <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver"/>
          <property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@localhost:1521:ORAC"/>
          <property name="JDBC.Username" value="test"/>
          <property name="JDBC.Password" value="test"/>
        </dataSource>
      </transactionManager>

      <sqlMap resource="com/cn/thinkmore/bean/BuMen_SqlMap.xml"/>

    </sqlMapConfig>

    然后創建一個pojo,對應數據庫中的一個表,例如:
    package com.cn.thinkmore.bean;

    public class BuMen {
     private String bid;

     private String bumenname;
     
     private String bumencode;

     public BuMen(){}
     
     public String getBumencode() {
      return bumencode;
     }

     public void setBumencode(String bumencode) {
      this.bumencode = bumencode;
     }

     public String getBid() {
      return bid;
     }

     public void setBid(String bid) {
      this.bid = bid;
     }

     public String getBumenname() {
      return bumenname;
     }

     public void setBumenname(String bumenname) {
      this.bumenname = bumenname;
     }

    }
    接著創建此pojo的映射xml文件,名字自定義,盡量pojo類名_SqlMap命名,我在這里的創建的POJO類名叫BuMen,所以我創建此xml文件叫BuMen_SqlMap.xml
    <?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>

      <select id="selectAll" resultClass="com.cn.thinkmore.bean.BuMen">
          select bid,bumenname,bumencode from BuMen
      </select>

    </sqlMap>

    后,我們來創建一個帶有main方法的測試類:
    package com.cn.thinkmore.bean;

    import java.io.IOException;
    import java.io.Reader;
    import java.sql.SQLException;
    import java.util.List;

    import com.ibatis.common.resources.Resources;
    import com.ibatis.sqlmap.client.SqlMapClient;
    import com.ibatis.sqlmap.client.SqlMapClientBuilder;

    public class TestConsole {
     
       private static SqlMapClient sqlMapClient;
     
     static {
         try {
           Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
           sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
           reader.close();
         } catch (IOException e) {
           // Fail fast.
           throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
         }
       }
     public static void main(String[] args) {
      try {
       List list = sqlMapClient.queryForList("selectAll");
       System.out.println(list);
       for(Object obj:list){
        BuMen bm = (BuMen)obj;
        System.out.println("bid="+bm.getBid()+"   bumenname="+bm.getBumenname()+"  bumencode="+bm.getBumencode());
       }
      }catch (SQLException e) {
       e.printStackTrace();
      }
     }
    }
    后運行成功,這樣我們就快速搭配起來了ibatis的環境了。
    ibatis核心技術
    ibatis配置文件---sqlMapConfig.xml:
     下面,我們來詳細介紹sqlMapConfig中的常用標簽:
     
    <sqlMapConfig>
      配置文件的父標簽,所有標簽必須寫在此標簽內部。

    <properties/>       
     引用屬性文件,用于引用標準的propertis屬性文件。
     在屬性文件中定義的屬性,可以作為變量在配置文件及其包含的所有映射文件中引用,例如:如果在屬性文件中包含如下屬性:
     url=jdbc:oracle:thin:@localhost:1521:ORAC
     那么就可以在xml文件中,這樣調用:
     <property name=" JDBC.ConnectionURL" value="${url}"/>
                   
    <settings/>         
     設置屬性,用于配置和優化SqlMap實例的各種屬性,此標簽本身及其所有的屬性都是可選的。下面是它的內部屬性介紹:
     maxRequests:同時執行SQL語句的大線程數。大于這個值的時候,后面的線程將被阻塞,直到有線程執行完成,不同的數據庫有不同的限制值,但是任何數據庫通常應該把此屬性值設置為maxTransactions的10倍,并且總是大于maxSessions和maxTransactions,減少此值可能會提高性能(默認值 512)
     maxSessions:同一時間內活動的大Session數,一個Session可以是代碼請求的顯式Session,也可以是當線程使用SqlMapClient實例(執行一條語句)自動獲得的Session,它應該總是大于或者等于maxTransactions
    并且小于maxRequests,減小這個參數值可能會減少內存使用(默認值 128)
     maxTransactions:同時進入SqlMapClient.startTransaction()的大線程數,大于這個值的線程將阻塞直到另一個線程退出。不同的數據庫有不同的限制值,但任何數據庫都有這些限制,這個參數值應該總是小于或等于maxSessions,并總是遠遠小于maxRequests,減小這個參數值可能會提高性能(默認值 32)
     cacheModelsEnabled:全局性的啟用或禁用SqlMapClient的所有緩存Model,在調試程序時使用(默認值 true)
     lazyLoadingEnabled:全局性的啟用或禁用SqlMapClient的所有延遲加載,在調試程序時使用(默認值 true)
     useStatementNamespaces:如果啟用本屬性,則必須使用全限定名來引用執行命令,例如:sqlMapClient.queryForObject("映射文件名.方法名");
    (默認值 false)      
            
    <transactionManager/>  
     定義事務管理器,包含一個唯一的屬性type,用以指定使用的事務管理器類型。有三種不同的選擇:JDBC,JTA,EXTERNAL
     JDBC:讓jdbc來管理事務(常用)
     JTA:使用JTA全局事務
     EXTERNAL:可以讓開發人員來管理事務
            
    <dataSource/>     
     定義數據源,type="SIMPLE"定義一個基本的實現,基于ibatis的SimpleDataSource連接池實現,其別名為SIMPLE
      
    <property/>      
     設置數據源參數
     JDBC.Driver           JDBC驅動程序類名
     JDBC.ConnectionURL    數據庫URL
     JDBC.Username         數據庫用戶名
     JDBC.Password         數據庫密碼
     JDBC.DefaultAutoCommit 連接池中所有連接默認的自動提交模式(默認為true)
     Pool.MaximumActiveConnections 數據庫連接池可維持的大容量 默認值為10
     Pool.MaximumIdleConnections  數據庫連接池中允許的掛起連接數,默認值為5
     
    <sqlMap/>       
     引用映射文件

    POJO映射文件---SqlMap.xml:

    <sqlMap namespace="BuMen">
      此配置文件的父標簽,所有標簽都需要配置在此標簽內部,它可以設定一個命名空間,但是通常沒有作用。

    <typeAlias alias="BuMen" type="com.cn.thinkmore.bean.BuMen"/>
     為POJO設置一個別名,為了在使用SQL標簽的時候引用,例如:
     <select id="selectOne" resultClass="BuMen">
     type屬性是指定POJO的包名+類名,alias屬性是給此POJO定義一個別名,為以后調用

    <resultMap id="BuMenResult" class="BuMen">
        <result property="bid" javaType="java.lang.String" column="bid" jdbcType="varchar2" nullValue="null"/>
        <result property="bumenname" column="bumenname"/>
        <result property="bumencode" column="bumencode"/>
    </resultMap>
     設置結果集映射,優先選用resultClass而不是resultMap,此標簽大多時候用于存儲過程的處理
     id:引用的值
          class:映射的POJO
          result標簽是指定每一個屬性
          property:指定關聯的屬性名
          javaType:指定屬性的類型
          column:指定此屬性關聯的字段名
          jdbcType:指定字段的類型
          nullValue:當此屬性沒有取到值的時候,指定的默認值
     通常情況下,只需要設置property和column屬性。

     下面介紹在ibatis中怎么操作數據庫的增刪改查,對應的標簽分別是insert, delete,update,select,在這四個標簽中,都有id,resultClass,parameterClass常用屬性:

     id:指定要調用的名字
     parameterClass:指定傳入參數的類型,例如:parameterClass="com.cn.thinkmore.bean.BuMen",也可以設定為基本類型
    parameterMap:指定傳入參數的類型,(很少使用)
    resultClass:指定返回的類型,例如:
     resultClass="com.cn.thinkmore.bean.BuMen",也可以設定為基本類型
    resultMap:指定返回的類型,(很少使用)

      注意:為了避免特殊符號與XML的標簽沖突,所以有時候需要使用
    <![CDATA[select * from BuMen where bid<#bid#]]>的方式來編寫SQL

    <select id="selectAll" resultClass="com.cn.thinkmore.bean.BuMen">
          select bid,bumenname,bumencode from BuMen
    </select>
     定義一個SQL的插入語句,ibatis會自動根據select語句中的字段名,調用對應POJO 的set方法設定屬性值,如上例中,ibatis會調用setBid,setBumenname,setBumencode 方法將Select語句返回的數據,裝載到相應的POJO實例屬性中。
     
    <insert id="insertObj" parameterClass="com.cn.thinkmore.bean.BuMen">
        insert into BuMen(bid,bumenname,bumencode) values (#bid#,#bumenname#,#bumencode#)
    </insert>
     定義一個SQL的插入語句,ibatis會自動根據select語句中的字段名,調用對應POJO 的get方法設定屬性值,如上例中,ibatis會調用getBid,getBumenname,getBumencode 方法將POJO實例屬性中的值插入了SQL語句中。

    <delete id="deleteObj" parameterClass="int">
       delete from BuMen where bid=#bid#
    </delete>
      定義一個SQL的刪除語句,parameterClass屬性定義傳入的類型為Integer類型,它會自動添加到#bid#位置,現在的#bid#不會再調用set或者get,ibatis會自動把它當做填充符使用。

    <update id="updateObj" parameterClass="bumen">
       update bumen set bid=#bid#,bumenname=#bumenname#,bumencode=#bumencode# where bumencode=#bumencode#
    </update>
     定義一個SQL的更新語句。
     
    使用SqlMapClient操作
     SqlMapClient的開發:
     每一個Dao或者Service都會有一個SqlMapClient的實例,通常情況,我們并不希望外部能訪問此實例對象,所以我們需要這樣做:
        private static SqlMapClient sqlMapper;
     為了讓程序在開始的時候就可以操作數據庫,所以,我們還需要一個靜態方法來自動創建這個實例:
     static {
         try {
           Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
           sqlmapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
           reader.close();
         } catch (IOException e) {
           // Fail fast.
           throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
         }
        }
     這樣做了以后,我們就可以創建我們想操作數據庫的方法了。
     我們在第二章里面已經學習怎樣快速搭建ibatis并且把它使用起來了,現在來說說,開發中,有哪些方法可以讓我們操作,這些方法都需要SqlMapClient的實例來調用。
     
     1. sqlmapClient.queryForList(String id)  基于一個id指定的sql來執行查詢,返回一個List
     2. sqlmapClient.queryForList(String id,Object param) 基于一個id和一個字符串參數來執行查詢,返回一個List
     3. sqlmapClient.queryForList(String id,Object pojo) 基于一個id和一個pojo參數來執行查詢,返回一個List
     4. sqlmapClient.queryForList(String id,Object map) 基于一個id和一個map參數來執行查詢(適合于多參查詢的時候使用),返回一個List
     5. sqlmapClient.queryForObject(String id) 基于一個id來執行查詢,返回一個Object,此方法也有4種常用方式,用法和queryForList一樣,只是返回值只有一個。
     6. sqlmapClient.update(String id) 基于一個id來執行更新,返回一個Integer值決定執行了多少條記錄,此方法也有4種常用方式,和queryForList類似,只是返回值是執行的結果個數
     7. sqlmapClient.insert(String id) 和update類似
     8. sqlmapClient.delete(String id) 和update類似
     
    事務管理
     SqlMapClient中的事務:
    sqlMapClient.startTransaction();  
     開始事務
    sqlMapClient.commitTransaction();
        提交事務
    sqlMapClient.endTransaction();   
       結束事務,操作失敗的時候,整個事務就會在endTransaction時回滾。
     新版的ibatis中,不再有rollbackTransaction方法,只能選擇endTransaction代替。
     如果代碼沒有顯式的調用SqlMapClient.startTransaction()方法,則ibatis會將當前的數據庫操作視為自動提交模式(AutoCommit=true),不過,值得注意的是,這里的所謂“自動判定”,實際上ibatis并沒有去檢查當前是否已經有事務開啟。
        實際上,在執行update語句時,sqlMap會檢查當前的Session是否已經關聯了某個
    數據庫連接,如果沒有,則取一個數據庫連接,將其AutoCommit屬性設為true,然后
    執行update 操作,執行完之后又將這個連接釋放。這樣,上面兩次update 操作實際上
    先后獲取了兩個數據庫連接,而不是我們通常所認為的兩次update 操作都基于同一個
    JDBC Connection。這點在開發時需特別注意。
     對于多條SQL 組合而成的一個JDBC 事務操作而言,必須使用startTransaction、commit和endTransaction操作以實現整體事務的原子性。
     注意!事務不能嵌套。在調用commit或end方法之前,從同一線程多次調用startTransaction將引起拋出例外。換句話說,對于每個SqlMap實例,每個線程多只能打開一個事務。
     
     
    深入SqlMap.xml中的SQL開發
     增刪改查4種SQL的深入化開發:

    <select id="selectLike"  parameterClass="java.lang.String" resultClass="bumen">
        select * from BuMen where bumencode like '%$bumencode$%'
    </select>
    當我們需要使用模糊查詢的時候,通配符需要特殊處理,否則無法查詢到想要的數據


    <select id="selectUser"  parameterClass="bumen" resultClass="int">
        select count(*) from BuMen where bid=#bid# and bumenname=#bumenname#
    </select>
     我們可以使用聚集函數來查詢,返回類型定義為int類型,也就是java.lang.Integer類型,這里我們傳入的參數是一個POJO類型,ibatis會自動get需要的屬性值,不用的屬性值不會get出來,這樣做雖然可以實現查詢,但是看來有點浪費資源。
     
     
    <resultMap id="BuMenResult" class="BuMen">
        <result property="bid" javaType="java.lang.String" column="bid" jdbcType="varchar2" nullValue="null"/>
        <result property="bumenname" column="bumenname"/>
        <result property="bumencode" column="bumencode"/>
    </resultMap>
    <select id="selectUser"  parameterClass="bumen" resultMap="BuMenResult">
        select count(*) from BuMen where bid=#bid# and bumenname=#bumenname#
    </select>
     和上面的查詢是一樣的效果,只是返回的方式有所改變,我們這次選用了resultMap來返回,這樣做的好處是可以讓其他開發人員來看懂POJO和數據庫中表的對應關系。
     
     
    <select id="selectAll2" parameterClass="int" resultClass="bumen">
          <![CDATA[select bid as id,bumenname as name,bumencode as code from BuMen where bid<#bid#]]>
      </select>
     數據庫表中的字段名和POJO中的屬性名不相同的時候,我們希望字段映射到POJO時,我們可以通過Select的as 字句對字段名進行轉義,這樣就會調用POJO的setId,setName,SetCode方法裝載數據。并且小于符號是xml中的關鍵字,使用會報錯,所以,我們還需要<![CDATA[……]]>的方式來編寫SQL語句。
     

    <update id="updateUser" parameterClass="java.util.Map">
     update bumen
     set
     bumenname=#bumenname#,
     bumencode=#bumencode#
     where bid = #bid#
      </update>
      這里傳入的參數就是一個Map對象,ibatis將以key "bid"、"bumenname"、"bumencode"從中提取對應的參數值,
      此方式大部分時候用于嵌套查詢,或者多表查詢,把要查詢的條件以Map拼接。
      此方式還可以用于任意的增刪改查SQL中,例如,我們要查詢一個用戶的名字和密碼是否存在的時候。


    <select id="getUsers" parameterClass="bumen" resultClass="bumen">
       select bid,bumenname,bumencode from bumen
       <dynamic prepend="where">
        <isNotEmpty prepend="and" property="bumenname">
       (bumenname=#bumenname#)
           </isNotEmpty>
        <isNotEmpty prepend="and" property="bumencode">
       (bumencode=#bumencode#)
        </isNotEmpty>
       </dynamic>
       </select>
     在很多時候,可能我們需要一些變化的sql語句,比如說,當用戶輸入幾個關鍵字查詢的時候,我們需要判斷用戶到底輸入了幾個關鍵字,然后通過if-else的方式,組建不同的SQL語句來操作數據庫,但是這樣做的話,會產生大量的代碼或者配置文件內容,但是我們在使用ibatis的時候,可以避免這個問題,我們通過dynamic節點,定義了一個動態的where子句。此where子句中將可能包含兩個針對bumenname和bumencode 字段的判斷條件。而這兩個字段是否加入查詢取決于用戶所提供的查詢條件(字段是否為空[isNotEmpty])。
     由于ibatis會自動判定是否需要追加prepend前綴,這里(bumenname=#bumenname#)是where 子句中的第一個條件子句,無需and前綴,所以自動省略。
     當用戶沒有傳入參數的時候,我們可以讓ibatis使用全表查詢,也就是上面配置中的select bid,bumenname,bumencode from bumen語句,如果用戶傳入了一個參數查詢的時候,我們可以讓ibatis基于一個條件查詢,也就是上面配置中的
    select bid,bumenname,bumencode from bumen where bumenname=#username#語句,如果用戶傳入了兩個參數查詢的時候,我們可以讓ibatis基于兩個條件查詢,也就是上面配置中的
    select bid,bumenname,bumencode from bumen where bumenname=#username# and bumencode=#bumencode#語句,通過這樣的方式,我們就可以靈活的操作用戶的查詢規則,而不必要去增加太多的代碼和配置內容,下面還有幾種判定標簽可以使用。
    <isPropertyAvailable> 參數類中是否提供了此屬性
    <isNotPropertyAvailable> 與<isPropertyAvailable>相反
    <isNull> 屬性值是否為NULL
    <isNotNull> 與<isNull>相反
    <isNotEmpty> 屬性值是否為空。
    <isEmpty> 與<isNotEmpty>相反


    二元判斷(使用方式和dynamic節點一樣,只是加入了一個屬性compareValue,它可以指定一個比較值):
    例如:
    <isEqual prepend="AND" property="bid" compareValue="18">
                (bid=#bid#)
    </isEqual>
    上面的作用是如果bid屬性等于18(compareValue),則在SQL中加入(bid=#bid#)條件。
    同樣,二元判斷也有及各種判斷標簽供我們選擇。
    <isEqual> 相等。
    <isNotEqual> 不等。
    <isGreaterThan> 大于
    <isGreaterEqual> 大于等于
    <isLessThan> 小于
    <isLessEqual> 小于等于


    分享到:
    近期文章

    搶試聽名額

    名額僅剩66名

    教育改變生活

    WE CHANGE LIVES

    主站蜘蛛池模板: 久久综合日本熟妇| 色欲色香天天天综合网WWW| 久久婷婷午色综合夜啪| 久久乐国产综合亚洲精品| 丁香五月综合缴情综合| 天天综合网网欲色| 色777狠狠狠综合| 一本一本久久a久久精品综合麻豆| 国产天天综合永久精品日| 国产成+人+综合+亚洲专| 亚洲国产综合精品中文字幕| 97久久天天综合色天天综合色hd| 狠狠色综合网站久久久久久久 | 色五月丁香五月综合五月4438| 狠狠色狠狠色很很综合很久久| 久久伊人久久亚洲综合| 国产亚洲综合久久系列| 人妻一本久道久久综合久久鬼色| 97se亚洲综合在线| 色婷婷综合久久久中文字幕| 久久本道综合久久伊人| 伊人久久亚洲综合影院| 色天天综合色天天看| 国产精品一区二区综合| 在线综合亚洲欧洲综合网站| 亚洲综合小说久久另类区| 九月丁香婷婷亚洲综合色| 婷婷综合久久中文字幕蜜桃三电影| 一本久道久久综合多人| 一本色道久久99一综合| 狠狠色噜噜狠狠狠狠狠色综合久久| 国产精品激情综合久久| 久久综合九九亚洲一区| 久久综合日韩亚洲精品色| 五月天激激婷婷大综合丁香| 亚洲av日韩av综合| 色偷偷91综合久久噜噜| 久久久久亚洲AV综合波多野结衣| 亚洲综合精品香蕉久久网| 久久综合亚洲色一区二区三区| 色噜噜狠狠成人中文综合|