MyBatis系列三: XxxMapper.xml-SQL映射文件

XxxMapper.xml-SQL映射文件

  • 官方文檔
  • 基本介紹
  • 詳細說明
    • 基本使用
    • parameterType(輸入參數類型)
    • 傳入HashMap
    • resultMap(結果集映射)

在這里插入圖片描述

官方文檔

文檔地址: https://mybatis.org/mybatis-3/zh_CN/sqlmap-xml.html

基本介紹

1.MyBatis的真正強大在于它的語句映射(在XxxMapper.xml配置), 由于它的異常強大, 如果拿它跟具有相同功能的JDBC代碼進行對比, 你會立即發現省掉了將近95%的代碼. MyBatis致力于減少使用成本, 讓用戶能更專注于SQL代碼.

2.SQL映射文件常用的幾個頂級元素 (按照應被定義的順序列出) :

cache - 該命名空間的緩存配置
cache-ref - 引用其它命名空間的緩存配置
resultMap - 描述如何從數據集結果集中加載對象, 是最復雜也是最強大的元素
parameterType - 將會傳入這條語句的參數的類全限定名或別名

sql - 可被其它語句引用的可重復的語句塊.
insert - 映射插入語句
update - 映射更新語句
delete - 映射刪除語句
select - 映射查詢語句

詳細說明

1.在原來的mybatis項目中, 新建xml-mapper子項目 [參考], 演示xml映射器的使用

2.新建Module后, 先創建需要的包, 再將需要的文件 / 資源拷貝過來(這里我們拷貝Monster.java, resources/jdbc.propertiesmybatis-config.xml)

3.拷貝MonsterMapper.java, MonsterMapper.xmlMonsterMapperTest.java, 做一個比較 干凈的講解環境

基本使用

1.insert, delete, update, select這個我們在前面學習過, 分別對應增刪改查的方法和SQL語句的映射
2.如何獲取到剛剛添加的Monster對象的id主鍵 [前面講解過了]

<insert id="addMonster" parameterType="Monster" useGeneratedKeys="true" keyProperty="id">INSERT INTO `monster` (`age`, `birthday`, `email`, `gender`, `name`, `salary`)VALUES (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary})
</insert>

parameterType(輸入參數類型)

●parameterType(輸入參數類型)
1.傳入簡單類型, 比如按照idMonster(前面學過)
2.傳入POJO類型, 查詢時需要有多個篩選條件
3.當有多個條件時, 傳入的參數就是Pojo類型的Java對象, 比如這里的Monster對象
4.當傳入的參數類是String時, 也可以使用 ${} 來接收參數

●parameterType-應用案例
案例1: 請查詢 id = 1 或者 name = 大象精 的妖怪
案例2: 請查詢 name 中包含 “牛魔王” 的妖怪

●代碼實現
1.修改MonsterMapper.java, 增加方法接口

public interface MonsterMapper {//通過id 或者 名字查詢public List<Monster> findMonsterByNameOrId(Monster monster);//查詢名字中含有牛魔王的妖怪public List<Monster> findMonsterByName(String name);
}

2.修改MonsterMapper.xml

<mapper namespace="com.zzw.mapper.MonsterMapper"><!--1. 配置/實現public List<Monster> findMonsterByNameOrId(Monster monster);2. 通過id 或者 名字查詢3. `id` = #{id} `id`表示表的字段名 #{id}中的id表示你傳入的Monster對象的屬性名--><select id="findMonsterByNameOrId" parameterType="Monster" resultType="Monster">SELECT * FROM `monster` WHERE `id` = #{id} OR `name` = #{name}</select><!--1. 配置/實現public List<Monster> findMonsterByName(Monster monster);2. 查詢名字中 含有 "牛魔王" 的妖怪 - 模糊查詢`3. 模糊查詢的使用 取值需要 ${value} 取值--><select id="findMonsterByName" parameterType="String" resultType="Monster">SELECT * FROM `monster` WHERE `name` LIKE '%${name}%'</select>
</mapper>

3.修改MonsterMapperTest.java, 進行測試

