1. 程式人生 > >SSM學習(1)---Mybatis

SSM學習(1)---Mybatis

Mybatis介紹

Mybatis本是Apache的一個開源專案iBatis,2010年這個專案由Apache software foundation 遷移到了 Google code,並且改名MyBatis。2013年11月遷移到Github。

MyBatis是一個優秀的持久的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使開發者只需關注SQL本身,而不需要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設定制引數、結果集檢索等jdbc繁雜的過程程式碼。

MyBatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatement、CallableStatement)配置起來,並通過java物件和statement中的sql進行對映生成最終執行的sql語句,最後MyBatis框架執行sql並將結果對映成java物件並返回。

jdbc問題總結

  1. 資料庫連線建立、釋放頻繁造成系統資源浪費,從而影響系統性能。如果使用資料庫連線池可解決此問題。

  2. Sql語句在程式碼中硬編碼,造成程式碼不易維護,實際應用中sql變化的可能較大,sql變動需要改變java程式碼。

  3. 使用preparedStatement向佔有位符號傳引數存在硬編碼,因為sql語句的where條件不一定,可能多也可能少,修改sql還要修改程式碼,系統不易維護。

  4. 對結果集解析存在硬編碼(查詢列名),sql變化導致解析程式碼變化,系統不易維護,如果能將資料庫記錄封裝成pojo物件解析比較方便。

Mybatis架構

Mybatis配置

 SqlMapConfig.xml,此檔案作為mybatis的全域性配置檔案,配置了mybatis的執行環境等資訊。

 mapper.xml檔案即sql對映檔案,檔案中配置了操作資料庫的sql語句。此檔案需要在SqlMapConfig.xml中載入。

通過mybatis環境等配置資訊構造SqlSessionFactory即會話工廠

由會話工廠建立sqlSession即會話,操作資料庫需要通過sqlSession進行。

mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器。

Mapped Statement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql對映資訊等。mapper.xml檔案中一個sql對應一個Mapped Statement物件,sql的id即是Mapped statement的id。

Mapped Statement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql前將輸入的java物件對映至sql中,輸入引數對映就是jdbc程式設計中對preparedStatement設定引數。

Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql後將輸出結果對映至java物件中,輸出結果對映過程相當於jdbc程式設計中對結果的解析處理過程。

 

小結

1.#{}和${}

#{}表示一個佔位符號,通過#{}可以實現preparedStatement向佔位符中設定值,自動進行java型別和jdbc型別轉換。#{}可以有效防止sql注入。 #{}可以接收簡單型別值或pojo屬性值。 如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。

${}表示拼接sql串,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。

 

2.parameterType和resultType

parameterType:指定輸入引數型別,mybatis通過ognl從輸入物件中獲取引數值拼接在sql中。

resultType:指定輸出結果型別,mybatis將sql查詢結果的一行記錄資料對映為resultType指定型別的物件。如果有多條資料,則分別進行對映,並把物件放到容器List中。

 

3.selectOne和selectList

selectOne查詢一條記錄,如果使用selectOne查詢多條記錄則丟擲異常:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3

at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)

selectList可以查詢一條或多條記錄。

Mybatis解決jdbc程式設計的問題

  1. 資料庫連線建立、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用資料庫連線池可解決此問題。

解決:在SqlMapConfig.xml中配置資料連線池,使用連線池管理資料庫連結。

  1. Sql語句寫在程式碼中造成程式碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java程式碼。

解決:將Sql語句配置在XXXXmapper.xml檔案中與java程式碼分離。

  1. 向sql語句傳引數麻煩,因為sql語句的where條件不一定,可能多也可能少,佔位符需要和引數一一對應。

解決:Mybatis自動將java物件對映至sql語句,通過statement中的parameterType定義輸入引數的型別。

  1. 對結果集解析麻煩,sql變化導致解析程式碼變化,且解析前需要遍歷,如果能將資料庫記錄封裝成pojo物件解析比較方便。

解決:Mybatis自動將sql執行結果對映至java物件,通過statement中的resultType定義輸出結果的型別。

 

mybatis與hibernate不同

Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程式設計師自己編寫Sql語句。mybatis可以通過XML或註解方式靈活配置要執行的sql語句,並將java物件和sql語句對映生成最終執行的sql,最後將sql執行的結果再對映生成java物件。

 

