1. 程式人生 > >Mybatis入門和配置(1)

Mybatis入門和配置(1)

Mybatis介紹

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

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

Mybatis解決jdbc程式設計的問題

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

問題2: Sql語句在程式碼中硬編碼,造成程式碼不易維護,實際應用中sql變化的可能較大,sql變動需要改變java程式碼。
解決: 將Sql語句配置在XXXmapper.xml檔案中與java程式碼分離。

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

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

問題4: 對結果集解析存在硬編碼(查詢列名),sql變化導致解析程式碼變化,系統不易維護,如果能將資料庫記錄封裝成pojo物件解析比較方便。
解決: Mybatis自動將sql執行結果對映至java物件,通過statement中的resultType定義輸出結果的型別。

核心配置檔案:SqlMapConfig.xml

標頭檔案:

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"		
"http://mybatis.org/dtd/mybatis-3-config.dtd">

Sql對映檔案:Mapper.xml

標頭檔案:

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

對映配置:

<!-- namespace:名稱空間,用於隔離sql -->
<mapper namespace="user">
	<!-- id:statement的id 或者叫做sql的id-->
	<!-- parameterType:宣告輸入引數的型別 -->
	<!-- resultType:宣告輸出結果的型別,應該填寫pojo的全路徑 -->
	!-- #{}:輸入引數的佔位符,相當於jdbc的? -->
	<select id="queryUserById" parameterType="int"
		resultType="cn.itcast.mybatis.pojo.User">
		SELECT * FROM `user` WHERE id  = #{id}
	</select>
	<!-- 如果傳入的引數是簡單資料型別,${}裡面必須寫value -->
	<select id="queryUserByUsername2" parameterType="string"
		resultType="cn.itcast.mybatis.pojo.User">
		SELECT * FROM `user` WHERE username LIKE '%${value}%'
	</select>
</mapper>

小結

${}和#{}的使用

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

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

parameterType和resultType

parameterType: 指定輸入引數型別,mybatis通過ognl從輸入物件中獲取引數值拼接在sql中。
resultType: 指定輸出結果型別,mybatis將sql查詢結果的一行記錄資料對映為resultType指定型別的物件。如果有多條資料,則分別進行對映,並把物件放到容器List中

selectOne和selectList

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

org.apache.ibatis.exceptions.TooManyResultsException

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

Mysql自增主鍵返回

在新增記錄的時候在sql語句之前配置主鍵自增:

<!-- order:設定在執行insert語句前執行查詢id的sql,還指在執行insert語句之後執行查詢id的sql -->
<!-- resultType:設定返回的id的型別 -->

<selectKey keyColumn="id" keyProperty="id" order="AFTER"
	resultType="int">
	SELECT LAST_INSERT_ID()
</selectKey>

uuid實現主鍵

<selectKey keyColumn="id" keyProperty="id" order="BEFORE" resultType="string">
	SELECT LAST_INSERT_ID()
</selectKey>

SqlSession的使用範圍

瞭解SqlSession的使用範圍,首先要明白他是怎麼建立的:

SqlSession中封裝了對資料庫的操作,如:查詢、插入、更新、刪除等。
SqlSession通過SqlSessionFactory建立。
SqlSessionFactory是通過SqlSessionFactoryBuilder進行建立。

1.SqlSessionFactoryBuilder

SqlSessionFactoryBuilder用於建立SqlSessionFacoty,
SqlSessionFacoty一旦建立完成就不需要SqlSessionFactoryBuilder了,
因為SqlSession是通過SqlSessionFactory建立的。
所以可以將SqlSessionFactoryBuilder當成一個工具類使用,
最佳使用範圍是方法範圍即方法體內區域性變數。

2.SqlSessionFactory

SqlSessionFactory是一個介面,介面中定義了openSession的不同過載方法,
SqlSessionFactory的最佳使用範圍是整個應用執行期間,一旦建立後可以重複使用,
通常以單例模式管理SqlSessionFactory。

3.SqlSession

SqlSession是一個面向使用者的介面,sqlSession中定義了資料庫操作方法。
每個執行緒都應該有它自己的SqlSession例項。
SqlSession的例項不能共享使用,它也是執行緒不安全的。
因此最佳的範圍是請求或方法範圍。
絕對不能將SqlSession例項的引用放在一個類的靜態欄位或例項欄位中。
開啟一個 SqlSession;使用完畢就要關閉它。

Mapper動態代理方式

Mapper介面開發方法只需要程式設計師編寫Mapper介面(相當於Dao介面),由Mybatis框架根據介面定義建立介面的動態代理物件,代理物件的方法體同上邊Dao介面實現類方法。

Mapper介面開發需要遵循以下規範:

Mapper.xml檔案中的namespacemapper介面的類路徑相同。

Mapper介面方法名和Mapper.xml中定義的每個statement的id相同

Mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql 的parameterType的型別相同

Mapper介面方法的輸出引數型別和mapper.xml中定義的每個sql的resultType的型別相同

Mapper.xml(對映檔案)的配置

<mapper namespace="Mapper介面類路徑">
	<select id="Mapper介面方法名" parameterType="介面方法引數型別" resultType="介面方法返回值型別">
		select * from user where id = #{id}
	</select>
</mapper>

注意: 要在Mabits核心配置檔案中配置載入對映檔案(Mapper.xml)

SqlMapConfig.xml配置檔案的其他配置

properties(屬性)
<!-- 使用resource屬性載入外部配置檔案 -->
<properties resource="db.properties">
	<!-- 在properties內部用property定義屬性 -->
	<!-- 如果外部配置檔案有該屬性,則內部定義屬性被外部屬性覆蓋 -->
	<property name="jdbc.username" value="root123" />
	<property name="jdbc.password" value="root123" />
</properties>
typeAliases(類型別名)

在Mybatis中有一些預設的別名,例如返回值型別的配置的時候,直接寫型別名即可,不需要寫型別的全限定名,這就是因為在Mybatis中已經配置好了一些預設的類型別名,直接使用即可,除此之外,還可以自定義類型別名:

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

需要注意的是,別名的大小寫不敏感

mappers(對映器)

Mapper配置的幾種方法:

方式一:
<mapper resource=" " />
<!--使用相對於類路徑的資源-->
方式二:
<mapper class=" " />
<!--使用mapper介面類路徑-->
方式三:
<package name=""/>
<!--註冊指定包下的所有mapper介面-->

注意: 使用方法二三時,要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中