public class MonsterMapperTest {//屬性private SqlSession sqlSession;private MonsterMapper monsterMapper;//編寫方法完成初始化@Beforepublic void init() {//獲取到sqlSessionsqlSession = MyBatisUtils.getSqlSession();//獲取到MonsterMapper對象 monsterMapper=class com.sun.proxy.$Proxy7 代理對象//, 底層是使用了動態代理機制, 后面我們自己實現mybatis底層機制時, 會講到monsterMapper = sqlSession.getMapper(MonsterMapper.class);System.out.println("monsterMapper=" + monsterMapper.getClass());}@Testpublic void findMonsterByNameOrId(){Monster monster = new Monster();monster.setId(1);monster.setName("大象精");List<Monster> monsters =monsterMapper.findMonsterByNameOrId(monster);for (Monster m : monsters) {System.out.println("m--" + m);}if (sqlSession != null) {sqlSession.close();}System.out.println("查詢成功");}@Testpublic void findMonsterByName() {List<Monster> monsters = monsterMapper.findMonsterByName("牛魔王");for (Monster monster : monsters) {System.out.println("monster--" + monster);}if (sqlSession != null) {sqlSession.close();}System.out.println("查詢成功");}
}

傳入HashMap

●傳入HashMap(重點)
1.HashMap傳入參數更加靈活, 比如可以靈活地增加查詢的屬性, 而不受限于Monster這個Pojo屬性本身
2.演示如何遍歷一個List<Map<String, Object>>的數據類型

●傳入HashMap - 應用實例1
要求: 聲明一個方法, 按傳入參數是HashMap的方式, 查詢 id > 10 并且 salary > 40的所有妖怪

1.修改MonsterMapper.java, 增加方法接口

//查詢 id > 10 并且 salary > 40的所有妖怪
public List<Monster> findMonsterByIdAndSalary_ParameterHashMap(Map<String, Object> map);

2.修改MonsterMapper.xml

<!--
1. 配置/實現public List<Monster> findMonsterByIdAndSalary_ParameterHashMap(Map<String, Objects> map);
2. 查詢 id > 10 并且 salary > 40的所有妖怪
3. 如果是以map形式傳入參數, 當你這樣寫條件 `id` > #{id} 表示你的map 中有一個k-v 中 key為id
-->
<select id="findMonsterByIdAndSalary_ParameterHashMap" parameterType="map" resultType="Monster">SELECT * FROM `monster` WHERE `id` > #{id} AND `salary` > #{salary}
</select>

3.修改MonsterMapperTest.java, 進行測試

@Test
public void findMonsterByIdAndSalary_ParameterHashMap() {Map<String, Object> map = new HashMap<>();map.put("id", 10);map.put("salary", 40);List<Monster> monsters =monsterMapper.findMonsterByIdAndSalary_ParameterHashMap(map);for (Monster monster : monsters) {System.out.println("monster--" + monster);}if (sqlSession != null) {sqlSession.close();}System.out.println("查詢成功");
}

●傳入和返回HashMap - 應用實例2
要求: 將上面的方法改成返回參數也是HashMap的類型

1.修改MonsterMapper.java, 增加方法接口

//查詢 id > 10 并且 salary > 40, 要求傳入的參數是HashMap
public List<Map<String, Object>>findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap(Map<String, Object> map);

2.修改MonsterMapper.xml

<!--
1. 配置/實現public List<Map<String, Object>>findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap
2. 查詢 id > 10 并且 salary > 40, 要求傳入的參數是HashMap
-->
<select id="findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap" parameterType="map"resultType="map">SELECT * FROM `monster` WHERE `id` > #{id} AND `salary` > #{salary}
</select>

3.修改MonsterMapperTest.java, 進行測試

@Test
public void findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap() {Map<String, Object> map = new HashMap<>();map.put("id", 10);map.put("salary", 40);List<Map<String, Object>> maps =monsterMapper.findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap(map);//取出返回的結果-以map的形式取出//回顧java基礎, map遍歷for (Map<String, Object> monsterMap : maps) {//System.out.println("monsterMap--" + monsterMap);//遍歷monsterMap(方式1), 取出屬性和對應值//Set<String> keySet = monsterMap.keySet();//for (String key : keySet) {//    Object value = monsterMap.get(key);//    System.out.println(key + "=>" + value);//}//遍歷monsterMap(方式2), 取出屬性和對應值Set<Map.Entry<String, Object>> entries = monsterMap.entrySet();for(Map.Entry<String, Object> entry : entries) {System.out.println(entry.getKey() + "=>" + entry.getValue());}System.out.println("==================================");}if (sqlSession != null) {sqlSession.close();}System.out.println("查詢成功");
}

