Mybatis【配置文件】就是這麼簡單

配置文件和映射文件還有挺多的屬性我尚未講的,如今就把它們一一補全前端

映射文件

在mapper.xml文件中配置不少的sql語句,執行每一個sql語句時,封裝爲MappedStatement對象,mapper.xml以statement爲單位管理sql語句java

Statement的實際位置就等於namespace+StatementIdmysql

佔位符

在Mybatis中,有兩種佔位符sql

  • #{}解析傳遞進來的參數數據
  • ${}對傳遞進來的參數原樣拼接在SQL中

主鍵生成策略

若是咱們在Hibernate中,當咱們插入數據的時候,咱們是能夠選擇是UUID策略的...數據庫

那麼在Mybatis是怎麼作的呢??微信

UUID

<!-- mysql的uuid生成主鍵 -->
	<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
		<selectKey keyProperty="id" order="BEFORE" resultType="string">
			select uuid()
		</selectKey>
		
		INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
	</insert> 
複製代碼

主鍵返回

若是咱們通常插入數據的話,若是咱們想要知道剛剛插入的數據的主鍵是多少,咱們能夠經過如下的方式來獲取mybatis

需求:oracle

  • user對象插入到數據庫後,新記錄的主鍵要經過user對象返回,經過user獲取主鍵值。

解決思路:app

  • 經過LAST_INSERT_ID()獲取剛插入記錄的自增主鍵值,在insert語句執行後,執行select LAST_INSERT_ID()就能夠獲取自增主鍵。

mysql:性能

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
		<selectKey keyProperty="id" order="AFTER" resultType="int">
			select LAST_INSERT_ID()
		</selectKey>
		INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
	</insert>
複製代碼

oracle:

實現思路:

  • 先查詢序列獲得主鍵,將主鍵設置到user對象中,將user對象插入數據庫。
<!-- oracle 在執行insert以前執行select 序列.nextval() from dual取出序列最大值,將值設置到user對象 的id屬性 -->
	<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
		<selectKey keyProperty="id" order="BEFORE" resultType="int">
			select 序列.nextval() from dual
		</selectKey>
		
		INSERT INTO USER(id,username,birthday,sex,address) VALUES( 序列.nextval(),#{username},#{birthday},#{sex},#{address})
	</insert> 
複製代碼

resultMap

有的時候,咱們看別的映射文件,可能看不到如下這麼一段代碼:

<resultMap id="userListResultMap" type="user" >
 		<!-- 列名 id_,username_,birthday_ id:要映射結果集的惟 一標識 ,稱爲主鍵 column:結果集的列名 property:type指定的哪一個屬性中 -->
 		 <id column="id_" property="id"/>
 		 <!-- result就是普通列的映射配置 -->
 		 <result column="username_" property="username"/>
 		 <result column="birthday_" property="birthday"/>
 	
 	</resultMap>
複製代碼

由於,若是咱們的數據表的字段和JavaBean的屬性名稱是相同時,咱們就不用上面那段代碼了。Mybatis會自動幫咱們把返回的結果進行封裝成JavaBean

那當咱們數據表的字段和JavaBean的屬性名稱不是相同時,咱們就須要使用resultMap,也就是上面那段代碼

  • 固然了,在正常狀況下列名和JavaBean的屬性名通常都是不一樣的,所以仍是須要resultMap的。

resultMap和resultType區別

resultType :指定輸出結果的類型(pojo、簡單類型、hashmap..),將sql查詢結果映射爲java對象 。

  • 使用resultType注意:sql查詢的列名要和resultType指定pojo的屬性名相同,指定相同 屬性方可映射成功,若是sql查詢的列名要和resultType指定pojo的屬性名所有不相同,list中沒法建立pojo對象的。

resultMap:將sql查詢結果映射爲java對象。

  • 若是sql查詢列名和最終要映射的pojo的屬性名不一致**,使用resultMap將列名和pojo的屬性名作一個對應關係 (列名和屬性名映射配置)**

使用resultMap

<resultMap id="userListResultMap" type="user" >
 		<!-- 列名 id_,username_,birthday_ id:要映射結果集的惟 一標識 ,稱爲主鍵 column:結果集的列名 property:type指定的哪一個屬性中 -->
 		 <id column="id_" property="id"/>
 		 <!-- result就是普通列的映射配置 -->
 		 <result column="username_" property="username"/>
 		 <result column="birthday_" property="birthday"/>
 	
 	</resultMap>
複製代碼

這裏寫圖片描述

這裏寫圖片描述


resultType和resultMap用法總結

resultType:

  • 做用:

    • 將查詢結果按照sql列名pojo屬性名一致性映射到pojo中。
  • 場合:

    • 常見一些明細記錄的展現,將關聯查詢信息所有展現在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)便可。

