Mybatis基礎(chǔ)知識(shí)4-Java API

5.Java API

5.1 典型應(yīng)用的目錄結(jié)構(gòu)

在我們深入 Java API 之前,理解關(guān)于目錄結(jié)構(gòu)的最佳實(shí)踐是很重要的。MyBatis 非常靈活, 你可以用你自己的文件來(lái)做幾乎所有的事情。 但是對(duì)于任一框架, 都有一些最佳的方式。

讓我們看一下典型應(yīng)用的目錄結(jié)構(gòu):

/my_application
  /bin
  /devlib
  /lib                <-- MyBatis *.jar文件在這里。
  /src
    /org/myapp/
      /action
      /data           <-- MyBatis配置文件在這里, 包括映射器類(lèi), XML配置, XML映射文件。
        /mybatis-config.xml
        /BlogMapper.java
        /BlogMapper.xml
      /model
      /service
      /view
    /properties       <-- 在你XML中配置的屬性 文件在這里。
  /test
    /org/myapp/
      /action
      /data
      /model
      /service
      /view
    /properties
  /web
    /WEB-INF
      /web.xml

5.2 SqlSessions

使用 MyBatis 的主要 Java 接口就是 SqlSession。

5.2.1 如果獲取 一個(gè) SqlSession 實(shí)例

SqlSessions 是由 SqlSessionFactory 實(shí)例創(chuàng)建的。SqlSessionFactory 對(duì) 象 包 含 創(chuàng) 建 SqlSession 實(shí) 例 的 所 有 方 法 。 而 SqlSessionFactory 本 身 是 由 SqlSessionFactoryBuilder 創(chuàng)建的,它可以從 XML 配置,注解或手動(dòng)配置 Java 來(lái)創(chuàng)建 SqlSessionFactory。
NOTE:如果使用的是Spring或者Guice框架,SqlSessions由DI框架生成和注入。

5.2.2 語(yǔ)句執(zhí)行方法

這些方法被用來(lái)執(zhí)行定義在 SQL 映射的 XML 文件中的 SELECT,INSERT,UPDA E T 和 DELETE 語(yǔ)句。它們都會(huì)自行解釋,每一句都使用語(yǔ)句的 ID 屬性和參數(shù)對(duì)象,參數(shù)可以 是原生類(lèi)型(自動(dòng)裝箱或包裝類(lèi)) ,JavaBean,POJO 或 Map。

     T selectOne(String statement, Object parameter)
     List selectList(String statement, Object parameter)
     Map selectMap(String statement, Object parameter, String mapKey)
    int insert(String statement, Object parameter)
    int update(String statement, Object parameter)
    int delete(String statement, Object parameter)

selectOne 和 selectList 的不同僅僅是 selectOne 必須返回一個(gè)對(duì)象。 如果多于一個(gè), 或者 沒(méi)有返回 (或返回了 null) 那么就會(huì)拋出異常。 如果你不知道需要多少對(duì)象, 使用 selectList。

如果你想檢查一個(gè)對(duì)象是否存在,那么最好返回統(tǒng)計(jì)數(shù)(0 或 1) 。因?yàn)椴⒉皇撬姓Z(yǔ)句都需 要參數(shù),這些方法都是有不同重載版本的,它們可以不需要參數(shù)對(duì)象。

     T selectOne(String statement)
     List selectList(String statement)
     Map selectMap(String statement, String mapKey)
    int insert(String statement)
    int update(String statement)
    int delete(String statement)

最后,還有查詢(xún)方法的三個(gè)高級(jí)版本,它們?cè)试S你限制返回行數(shù)的范圍,或者提供自定 義結(jié)果控制邏輯,這通常用于大量的數(shù)據(jù)集合。

<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)

RowBounds 參數(shù)會(huì)告訴 MyBatis 略過(guò)指定數(shù)量的記錄,還有限制返回結(jié)果的數(shù)量。 RowBounds 類(lèi)有一個(gè)構(gòu)造方法來(lái)接收 offset 和 limit,否則是不可改變的。

    int offset = 100;
    int limit = 25;
    RowBounds rowBounds = new RowBounds(offset, limit);

不同的驅(qū)動(dòng)會(huì)實(shí)現(xiàn)這方面的不同級(jí)別的效率。對(duì)于最佳的表現(xiàn),使用結(jié)果集類(lèi)型的 SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE(或句話說(shuō):不是 FORWARD_ONLY)。

ResultHandler 參數(shù)允許你按你喜歡的方式處理每一行。你可以將它添加到 List 中,創(chuàng) 建 Map, 或拋出每個(gè)結(jié)果而不是只保留總計(jì)。 Set 你可以使用 ResultHandler 做很多漂亮的事, 那就是 MyBatis 內(nèi)部創(chuàng)建結(jié)果集列表。

它的接口很簡(jiǎn)單。

    package org.apache.ibatis.session;
    public interface ResultHandler {
      void handleResult(ResultContext context);
    }

ResultContext 參數(shù)給你訪問(wèn)結(jié)果對(duì)象本身的方法, 大量結(jié)果對(duì)象被創(chuàng)建, 你可以使用布 爾返回值的 stop()方法來(lái)停止 MyBatis 加載更多的結(jié)果。