resultMap(結果集映射)

●基本介紹
當實體類的屬性和表的字段不一致時, 我們可以通過resultMap進行映射, 從而屏蔽實體類屬性名和表的字段名的不同.

●案例演示
1.創建表user

-- 創建表 user
CREATE TABLE `user` (`user_id` INT NOT NULL AUTO_INCREMENT,`user_email` VARCHAR(255) DEFAULT '',`user_name` VARCHAR(255) DEFAULT '',PRIMARY KEY (`user_id`)
)CHARSET=utf8

2.創建實體類com.zzw.entity.User

public class User {private Integer user_id;private String username;private String useremail;//setter, getter, toString方法
}

3.創建com.zzw.mapper.UserMapper.java

public interface UserMapper {//添加方法public void addUser(User user);//查詢所有Userpublic List<User> findAllUser();
}

4.創建com.zzw.mapper.UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--解讀1. 這是一個mapper xml 文件2. 該文件可以去實現對應的接口的方法3. namespace 指定該xml文件和哪個接口對應!!!
-->
<mapper namespace="com.zzw.mapper.UserMapper"><!--1. 配置/實現public void addUser(User user);2. 完成添加用戶的任務,注意這里--><select id="addUser" parameterType="User">INSERT INTO `user` (`user_email`, `user_name`)VALUES (#{useremail}, #{username})</select><!--1.配置/實現public List<User> findAllUser();2.返回所有User信息3.按照傳統的方式完成, 會出現什么問題?=> 如果對象屬性和表字段相同時, 就會設置值; 如果不同, 就會是默認值4.我們可以使用resultMap來解決5.resultMap: 表示我們要定義一個resultMap6.id="findAllUserMap" type="User" => id 就是程序員指定的resultMap id, 后面通過id可以使用它7.type="User", 就是你需要返回的對象類型8.result column="user_name" property="username": column="user_name" 表的字段名, property="username" 對象屬性名9.resultMap="findAllUserMap" 表示使用我們定義的 resultMap, 通過id關聯--><resultMap id="findAllUserMap" type="com.zzw.entity.User"><result column="user_name" property="username"/><result column="user_email" property="useremail"/></resultMap><select id="findAllUser" resultMap="findAllUserMap">SELECT * FROM `user`</select>
</mapper>

5.測試com.zzw.mapper.UserMapperTest

public class UserMapperTest {//屬性private SqlSession sqlSession;private UserMapper userMapper;//初始化@Beforepublic void init() {sqlSession = MyBatisUtils.getSqlSession();userMapper = sqlSession.getMapper(UserMapper.class);}@Testpublic void addUser() {User user = new User();user.setUsername("jack");user.setUseremail("jack@163.com");userMapper.addUser(user);//如果是增刪改, 需要提交事務if (sqlSession != null) {sqlSession.commit();sqlSession.close();}System.out.println("增加成功");}@Testpublic void findAllUser() {List<User> users = userMapper.findAllUser();for (User user : users) {System.out.println("user--" + user);}if (sqlSession != null) {sqlSession.close();}System.out.println("查詢成功");}
}

●注意事項和細節
1.解析表字段和對象屬性名不一致, 也支持使用字段別名

<!--使用表字段別名, 來解決表的字段名和對象屬性名, 不一致問題, 可以用, 但是我們仍然推薦使用resultMap-->
<select id="findAllUser" resultType="User">SELECT user_id, user_name as username, user_email as useremail FROM `user`
</select>

2.說明: 如果是MyBatis-Plus處理就比較簡單, 可以使用 注解TableField 來解決實體字段名和表字段名不一致的問題, 還可以使用@TableName來解決 實體類名和表名不一致的問題

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39455.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39455.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39455.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024年06月CCF-GESP編程能力等級認證Python編程一級真題解析

本文收錄于專欄《Python等級認證CCF-GESP真題解析》,專欄總目錄:點這里,訂閱后可閱讀專欄內所有文章。 一、單選題(每題 2 分,共 30 分) 第 1 題 小楊父母帶他到某培訓機構給他報名參加CCF組織的GESP認證考試的第1級,那他可以選擇的認證語言有幾種?( ) A. 1 B. 2 C…

React@16.x(45)路由v5.x(10)源碼(2)- history

目錄 1&#xff0c;作用1.1&#xff0c;createBrowserHistory1.2&#xff0c;createHashHistory1.3&#xff0c;createMemoryHistory 2&#xff0c;history 對象的屬性2.1&#xff0c;action2.2&#xff0c;push / replace / go / goBack / goForward2.3&#xff0c;location2.…

網絡配線架的隱藏功能

網絡布線是確保現代信息社會高效運轉的關鍵技術之一。在這一領域&#xff0c;網絡配線架扮演著至關重要 的角色。它不僅僅是一個簡單的物理連接點&#xff0c;更擁有許多隱藏功能&#xff0c;這些功能極大地提升了網絡的 效率、穩定性和可管理性。 1、集中管理 網絡配線架提…

【BES2500x系列 -- RTX5操作系統】深入探索CMSIS-RTOS RTX -- 同步與通信篇 -- 消息隊列和郵箱處理 --(四)

&#x1f48c; 所屬專欄&#xff1a;【BES2500x系列】 &#x1f600; 作??者&#xff1a;我是夜闌的狗&#x1f436; &#x1f680; 個人簡介&#xff1a;一個正在努力學技術的CV工程師&#xff0c;專注基礎和實戰分享 &#xff0c;歡迎咨詢&#xff01; &#x1f49…

經典FC游戲web模擬器--EmulatorJS

簡介 EmulatorJS是一個基于JavaScript和Webassembly技術的虛擬環境的實現&#xff0c;可以在網頁中運行各種經典FC游戲系統&#xff0c;支持任天堂、世嘉、雅達利等經典紅白機。EmulatorJS的誕生使得諸如超級瑪麗、坦克大戰、魂斗羅等經典FC游戲能夠以一種全新的方式回歸。本文…

SAP MM模塊的ATP檢查

前面幾篇文章都演示和說明ATP的一些設置和操作&#xff0c;通常情況下ATP的檢查PP模塊&#xff0c;SD模塊用的相對來說是比較多的&#xff0c;但是實際上MM模塊也會遵循ATP的可用性的檢查規則。 當我們在做311、301等移動類型時&#xff0c;系統會根據相應的可用性檢查規則&am…

Linux常用指令匯總

Linux常用指令匯總 Cfilt 功能&#xff1a;解析C程序中被修飾的符號&#xff0c;比如變量與函數名稱。 示例&#xff1a; 解析編譯器 g 修飾的函數名稱。 cfilt -s gnu-v3 _Z5printRKSs print(std::basic_string<char, std::char_traits<char>, std::allocator<…

Django 多對多關系

多對多關系作用 Django 中&#xff0c;多對多關系模型的作用主要是為了表示兩個模型之間的多對多關系。具體來說&#xff0c;多對多關系允許一個模型的實例與另一個模型的多個實例相關聯&#xff0c;反之亦然。這在很多實際應用場景中非常有用&#xff0c;比如&#xff1a; 博…

【每日一個Git命令: cherry-pick】

git cherry-pick 命令的作用是將指定的提交&#xff08;commit&#xff09;應用到其他分支上。這個命令允許你選擇一個或多個已有的提交&#xff0c;并將它們作為新的提交引入到當前分支中。 這個過程不會改變項目的歷史記錄&#xff0c;因為它實際上是創建了這些提交的副本。…

BMA530 運動傳感器

型號簡介 BMA530是博世&#xff08;bosch-sensortec&#xff09;的一款運動傳感器。時尚簡約的可穿戴設備為功能強大的組件提供了很小的空間。具有先進功能集的下一代加速度計是世界上最小的加速度傳感器&#xff08;1.2 x 0.8 x 0.55 mm&#xff09;。它專為緊湊型設備而設計&…

24/07/02數據結構(1.1201)算法效率順序表

數據結構基本內容:1.時間復雜度 空間復雜度2.順序表鏈表3.棧 隊列4.二叉樹5.排序 數據結構是存儲,組織數據的方式.指相互之間存在一種或多種特定關系的數據元素的集合 算法是定義良好的計算過程.取一個或一組值為輸入并產生一個或一組值為輸出. 需要知道雖然選擇題有20-30個…

Leetcode1114 交替打印 FooBar及其測試

題目描述 相關標簽 相關企業 給你一個類&#xff1a; class FooBar { public void foo() { for (int i 0; i < n; i) { print(“foo”); } } public void bar() { for (int i 0; i < n; i) { print(“bar”); } } } 兩個不同的線程將會共用一個 FooBar 實例&#xf…

python自動化運維--DNS處理模塊dnspython

1.dnspython介紹 dnspython是Pyhton實現的一個DNS工具包&#xff0c;他幾乎支持所有的記錄類型&#xff0c;可以用于查詢、傳輸并動態更新ZONE信息&#xff0c;同事支持TSIG&#xff08;事物簽名&#xff09;驗證消息和EDNS0&#xff08;擴展DNS&#xff09;。在系統管理方面&a…

Linux高并發服務器開發(九)Tcp狀態轉移和IO多路復用

文章目錄 0 包裹函數1 多進程服務器流程代碼 2 多線程服務器3 TCP狀態轉移半關閉心跳包 4 端口復用5 IO多路復用技術高并發服務器 6 select代碼總結 7 POLLAPI代碼poll相對select的優缺點 8 epoll&#xff08;重點&#xff09;API監聽管道代碼EPOLL 高并發服務器 9 Epoll的兩種…

Iot解決方案開發的體系結構模式和技術

前言 Foreword 計算機技術起源于20世紀40年代&#xff0c;最初專注于數學問題的基本原理&#xff1b;到了60年代和70年代&#xff0c;它以符號系統為中心&#xff0c;該領域首先開始面臨復雜性問題&#xff1b;到80年代&#xff0c;隨著個人計算的興起和人機交互的問題&#x…

【進階篇】Java 項目中對使用遞歸的理解分享

前言 筆者在最近的項目開發中&#xff0c;遇到了兩個父子關系緊密相關的場景&#xff1a;評論樹結構、部門樹結構。具體的需求如&#xff1a;找出某條評論下的所有子評論id集合&#xff0c;找出某個部門下所有的子部門id集合。 在之前的項目開發經驗中&#xff0c;遞歸使用得是…

centos7安裝python3.10

文章目錄 1. 安裝依賴項2. 下載Python 3.10源碼3. 解壓源碼并進入目錄4. 配置安裝選項5. 編譯并安裝Python6. 驗證安裝7.創建軟連接8. 安裝pip39. 換源 1. 安裝依賴項 sudo yum groupinstall -y "Development Tools" sudo yum install -y openssl-devel bzip2-devel…

Eureka的自擴展之道:服務自動擴展的秘訣

&#x1f31f; Eureka的自擴展之道&#xff1a;服務自動擴展的秘訣 在微服務架構中&#xff0c;服務的自動擴展是實現高可用性和彈性伸縮的關鍵。Eureka作為Netflix開源的服務發現框架&#xff0c;提供了一套機制來支持服務的自動擴展。本文將詳細介紹Eureka如何實現服務的自動…

【LeetCode】十、二分查找法:尋找峰值 + 二維矩陣的搜索

文章目錄 1、二分查找法 Binary Search2、leetcode704&#xff1a;二分查找3、leetcode35&#xff1a;搜索插入位置4、leetcode162&#xff1a;尋找峰值5、leetcode74&#xff1a;搜索二維矩陣 1、二分查找法 Binary Search 找一個數&#xff0c;有序的情況下&#xff0c;直接…

第4章:Electron主窗口與子窗口管理

4.1 創建主窗口 主窗口是 Electron 應用啟動后顯示的第一個窗口&#xff0c;通常用來承載應用的主界面。我們使用 BrowserWindow 類來創建主窗口。 4.1.1 創建主窗口的基礎代碼 // 引入 Electron 模塊和 Node.js 的 path 模塊 const { app, BrowserWindow } require(electr…