Mybatis學習門檻低,簡單易學,程式設計師直接編寫原生態sql,可嚴格控制sql執行效能,靈活度高,非常適合對關係資料模型要求不高的軟體開發,例如網際網路軟體、企業運營類軟體等,因為這類軟體需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到資料庫無關性,如果需要實現支援多種資料庫的軟體則需要自定義多套sql對映檔案,工作量大。

 

Hibernate物件/關係對映能力強,資料庫無關性好,對於關係模型要求高的軟體(例如需求固定的定製化軟體)如果用hibernate開發可以節省很多程式碼,提高效率。但是Hibernate的學習門檻高,要精通門檻更高,而且怎麼設計O/R對映,在效能和物件模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力才行。

總之,按照使用者的需求在有限的資源環境下只要能做出維護性、擴充套件性良好的軟體架構都是好架構,所以框架只有適合才是最好。 

 

SqlMapConfig.xml配置檔案

配置內容

SqlMapConfig.xml中配置的內容和順序如下:

  • properties(屬性)
  • settings(全域性配置引數)
  • typeAliases(類型別名)
  • typeHandlers(型別處理器)
  • objectFactory(物件工廠)
  • plugins(外掛)
  • environments(環境集合屬性物件)
  •      environment(環境子屬性物件)
  •          transactionManager(事務管理)
  •          dataSource(資料來源)
  • mappers(對映器)

1.properties(屬性)

SqlMapConfig.xml可以引用java屬性檔案中的配置資訊如下:

在config下定義db.properties檔案

db.properties配置檔案內容如下:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

SqlMapConfig.xml引用如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 是用resource屬性載入外部配置檔案 -->
	<properties resource="db.properties">
		<!-- 在properties內部用property定義屬性 -->
		<!-- 如果外部配置檔案有該屬性,則內部定義屬性被外部屬性覆蓋 -->
		<property name="jdbc.username" value="root123" />
		<property name="jdbc.password" value="root123" />
	</properties>

	<!-- 和spring整合後 environments配置將廢除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事務管理 -->
			<transactionManager type="JDBC" />
			<!-- 資料庫連線池 -->
			<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>
	</environments>

	<!-- 載入對映檔案 -->
	<mappers>
		<mapper resource="sqlmap/User.xml" />
		<mapper resource="mapper/UserMapper.xml" />
	</mappers>
</configuration>

 

注意: MyBatis 將按照下面的順序來載入屬性:

  1. 在 properties 元素體內定義的屬性首先被讀取。
  2. 然後會讀取properties 元素中resource或 url 載入的屬性,它會覆蓋已讀取的同名屬性。

 

 

2.typeAliases(類型別名)

mybatis支援別名:

別名

對映的型別

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

map

Map

自定義別名:

在SqlMapConfig.xml中配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 是用resource屬性載入外部配置檔案 -->
	<properties resource="db.properties">
		<!-- 在properties內部用property定義屬性 -->
		<property name="jdbc.username" value="root123" />
		<property name="jdbc.password" value="root123" />
	</properties>

	<typeAliases>
		<!-- 單個別名定義 -->
		<typeAlias alias="user" type="cn.itcast.mybatis.pojo.User" />
		<!-- 批量別名定義,掃描整個包下的類,別名為類名(大小寫不敏感) -->
		<package name="cn.itcast.mybatis.pojo" />
		<package name="其它包" />
	</typeAliases>

	<!-- 和spring整合後 environments配置將廢除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事務管理 -->
			<transactionManager type="JDBC" />
			<!-- 資料庫連線池 -->
			<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>
	</environments>

	<!-- 載入對映檔案 -->
	<mappers>
		<mapper resource="sqlmap/User.xml" />
		<mapper resource="mapper/UserMapper.xml" />
	</mappers>
</configuration>

在mapper。xml配置檔案中,就可以使用別名了

別名不考慮大小寫

 

3.mappers(對映器)

Mapper配置的幾種方法:

a. <mapper resource=" " />

使用相對於類路徑的資源(現在的使用方式)

如:<mapper resource="sqlmap/User.xml" />

b .​​​<mapper class=" " />

使用mapper介面類路徑

如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中

c . <package name=""/>

註冊指定包下的所有mapper介面

如:<package name="cn.itcast.mybatis.mapper"/>

注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中