5.2.3 事務(wù)控制方法

控制事務(wù)范圍有四個(gè)方法。 當(dāng)然, 如果你已經(jīng)選擇了自動(dòng)提交或你正在使用外部事務(wù)管 理器,這就沒(méi)有任何效果了。然而,如果你正在使用 JDBC 事務(wù)管理員,由 Connection 實(shí) 例來(lái)控制,那么這四個(gè)方法就會(huì)派上用場(chǎng):

    void commit()
    void commit(boolean force)
    void rollback()
    void rollback(boolean force)

默認(rèn)情況下 MyBatis 不會(huì)自動(dòng)提交事務(wù), 除非它偵測(cè)到有插入, 更新或刪除操作改變了 數(shù)據(jù)庫(kù)。如果你已經(jīng)做出了一些改變而沒(méi)有使用這些方法,那么你可以傳遞 true 到 commit 和 rollback 方法來(lái)保證它會(huì)被提交(注意,你不能在自動(dòng)提交模式下強(qiáng)制 session,或者使用 了外部事務(wù)管理器時(shí)) 。很多時(shí)候你不用調(diào)用 rollback(),因?yàn)槿绻銢](méi)有調(diào)用 commit 時(shí) MyBatis 會(huì)替你完成。然而,如果你需要更多對(duì)多提交和回滾都可能的 session 的細(xì)粒度控 制,你可以使用回滾選擇來(lái)使它成為可能。
NOTE: Spring提供聲明式事務(wù)處理

5.2.4 清理 Session 級(jí)的緩存

void clearCache()

SqlSession 實(shí)例有一個(gè)本地緩存在執(zhí)行 update,commit,rollback 和 close 時(shí)被清理。要 明確地關(guān)閉它 ,你可以調(diào)用 clearCache()。

5.2.5 確保 SqlSession 被關(guān)閉

你必須保證的最重要的事情是你要關(guān)閉所打開(kāi)的任何 session。保證做到這點(diǎn)的最佳方 式是下面的工作模式:

    SqlSession session = sqlSessionFactory.openSession();
    try {
        // following 3 lines pseudocod for "doing some work"
        session.insert(...);
        session.update(...);
        session.delete(...);
        session.commit();
    } finally {
        session.close();
    }

或者:
    try (SqlSession session = sqlSessionFactory.openSession()) {
        // following 3 lines pseudocode for "doing some work"
        session.insert(...);
        session.update(...);
        session.delete(...);
        session.commit();
    }

5.2.6 使用映射器

一個(gè)更通用的方式來(lái)執(zhí)行映射語(yǔ)句是使用映射器類(lèi)。 一個(gè)映射器類(lèi)就是一個(gè)簡(jiǎn)單 的接口,其中的方法定義匹配于 SqlSession 方法。下面的示例展示了一些方法簽名和它們是 如何映射到 SqlSession 的。

    public interface AuthorMapper {
      // (Author) selectOne("selectAuthor",5);
      Author selectAuthor(int id);
      // (List) selectList("selectAuthors")
      List selectAuthors();
      // (Map) selectMap("selectAuthors", "id")
      @MapKey("id")
      Map selectAuthors();
      // insert("insertAuthor", author)
      int insertAuthor(Author author);
      // updateAuthor("updateAuthor", author)
      int updateAuthor(Author author);
      // delete("deleteAuthor",5)
      int deleteAuthor(int id);
    }
  • 注解
    這個(gè)例子展示了如何使用 @SelectKey 注解來(lái)在插入前讀取數(shù)據(jù)庫(kù)序列的值:
@Insert("insert into table3 (id, name) values(#{nameId}, #{name})")
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class)
int insertTable3(Name name);

這個(gè)例子展示了如何使用 @SelectKey 注解來(lái)在插入后讀取數(shù)據(jù)庫(kù)識(shí)別列的值:

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的...
    笨鳥(niǎo)慢飛閱讀 6,220評(píng)論 0 4
  • MyBatis 理論篇 [TOC] 什么是MyBatis ?MyBatis是支持普通SQL查詢(xún),存儲(chǔ)過(guò)程和高級(jí)映射...
    有_味閱讀 3,168評(píng)論 0 26
  • # 前言 在java程序員的世界里,最熟悉的開(kāi)源軟件除了 Spring,Tomcat,還有誰(shuí)呢?當(dāng)然是 Mybat...
    莫那一魯?shù)?/span>閱讀 3,436評(píng)論 3 11
  • 兒女對(duì)父母的愛(ài)——母親節(jié) 2016-05-08 17:08:584感情 在這個(gè)世界上,有一個(gè)人會(huì)對(duì)你孜孜不倦的訴說(shuō)...
    少爺0213閱讀 432評(píng)論 0 0
  • L西, 目標(biāo)滿(mǎn)分, 一個(gè)生肖周期的年齡差寫(xiě)滿(mǎn)我的震驚臉…… 碎片式記憶也是回憶的一劑良藥
    silence談閱讀 306評(píng)論 0 0

友情鏈接更多精彩內(nèi)容