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還要修改程式碼,系統不易維護。
解決:
問題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檔案中的namespace與mapper介面的類路徑相同。
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對映檔名稱相同,且放在同一個目錄中