1. 程式人生 > >mybatis系列之入門和XML配置

mybatis系列之入門和XML配置

一、為什麼使用mybatis

1.1 JDBC處理過程

這裡寫圖片描述

  • JDBC功能簡單,一般需要上門五個過程即可;
  • sql語句編寫在java程式碼裡面;硬編碼高耦合的方式;
  • 維護不易且實際開發需求中sql是有變化,頻繁修改的情況多見 ;
  • JDBC這種方式一般不推薦。其他框架一般都是在JDBC處理過程進行封裝,簡化處理過程,並提供整套解決方案。

1.2 Hibernate

  • 全自動全對映ORM(Object Relation Mapping)框架;
  • 旨再消除sql。針對較複雜的業務場景,使用HQL這裡寫圖片描述
  • 將JDBC的整個過程進行封裝,黑箱操作。
  • 只關注javaBean與DbRecords之間的對映。中間的過程交個了Hibernate去處理。
  • 但是企業應用中常常複雜,且後期需要優化,所以將sql抽取出來,能夠靈活控制就變的十分需求。

另外,基於全對映的全自動框架,大量欄位的POJO進行部分對映時比較困難。 導致資料庫效能下。

1.3 半自動,輕量級的框架 Mybatis

這裡寫圖片描述

其中編寫sql對開發人員都是自由的,可以針對任何複雜的情況。更加靈活。

二、Mybatis的下載和文件

三、案例

四、類說明

4.1 SqlSession

跟JDBC中的Connection是一樣,非執行緒安全的。每次會話都應該拿取新的物件,不能共享(例如,不能將其當做成員變數,多個物件共享;或者使用static去修飾它也一樣不行);需要注意其作用域。

mapper介面沒有實現類,但是mybatis會為這個介面生成一個代理物件(將介面和xml進行繫結)

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

4.2 配置檔案

mybatis全域性配置檔案:包含資料庫連線池資訊,事務管理器資訊等系統執行環境資訊

sql對映檔案:儲存了每一個sql語句的對映資訊:將sql抽取出來。

4.3 配置檔案詳解

configuration 配置
    properties 屬性
    settings 設定
    typeAliases 類型別名
    typeHandlers 型別處理器
    objectFactory 物件工廠
    plugins 外掛
    environments 環境
        environment 環境變數
            transactionManager 事務管理器
            dataSource 資料來源
    databaseIdProvider 資料庫廠商標識
    mappers 對映器

4.3.1 properties

mybatis可以使用properties來引入外部properties配置檔案的內容; resource:引入類路徑下的資源 url:引入網路路徑或者磁碟路徑下的資源

整合spring,則交個spring管理。

####4.3.2 settings 這是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的執行時行為。

設定引數 描述 有效值 預設值
cacheEnabled 全域性地開啟或關閉配置檔案中的所有對映器已經配置的任何快取 true or false true
lazyLoadingEnabled 延遲載入的全域性開關。當開啟時,所有關聯物件都會延遲載入。 特定關聯關係中可通過設定fetchType屬性來覆蓋該項的開關狀態。 true or false false
mapUnderscoreToCamelCase 是否開啟自動駝峰命名規則(camel case)對映,即從經典資料庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似對映。 true or false False
……

4.3.3 typeAliases

類型別名是為 Java 型別設定一個短的名字。它只和 XML 配置有關,存在的意義僅在於用來減少類完全限定名的冗餘

例如:

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>

當這樣配置時,Blog可以用在任何使用domain.blog.Blog的地方

也可以指定一個包名,MyBatis 會在包名下面搜尋需要的 Java Bean,比如

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

每一個在包domain.blog 中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作為它的別名。 比如 domain.blog.Author的別名為 author;若有註解,則別名為其註解值.

@Alias("author")
public class Author {
    ...
}

4.3.4 typeHandlers型別處理器

無論是 MyBatis 在預處理語句(PreparedStatement)中 設定一個引數時,還是從結果集中取出一個值時, 都會 用型別處理器將獲取的值以合適的方式轉換成 Java 型別

你可以重寫型別處理器或建立你自己的型別處理器來處理不支援的或非標準的型別。 具體做法為:實現 org.apache.ibatis.type.TypeHandler 介面, 或繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler, 然後可以選擇性地將它對映到一個 JDBC 型別.

