MyBatis是Apache的一個開源項目iBatis, iBatis一詞來源於「internet」和「abatis」的組合,是一個基於Java的持久層框架。 iBatis 提供的持久層框架包括SQL Maps和Data Access Objects(DAO)java
Mybatis 是一個 半自動的ORM(Object Relation Mapping)框架mysql
sql和java編碼分開,功能邊界清晰,一個專一業務、一個專一數據git
MyBatis全局配置文件結構順序是規定好的,能夠省略但不可顛倒位置github
1)properties屬性sql
既能夠在典型的 Java 屬性文件中配置,亦可經過 properties 元素的子元素來配置數據庫
還能夠建立一個資源文件,經過properties引入外部文件apache
resource: 從類路徑下引入屬性文件緩存
url: 引入網絡路徑或者是磁盤路徑下的屬性文件安全
<properties> <property name="driver" value="com.mysql.jdbc.Driver" /> </properties> <!-- 引入類路徑下文件 --> <properties resource="db.properties"></properties>
是 MyBatis 中極爲重要的調整設置,它們會改變 MyBatis 的運行時行爲
<settings> <!-- 映射下劃線到駝峯命名 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 設置Mybatis對null值的默認處理 --> <setting name="jdbcTypeForNull" value="NULL"/> <!-- 開啓延遲加載 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 設置加載的數據是按需仍是所有 --> <setting name="aggressiveLazyLoading" value="false"/> <!-- 配置開啓二級緩存 --> <setting name="cacheEnabled" value="true"/> </settings>
3)typeAliases 別名處理
類型別名是爲 Java 類型設置一個短的名字,能夠方便咱們在配置文件中其餘位置引用某個類。
不少的狀況下,能夠批量設置別名爲這個包下的每個類建立一個默認的別名,就是用簡單類名小寫的形式
<typeAliases> <package name="com.mybatis.bean"/> </typeAliases>
MyBatis已經取好的別名
4)typeHandlers 類型處理器
不管是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,仍是從結果集中取出一個值時, 都會用類型處理器將獲取的值以合適的方式轉換成 Java 類型
MyBatis3.4之前的版本須要咱們手動註冊這些處理器,之後的版本都是自動註冊的,因此基本不需設置
咱們也能夠重寫類型處理器或建立本身的類型處理器來處理不支持的或非標準的類型
5)objectFactory 對象工廠
6)plugins 插件機制
咱們能夠經過插件來修改MyBatis的一些核心行爲。插件經過動態代理機制,能夠介入四大對象的任何一個方法的執行
<plugins> <!-- 分頁插件 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
四大對象
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) ParameterHandler (getParameterObject, setParameters) ResultSetHandler (handleResultSets, handleOutputParameters) StatementHandler (prepare, parameterize, batch, update, query)
7)environments 環境配置
MyBatis能夠配置多種環境,根據須要每種環境使用一個environment標籤進行配置並指定惟一標識符
能夠經過environments標籤中的default屬性指定一個環境的標識符來快速的切換環境
id:指定當前環境的惟一標識 transactionManager、和 dataSource 都必須有
<environments default="mysql"> <environment id="mysql"> <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>
實際開發中咱們使用Spring管理數據源,並進行事務控制的配置來覆蓋上述配置
8)databaseIdProvider數據庫廠商標識
MyBatis 能夠根據不一樣的數據庫廠商執行不一樣的語句
<databaseIdProvider type="DB_VENDOR"> <property name="MySQL" value="mysql"/> </databaseIdProvider>
Type: DB_VENDOR, 使用MyBatis提供的VendorDatabaseIdProvider解析數據庫廠商標識。也能夠實現DatabaseIdProvider接口來自定義.
配置了databaseIdProvider後,在SQL映射文件中的增刪改查標籤中使用databaseId來指定數據庫標識的別名
<select id="getEmployeeById" resultType="com.mybatis.bean.Employee" databaseId="mysql"> select * from tbl_employee where id = #{id} </select>
MyBatis匹配規則以下
① 若是沒有配置databaseIdProvider標籤,那麼databaseId=null
② 若是配置了databaseIdProvider標籤,使用標籤配置的name去匹配數據庫信息,匹配上設置databaseId=配置指定的值,不然依舊爲null
③ 若是databaseId不爲null,他只會找到配置databaseId的sql語句
④ MyBatis 會加載不帶 databaseId 屬性和帶有匹配當前數據庫databaseId 屬性的全部語句。若是同時找到帶有 databaseId 和不帶databaseId 的相同語句,則後者會被捨棄。
9)mappers 映射器
用來在mybatis初始化的時候,告訴mybatis須要引入哪些Mapper映射文件
resource : 引入類路徑下的文件
url : 引入網絡路徑或者是磁盤路徑下的文件
class : 引入Mapper接口
一般狀況下使用批量註冊,這種方式要求SQL映射文件名必須和接口名相同而且在同一目錄下
<mappers> <package name="com.mybatis.dao"/> </mappers>
MyBatis 的真正強大在於它的映射語句,就是針對 SQL 語句構建的
<mapper namespace="main.mapper.BookMapper" > </mapper>
SQL 映射文件有不多的幾個頂級元素
cache – 給定命名空間的緩存配置。
cache-ref – 其餘命名空間緩存配置的引用。
resultMap – 是最複雜也是最強大的元素,用來描述如何從數據庫結果集中來加載對象。
parameterMap – 已廢棄!老式風格的參數映射。內聯參數是首選,這個元素可能在未來被移除,這裏不會記錄。
sql – 可被其餘語句引用的可重用語句塊。
insert – 映射插入語句
update – 映射更新語句
delete – 映射刪除語句
select – 映射查詢語
MyBatis 默認不是自動提交,需手動提交:sqlSession.commit();
insert
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> INSERT INTO users (id,username,PASSWORD) VALUES(NULL,#{username},#{password}) </insert>
delete
<delete id="deleteUser"> DELETE FROM users WHERE id = #{id} </delete>
update
<update id="updateUser"> UPDATE users SET name=#{name},email=#{email} WHERE id = #{id} </update>
select
<select id="getUserById" resultType="main.beans.User"> SELECT id,username,`password`,`name`,email FROM users WHERE id = #{id} </select>
數據庫分爲支持主鍵自增與不支持的,mysql是支持的
功能:插入一條新數據時,便可經過其主鍵id值立馬查詢這條數據,通常在 insert 中設置 useGeneratedKeys 爲 true,返回數據庫自動生成的主鍵 id,keyColumn 用於指定數據庫table中的主鍵,keyProperty 用於指定傳入對象的成員變量。
注意:settings 中設置爲全局,在接口映射器(註解)中設置的 useGeneratedKeys 參數值將會覆蓋在settings元素中設置全局 useGeneratedKeys 參數值,xml 映射器中配置的 useGeneratedKeys參數只會對 xml 映射器產生影響
@Options(useGeneratedKeys=true,keyProperty="userId",keyColumn="userId")
1) 單個普通類型參數
能夠接受基本類型,包裝類型,字符串類型等。這種狀況MyBatis可直接使用這個參數,#{abc},大括號內可隨便定義
2) 多個參數
任意多個參數,都會被MyBatis從新包裝成一個Map傳入。Map的key是param1,param2,或者0,1…, #{param1,param2}
值就是參數的值 #{key1,key2}:獲取參數的值,預編譯到SQL中。安全。
3) 命名參數
爲參數使用@Param起一個名字,MyBatis就會將這些參數封裝進map中,key就是咱們本身指定的名字
public Employee getEmployeeById(@Param("id")Integer id);
4) POJO
resultType自動映射,當這些參數屬於咱們業務POJO時,咱們直接傳遞POJO
autoMappingBehavior默認是PARTIAL,開啓自動映射的功能。惟一的要求是結果集列名和javaBean屬性名一致
5) Map
咱們也能夠封裝多個參數爲map,直接傳遞 #{key} 直接傳入map中的key值
1) 查詢單行數據返回Map集合
public Map<String,Object> getEmployeeByIdReturnMap(Integer id );
2) 查詢多行數據返回Map集合
@MapKey("id") // 指定使用對象的哪一個屬性來充當map的key public Map<Integer,Employee> getAllEmpsReturnMap();
6) Collection/Array
會被MyBatis封裝成一個 map 傳入, Collection 對應的 key 是 collection , Array 對應的 key 是 array . 若是肯定是 List 集合,key 還能夠是 list.
自定義 resultMap,能夠實現高級結果集的映射
1) id :用於完成主鍵值的映射
2) result :用於完成普通列的映射
id、result屬性
<resultMap id="getBookById" type="main.beans.User"> <id column="id" property="id"></id> <result column="username" property="username"></result> <result column="password" property="password"></result> </resultMap>
3) association :一個複雜的類型關聯,當一個對象的某個屬性是一個對象時,通常將結果包裝成此類型
咱們可使用聯合查詢,並以級聯屬性的方式封裝對象.使用 association 標籤訂義對象的封裝規則
<select id="getEmployeeAndDept" resultMap="myEmpAndDept" > SELECT e.id eid, e.last_name, e.email,e.gender ,d.id did, d.dept_name FROM tbl_employee e , tbl_dept d WHERE e.d_id = d.id AND e.id = #{id} </select> <resultMap type="com.mybatis.beans.Employee" id="myEmpAndDept"> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <!-- 級聯的方式 --> <result column="did" property="dept.id"/> <result column="dept_name" property="dept.departmentName"/> </resultMap>
對於每一個實體類都應該有具體的增刪改查方法,也就是DAO層,所以咱們也可使用 association 分步查詢
在分步查詢的基礎上,可使用延遲加載來提高查詢的效率,只須要在全局的 Settings 中配置
<select id="getEmployeeAndDeptStep" resultMap="myEmpAndDeptStep"> select id, last_name, email,gender,d_id from tbl_employee where id =#{id} </select> <resultMap type="com.mybatis.beans.Employee" id="myEmpAndDeptStep"> <id column="id" property="id" /> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <association property="dept" select="com.mybatis.dao.DepartmentMapper.getDeptById" //mapper包中定義的查詢方法全類名 column="d_id" fetchType="eager"> </association> </resultMap>
4) collection :複雜類型的集,當一個對象的某個屬性是一個集合對象時
咱們可使用聯合查詢,並以級聯屬性的方式封裝對象.使用 collection 標籤訂義對象的封裝規則
property: 關聯的屬性名
ofType: 集合中元素的類型
實際的開發中常常能夠經過分步的方式完成查詢.
<select id="getDeptAndEmpsByIdStep" resultMap="myDeptAndEmpsStep"> select id ,dept_name from tbl_dept where id = #{id} </select> <resultMap type="com.mybatis.beans.Department" id="myDeptAndEmpsStep"> <id column="id" property="id"/> <result column="dept_name" property="departmentName"/> <collection property="emps" select="com.mybatis.dao.EmployeeMapper.getEmpsByDid" //mapper包中定義的查詢方法全類名 column="id"> </collection> </resultMap>
分步查詢多列值的傳遞
若是分步查詢時,須要傳遞給調用的查詢中多個參數,則須要將多個參數封裝成 Map來進行傳遞,語法以下: {k1=v1, k2=v2....}
在所調用的查詢方法取值時,就要參考Map的取值方式,須要嚴格的按照封裝map 時所用的key來取值.
fetchType屬性
在<association> 和 <collection> 標籤中均可以設置 fetchType,指定本次查詢是否要使用延遲加載。默認爲 fetchType=」lazy」 ,若是本次的查詢不想使用延遲加載,則可設置爲 fetchType=」eager」.