mybatis中映射文件(mapper)中的書寫規則

一、增刪改

1、增加

<!-- 添加用戶-->
<insert id="saveUser" parameterType="com.tfjybj.domain.User">
		insert into user(username,birthday,sex,address)
		values(#{username},#{birthday},#{sex},#{address})
</insert>

說明
id屬性:
映射文件中方法的唯一標識,與對應dao層中執行此功能的方法名相同。

parameterType 屬性:
代表參數的類型,因爲我們要傳入的是一個類的對象,所以類型就寫類的全名稱。

sql 語句中使用#{}字符:
它代表佔位符,相當於原來 jdbc 部分所學的?,都是用於執行語句時替換實際的數據。具體的數據是由#{}裏面的內容決定的。

#{}中內容的寫法:
由於參數是 一個 User 對象,此處要寫 User 對象中的屬性名稱。這裏應用了 ognl 表達式。

ognl 表達式:
它是 apache 提供的一種表達式語言,全稱是:Object Graphic Navigation Language 對象圖導航語言。它是按照 #{對象.對象}的語法格式來獲取數據的,#{user.username}它會先去找 user 對象,然後在 user 對象中找到 username 屬性,並調用getUsername()方法把值取出來。但是我們在 parameterType 屬性上指定了實體類名稱,所以可以省略 user,而直接寫 username。

如何獲得新增數據id的返回值

方式一
mysql支持自增主鍵,自增主鍵的獲取,mybatis利用了statement.getGenreatedKeys();

在< insert> 標籤中添加
userGeneratedKeys=“true” :標明使用自增主鍵獲取主鍵值策略。
keyProperty:指定對應的主鍵屬性,也就是mybatis獲取到主鍵值之後,將這個值封裝給JavaScriptBean的哪個屬性。

<insert id="saveUser" parameterType="com.tfjybj.domain.User" 
	useGeneratedKeys="true" keyProperty="id">
		insert into user(username,birthday,sex,address)
		values(#{username},#{birthday},#{sex},#{address})
</insert>

方式二
新增用戶後,要求在新增數據後,將自動增長的auto_increment的值返回,mysql主鍵自增的返回,配置如下:

<insert id="saveUser" parameterType="com.tfjybj.domain.User">
<!-- keyColumn:要獲得哪個列的值
	 keyProperty:查詢出來的主鍵值封裝給就AV額Bean的哪個屬性
	 order:取值爲before,當前SQL在插入SQL之前運行。取值爲fater,當前SQL在插入SQL之後運行
	 resultType:查出的數據的返回值類型 -->
	<selectKey keyColumn="id" keyProperty="id" resultType="int" order="after">
		select last_insert_id();
	</selectKey>
	
	insert into user(username,birthday,sex,address)
	values(#{username},#{birthday},#{sex},#{address})
</insert>

2、刪除

<!-- 刪除用戶 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
	delete from user where id = #{uid}
</delete>

3、更新

<!-- 更新用戶 -->
<update id="updateUser" parameterType="com.tfjybj.domain.User">
	update user set username=#{username},birthday=#{birthday},sex=#{sex},
	address=#{address} where id=#{id}
</update>

:對於增刪改,我們需要手動提交數據
sqlSessionFactory.openSession(false)——默認爲false即代表手動提交

二、傳入參數處理

1、單個參數

mybatis不會做特殊處理,#{參數名},取出參數值。

2、多個參數

mybatis會被特殊處理,多個參數會被封裝成一個map
key :param1,param2,…paramN, 或者參數的索引也可以
value:傳入的參數值
#{key} 就是從map中獲取指定的key的值。
在這裏插入圖片描述
取值時,寫成 #{param1},#{param2}就會不報錯。

註解 @Param
而mybatis中還爲我們提供了一個註解 @Param,用來將傳入的參數,做一個別名處理,取值是直接使別名就能取到值:#{別名}
在這裏插入圖片描述

3、參數中有Collection(List、Set) 類型或者是數組

如果傳入的參數中有Collection(List、Set) 類型或者是數組,也會特殊處理,也會吧傳入的list或者數組封裝到map中。
key:Collection(collection)。
如果是List還可以使用key(list)、如果是數組可以使用key(array)
在這裏插入圖片描述

4、參數封裝成數據模型

如果多個參數正好是我們業務邏輯的數據模型,我們可以直接傳入pojo;
#{屬性名}:取出傳入的pojo的屬性值。

//dao層方法參數爲一個pojo
public Employee getEmpById(Employee employee);

<!-- mapper中可直接取出屬性名 -->
<select id="getEmpById"  resultType="com.zhyheima.mybatis.bean.Employee">
        select * from tb1_employee where id=#{id}
    </select>

如果多個參數不是業務模型中的數據,沒有對應的pojo,不經常使用,爲了方便,我們可以傳入map
#{key}:取出map中對應的值。
在這裏插入圖片描述

5、parameterType 配置 參數

基本類型和 String 我 們可以直接寫類型名稱 ,也可以使用包 名 . 類名的方式 ,例如 :java.lang.String。
實體類類型,目前我們只能使用全限定類名(前提是沒有在mybatis的全局配置文件中起別名)。

mybaits 在加載時已經把常用的數據類型註冊了別名,從而我們在使用時可以不寫包名,而我們的是實體類並沒有註冊別名,所以必須寫全限定類名。
在這裏插入圖片描述

三、查詢

1、模糊查詢

方式一

<!-- 根據名稱模糊查詢 -->
<select id="findByName" resultType="com.tfjybj.domain.User" parameterType="String">
	select * from user where username like #{username}
</select>

以上寫法中沒有加入%來作爲模糊查詢的條件,所以在程序代碼中傳入字符串實參時,就需要給定模糊查詢的標識%。配置文件中的#{username}也只是一個佔位符,所以 SQL 語句顯示爲“?”。

方式二

<!-- 根據名稱模糊查詢 -->
<select id="findByName" parameterType="string" resultType="com.tfjybj.domain.User">
	select * from user where username like '%${value}%'
</select>

將原來的#{}佔位符,改成了$ {value}。注意如果用模糊查詢的這種寫法,那麼$ {value}的寫法就是固定的,不能寫成其它名字。這樣在程序代碼中就不需要加入模糊查詢的匹配符%了。

2、#{}與${}的區別

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

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

大多數情況下,我們去參數的值都應該去使用#{};

3、返回屬性爲resultType

resultType 屬性可以指定結果集的類型,它支持基本類型和實體類類型。

  • 若返回的是一個List集合,則resultType中寫這個集合中的類型即可。
  • 若返回的是一個Map集合(查詢一條數據),則mybatis中的resultType中可以直接寫小map。
  • 若返回的是一個Map集合(查詢多條數據,每條數據的model作爲value),則mybatis中用這個model作爲返回類型,並且在dao層返回的Map聲明上加上註解@MapKey(“要作爲key的字段名”)
    在這裏插入圖片描述
    對於實體類型,它和 parameterType 一樣,如果註冊過類型別名的,可以直接使用別名。沒有註冊過的必須使用全限定類名。
    同時,當是實體類名稱時,還有一個要求,實體類中的屬性名稱必須和查詢語句中的列名保持一致,否則無法實現封裝。

4、返回屬性爲resultMap

若mybatis中查詢出的數據列與bean中的屬性無法對應上(名稱不對應),解決辦法:

  1. sql查詢的時候,查詢出的字段用as 後面加一個別名。
  2. 在全局配置文件中,使用settings設置,支持駝峯命名法。(mybatis在window系統下不區分字母大小寫,若數據庫中字段名爲lastname,javabean中的屬性名稱爲lastName,則可以查詢成功)。
  3. mybatis中使用resultMap作爲返回,resultMap可以自定義結果映射規則。

resultMap 標籤可以建立查詢的列名和實體類的屬性名稱不一致時建立對應關係。從而實現封裝。
在 select 標籤中使用 resultMap 屬性指定引用即可。同時 resultMap 可以實現將查詢結果映射爲複雜類型的 pojo,比如在查詢結果映射對象中包括 pojo 和 list 實現一對一查詢和一對多查詢。

自定義某個javaBean的封裝規則

resultMap屬性
type 屬性:指定實體類的全限定類名
id 屬性:給定一個唯一標識,是給查詢 select 標籤引用用的。

內部標籤
id 標籤:用於指定主鍵字段
result 標籤:用於指定非主鍵字段
column 屬性:用於指定數據庫列名
property 屬性:用於指定實體類屬性名稱

<!-- 建立 User 實體和數據庫表的對應關係
type 屬性:指定實體類的全限定類名
id 屬性:給定一個唯一標識,是給查詢 select 標籤引用用的。
-->
<resultMap type="com.zhyheima.domain.User" id="userMap">
	<id column="id" property="userId"/>
	<result column="username" property="userName"/>
	<result column="sex" property="userSex"/>
	<result column="address" property="userAddress"/>
	<result column="birthday" property="userBirthday"/>
</resultMap>

<!-- 配置查詢所有操作 -->
<select id="findAll" resultMap="userMap">
	select * from user
</select>

聯合查詢,實體級聯屬性封裝結果集(一對一或多對一)

一對一:對於查詢結果中,是兩個model的集合,即一個model嵌套了一個model,比如查詢被僱傭者的信息,並根據該信息查詢出僱主的信息,返回被僱傭者和僱主兩個model的信息。
多對一:僱傭者可能有多個,但只有一個僱主。
在這裏插入圖片描述

使用asscociation聯合查詢,定義實體級聯屬性封裝規則(一對一或多對一)

resultMap中還可以使用association標籤,進行一對一查詢。
在這裏插入圖片描述

進行分步查詢,使用asscociation聯合查詢,定義實體級聯屬性封裝規則(一對一或多對一)

分步查詢,先查詢被僱傭者的信息,在根據被僱傭者查詢僱傭者信息。被分爲了兩個sql語句。
在這裏插入圖片描述

使用collection嵌套結果集(一對多或多對多)

例如:
查詢所有用戶信息及用戶關聯的賬戶信息。
用戶信息和他的賬戶信息爲一對多關係。

<resultMap type="com.zhyheima.bean.user" id="userMap">
	<id column="id" property="id"></id>
	<result column="username" property="username"/>
	<result column="address" property="address"/>
	<result column="sex" property="sex"/>
	<result column="birthday" property="birthday"/>
	
	<!-- collection 是用於建立一對多中集合屬性的對應關係
	ofType 用於指定集合元素的數據類型
	-->
	<collection property="accounts" ofType="com.zhyheima.bean.account">
		<id column="aid" property="id"/>
		<result column="uid" property="uid"/>
		<result column="money" property="money"/>
	</collection>
</resultMap>

<!-- 配置查詢所有操作 -->
<select id="findAll" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
a on u.id =a.uid
</select>

collection
部分定義了用戶關聯的賬戶信息。表示關聯查詢結果集。

property=“accounts”
關聯查詢的結果集存儲在 User 對象的上哪個屬性。

ofType=“com.zhyheima.bean.account”
指定關聯查詢的結果集中的對象類型即List中的對象類型。

同樣collection也支持分佈查詢,具體查詢方式和association的方式一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章