Mybatis簡介

俺就不起網名發表於2018-07-31

一、入門

1、匯入mybatis相關jar包
2、獲取 SqlSession。


通過 SqlSessionFactoryBuilder 獲取到 SqlSessionFactory,然後再通過 SqlSessionFactory 獲取到 SqlSession。


2-1、獲取 SqlSessionFactoryBuilder 的兩種方式

1、xml配置獲取

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

2、java程式碼獲取

//構建資料庫連線池, POOLED:這是JDBC連線物件的資料來源連線池的實現,用來避免建立新的連線例項時必要的初始連線和認證時間
        PooledDataSource dataSource = new PooledDataSource();
        dataSource.setDriver("oracle.jdbc.OracleDriver");
        dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        //事務方式
        TransactionFactory transactionFactory = new JdbcTransactionFactory();

        //執行環境
        Environment environment = new Environment("development", transactionFactory, dataSource);

        //構建Configuration物件
        Configuration configuration = new Configuration(environment);

        //註冊一個mybatis上下文別名
        configuration.getTypeAliasRegistry().registerAlias("person", Person.class);

        //加入一個對映器
        configuration.addMapper(PersonMapper.class);//sql通過註解方式,而不是xml方式

        //使用sqlsessionFactoryBuild構建sqlsessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

        return sqlSessionFactory;

註解sql mapper介面程式碼:

public interface PersonMapper2 {
    @Select("SELECT * FROM PERSON WHERE id = #{id}")
    Person2 selectByPrimaryKey(Integer id);
}

通過xml配置,mapper類只是個介面,具體sql在xml檔案中; 

2-2、獲取SqlSession

SqlSession session = sqlSessionFactory.openSession();
try {
  PersonMapper mapper = session.getMapper(PersonMapper.class);
  PersonMapper person = mapper.selectByPrimaryKey(1);
} finally {
  session.close();
}

3、物件的生命週期

SqlSessionFactoryBuilder:

這個類可以被例項化、使用和丟棄,一旦建立了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 例項的最佳作用域是方法作用域(也就是區域性方法變數)。

SqlSessionFactory:

SqlSessionFactory 一旦被建立就應該在應用的執行期間一直存在,沒有任何理由對它進行清除或重建。使用 SqlSessionFactory 的最佳實踐是在應用執行期間不要重複建立多次,多次重建 SqlSessionFactory 被視為一種程式碼“壞味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是應用作用域。有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

SqlSession:

每個執行緒都應該有它自己的 SqlSession 例項。SqlSession 的例項不是執行緒安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。絕對不能將 SqlSession 例項的引用放在一個類的靜態域,甚至一個類的例項變數也不行。

對映器例項(Mapper Instances):

對映器是一個你建立來繫結你對映的語句的介面。對映器介面的例項是從 SqlSession 中獲得的。因此從技術層面講,任何對映器例項的最大作用域是和請求它們的 SqlSession 相同的。儘管如此,對映器例項的最佳作用域是方法作用域。也就是說,對映器例項應該在呼叫它們的方法中被請求,用過之後即可廢棄。並不需要顯式地關閉對映器例項,儘管在整個請求作用域(request scope)保持對映器例項也不會有什麼問題,但是很快你會發現,像 SqlSession 一樣,在這個作用域上管理太多的資源的話會難於控制。所以要保持簡單,最好把對映器放在方法作用域(method scope)內。

  PersonMapper mapper = session.getMapper(PersonMapper.class);

二、xml配置

xm可以l配置的內容如下:

1、propeties:屬性配置

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

如上引入了屬性,下面的配置就可以直接引用config.properties中的值了

<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

2、settings

如設定快取、懶載入等

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
</settings>

3、environments(環境配置)

<environments default="development"><!--預設的環境 ID-->
  <environment id="development"><!--每個 environment 元素定義的環境 ID-->
    <transactionManager type="JDBC"><!--事務管理器的配置-->
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED"><!--資料來源的配置-->
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

事務管理器(transactionManager):
在 MyBatis 中有兩種型別的事務管理器(也就是 type=”[JDBC|MANAGED]”):
JDBC – 這個配置就是直接使用了 JDBC 的提交和回滾設定,它依賴於從資料來源得到的連線來管理事務作用域。
MANAGED – 這個配置幾乎沒做什麼。它從來不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 預設情況下它會關閉連線
注意:如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器, 因為 Spring 模組會使用自帶的管理器來覆蓋前面的配置

資料來源(dataSource):
有三種內建的資料來源型別(也就是 type=”[UNPOOLED|POOLED|JNDI]”):
UNPOOLED– 這個資料來源的實現只是每次被請求時開啟和關閉連線。
POOLED– 這種資料來源的實現利用“池”的概念將 JDBC 連線物件組織起來,避免了建立新的連線例項時所必需的初始化和認證時間。 這是一種使得併發 Web 應用快速響應請求的流行處理方式。
JNDI – 這個資料來源的實現是為了能在如 EJB 或應用伺服器這類容器中使用,容器可以集中或在外部配置資料來源,然後放置一個 JNDI 上下文的引用。
可以配置多資料來源,然後使用SqlSessionFactory build(不同的引數)來實現不同的資料來源環境;

4、對映器(mappers)

<!-- 使用相對於類路徑的資源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
</mappers>

三、Mapper XML 檔案

SQL 對映檔案有很少的幾個頂級元素(按照它們應該被定義的順序):
cache – 給定名稱空間的快取配置。
cache-ref – 其他名稱空間快取配置的引用。
resultMap – 是最複雜也是最強大的元素,用來描述如何從資料庫結果集中來載入物件。
sql – 可被其他語句引用的可重用語句塊。
insert – 對映插入語句
update – 對映更新語句
delete – 對映刪除語句
select – 對映查詢語句

四、動態sql

1、if

<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG 
  WHERE state = ‘ACTIVE’ 
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

2、choose (when, otherwise)

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

3、where, set

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG 
  <where> 
    <if test="state != null">
         state = #{state}
    </if> 
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

where 元素只會在至少有一個子元素的條件返回 SQL 子句的情況下才去插入“WHERE”子句。而且,若語句的開頭為“AND”或“OR”,where 元素也會將它們去除。

4、foreach

五、mybatis快取

1、一級快取
一級快取是指SqlSession。一級快取的作用域是一個SqlSession。Mybatis預設開啟一級快取。
2、二級快取
二級快取是指mapper對映檔案。二級快取的作用域是同一個namespace下的mapper對映檔案內容,多個SqlSession共享。Mybatis需要手動設定啟動二級快取。

<setting name="cacheEnabled" value="true" />

3、自定義快取

3-1、自定義快取類實現mybatis提供的Cache 介面
3-2、需要在mybatis的配置檔案裡手動設定快取可用

<setting name="cacheEnabled" value="true"/>

3-3、在對應的mapper裡設定我們想用的自定義快取類

<cache type="org.mybatis.caches.redis.RedisCache"/>