resultMap:

  • 使用association和collection完成一對一和一對多高級映射。

association:

  • 做用:
    • 將關聯查詢信息映射到一個pojo類中。
  • 場合:
    • 爲了方便獲取關聯信息可使用association將關聯訂單映射爲pojo,好比:查詢訂單及關聯用戶信息。

collection:

  • 做用:
    • 將關聯查詢信息映射到一個list集合中。
  • 場合:
    • 爲了方便獲取關聯信息可使用collection將關聯信息映射到list集合中,好比:查詢用戶權限範圍模塊和功能,可以使用collection將模塊和功能列表映射到list中。

Collection在前面好像並無用過,下面就看一下它的用法:

Order與OrderDetails關係

package cn.itcast.mybatis.po;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class Orders implements Serializable {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //關聯用戶信息
    private User user;
    
    //訂單明細
    private List<Orderdetail> orderdetails;
   

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public List<Orderdetail> getOrderdetails() {
		return orderdetails;
	}

	public void setOrderdetails(List<Orderdetail> orderdetails) {
		this.orderdetails = orderdetails;
	} 
    
}

複製代碼

SQL語句

<!-- 一對多查詢使用reusltMap完成 查詢訂單關聯查詢訂單明細 -->
	 <select id="findOrderAndOrderDetails" resultMap="orderAndOrderDetails" >
			SELECT 
	  orders.*,
	  user.username,
	  user.sex ,
	  orderdetail.id orderdetail_id,
	  orderdetail.items_num,
	  orderdetail.items_id
	FROM
	  orders,
	  USER,
	  orderdetail
	WHERE orders.user_id = user.id  AND orders.id = orderdetail.orders_id
	 </select>
複製代碼

resultMap

<!-- 一對多,查詢訂單及訂單明細 -->
	<resultMap type="orders" id="orderAndOrderDetails" extends="ordersUserResultMap">
		<!-- 映射訂單信息,和用戶信息,這裏使用繼承ordersUserResultMap -->
		
		<!-- 映射訂單明細信息 property:要將關聯信息映射到orders的哪一個屬性中 ofType:集合中pojo的類型 -->
		<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
			<!-- id:關聯信息訂單明細的惟 一標識 property:Orderdetail的屬性名 -->
			<id column="orderdetail_id" property="id"/>
			<result column="items_num" property="itemsNum"/>
			<result column="items_id" property="itemsId"/>
		</collection>
	
	</resultMap>
複製代碼

通常地使用resultMap會多一點。


Mybatis映射文件處理特殊字符

第一種方法:

  • 用了轉義字符把>和<替換掉,而後就沒有問題了。
  • SELECT * FROM test WHERE 1 = 1 AND start_date <= CURRENT_DATE AND end_date >= CURRENT_DATE

第二種方法:

  • <![CDATA[ ]]>

配置文件

別名

typeAliases別名:

這裏寫圖片描述

自定義別名:

<!-- 定義 別名 -->
	<typeAliases>
		<!-- 單個別名的定義 alias:別名,type:別名映射的類型 -->
		<!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
		<!-- 批量別名定義 指定包路徑,自動掃描包下邊的pojo,定義別名,別名默認爲類名(首字母小寫或大寫) -->
		<package name="cn.itcast.mybatis.po"/>
		
	</typeAliases>
複製代碼

Mapper加載

<mappers>
		<!-- 經過resource引用mapper的映射文件 -->
		<mapper resource="sqlmap/User.xml" />
		<!-- <mapper resource="mapper/UserMapper.xml" /> -->
		<!-- 經過class引用mapper接口 class:配置mapper接口全限定名 要求:須要mapper.xml和mapper.java同名而且在一個目錄 中 -->
		<!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->
		<!-- 批量mapper配置 經過package進行自動掃描包下邊的mapper接口, 要求:須要mapper.xml和mapper.java同名而且在一個目錄 中 -->
		<package name="cn.itcast.mybatis.mapper"/>
	</mappers>
複製代碼

延遲加載

在進行數據查詢時,爲了提升數據庫查詢性能,儘可能使用單表查詢,由於單表查詢比多表關聯查詢速度要快。

若是查詢單表就能夠知足需求,一開始先查詢單表,當須要關聯信息時,再關聯查詢,當須要關聯信息再查詢這個叫延遲加載

在Mybatis中延遲加載就是在resultMap中配置具體的延遲加載..

這裏寫圖片描述

在Mybatis的文件中配置全局延遲加載

<!-- 全局配置參數 -->
	<settings>
		<!-- 延遲加載總開關 -->
		<setting name="lazyLoadingEnabled" value="true" />	
		<!-- 設置按需加載 -->
		<setting name="aggressiveLazyLoading" value="false" />
	</settings>
複製代碼

延遲加載測試

當須要用戶時調用 Orders類中的getUser()方法執行延遲加載 ,向數據庫發出sql。

因爲是對User進行延遲加載,那麼咱們只要查詢Orders相關的信息便可了

<!-- 一對一查詢延遲加載 開始只查詢訂單,對用戶信息進行延遲加載 -->
	 <select id="findOrderUserListLazyLoading" resultMap="orderCustomLazyLoading">
		 SELECT 
		  orders.*
		FROM
		  orders
	 </select>
複製代碼

使用resultMap來配置延遲加載

<!-- 一對一查詢延遲加載 的配置 -->
	<resultMap type="orders" id="orderCustomLazyLoading">
		<!-- 完成了訂單信息的映射配置 -->
		<!-- id:訂單關聯用戶查詢的惟 一 標識 -->
		<id column="id" property="id" />
		<result column="user_id" property="userId" />
		<result column="number" property="number" />
		<result column="createtime" property="createtime" />
		<result column="note" property="note" />
		<!-- 配置用戶信息的延遲加載 select:延遲加載執行的sql所在的statement的id,若是不在同一個namespace須要加namespace sql:根據用戶id查詢用戶信息【column就是參數】 column:關聯查詢的列 property:將關聯查詢的用戶信息設置到Orders的哪一個屬性 -->


		<!--當須要user數據的時候,它就會把column所指定的user_id傳遞過去給cn.itcast.mybatis.mapper.UserMapper.findUserById做爲參數來查詢數據-->
		<association property="user" select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id"></association>

	</resultMap>
複製代碼

這裏寫圖片描述

總結

  • 在程序中調用的SQL語句是由映射文件的命令空間+sql片斷的id所組成的。它內部會生成一個Statement對象的。
  • 在使用別名的時候,能夠指定包名,在使用總配置文件加載映射文件時,也能夠指定包名。
  • 主鍵若是須要返回的話,使用selectKey 標籤便可。UUID也能夠返回。在Oracle的話,是使用序列來返回自動增加的主鍵的。
  • 佔位符有兩種,一種是解析傳遞進來的參數數據、一種是原樣輸出傳遞進來的數據。

若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y

相關文章
相關標籤/搜索