4.3.5 外掛 plugins

MyBatis 允許你在已對映語句執行過程中的某一點進行攔截呼叫。預設情況下,MyBatis 允許使用外掛來攔截的方法呼叫包括:

Executor (update, query, flushStatements, commit, 
          rollback,getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)

通過 MyBatis 提供的強大機制,使用外掛是非常簡單的,只需實現 Interceptor 介面,並指定想要攔截的方法簽名即可

@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  public Object intercept(Invocation invocation) throws Throwable {
    return invocation.proceed();
  }
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }
  public void setProperties(Properties properties) {
  }
}

<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>

上面的外掛將會攔截在 Executor 例項中所有的 update方法呼叫, 這裡的 Executor 是負責執行低層對映語句的內部物件。

4.3.6 environments

MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 對映應用於多種資料庫之中, 現實情況下有多種理由需要這麼做。例如,開發、測試和生產環境需要有不同的配置;或者共享相同 Schema 的多個生產資料庫, 想使用相同的 SQL 對映。許多類似的用例。

不過要記住:儘管可以配置多個環境,每個 SqlSessionFactory 例項只能選擇其一 所以,如果你想連線兩個資料庫,就需要建立兩個 SqlSessionFactory例項,每個資料庫對應一個。而如果是三個資料庫,就需要三個例項。

為了指定建立哪種環境,只要將它作為可選的引數傳遞給 SqlSessionFactoryBuilder即可。可以接受環境配置的兩個方法簽名是:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);

如果忽略了環境引數,那麼預設環境將會被載入,如下所示:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
<environments default="development">
  <environment id="development">
    <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>

注意這裡的關鍵點:

  • 預設的環境 ID(比如:default=development)。
  • 每個 environment 元素定義的環境 ID(比如:id=development)。
  • 事務管理器的配置(比如:type=JDBC)。
  • 資料來源的配置(比如:type=POOLED)。

在 MyBatis 中有兩種型別的事務管理器(也就是 type=[JDBC|MANAGED]) 如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器, 因為 Spring 模組會使用自帶的管理器來覆蓋前面的配置。

4.3.6 databaseIdProvider

MyBatis 可以根據不同的資料庫廠商執行不同的語句,這種多廠商的支援是基於對映語句中的 databaseId 屬性。 MyBatis 會載入不帶 databaseId 屬性和帶有匹配當前資料庫 databaseId 屬性的所有語句。 如果同時找到帶有 databaseId 和不帶 databaseId 的相同語句,則後者會被捨棄。 為支援多廠商特性只要像下面這樣在mybatis-config.xml 檔案中加入 databaseIdProvider 即可:

這裡的 DB_VENDOR 會通過 DatabaseMetaData#getDatabaseProductName()返回的字串進行設定

<environments default="dev_mysql">
	<!-- 設定default的值,來表示選擇廠商 -->
		<environment id="dev_mysql">
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	
		<environment id="dev_oracle">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${orcl.driver}" />
				<property name="url" value="${orcl.url}" />
				<property name="username" value="${orcl.username}" />
				<property name="password" value="${orcl.password}" />
			</dataSource>
		</environment>
	</environments>
<databaseIdProvider type="DB_VENDOR">
  <property name="SQL Server" value="sqlserver"/>
  <property name="DB2" value="db2"/>        
  <property name="Oracle" value="oracle" />
</databaseIdProvider>

使用案例:

<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee">
		select * from tbl_employee where id = #{id}
	</select>
	<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee"
		databaseId="mysql">
		select * from tbl_employee where id = #{id}
	</select>
	<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee"
		databaseId="oracle">
		select EMPLOYEE_ID id,LAST_NAME	lastName,EMAIL email 
		from employees where EMPLOYEE_ID=#{id}
	</select>

4.3.7 mappers

既然 MyBatis 的行為已經由上述元素配置完了,我們現在就要定義 SQL 對映語句了。但是首先我們需要告訴 MyBatis 到哪裡去找到這些語句。

<!-- 使用相對於類路徑的資源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
</mappers>
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<!-- 使用對映器介面實現類的完全限定類名 -->
<!--有sql對映檔案,對映檔名必須和介面同名,並且放在與介面同一目錄下-->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
<!-- 將包內的對映器介面實現全部註冊為對映器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

:每種標籤的是有順序的。