這是mybatis系列第5篇,沒看前文的建議先去【Java冢狐】公眾號中查看前文,方便理解和掌握,
說到底Mybatis常見的傳參形式無非是傳遞一個引數、Map、Java物件,亦或是多個引數,下面就分別對這些進行講解和說明,
傳遞一個引數
傳遞一個引數相對來說較為簡單
用法
Mapper介面方法中只有一個引數,如:
UserModel getByName(String name);
Mapper xml參考這個name引數:
#{任意合法名稱}
如:#{name}、#{val}、${x}等等寫法都可以參考上面name引數的值,
直接使用即可相當的方便和簡單
傳遞一個Map引數
用法
如果我們需要傳遞的引數比較多,引數個數是動態的,那么我們可以將這些引數放在一個map中,key為引數名稱,value為引數的值,在作業中,這種可以說是最常見的,大多數情況下都可以進行使用
Mapper介面中可以這么定義,如:
List<UserModel> getByMap(Map<String,Object> map);
如我們傳遞:
Map<String, Object> map = new HashMap<>();
map.put("id", 1L);
map.put("name", "冢狐");
對應的mapper xml中可以通過#{map中的key}可以獲取key在map中對應的value的值作為引數,如:
SELECT * FROM t_user WHERE id=#{id} OR name = #{name}
傳遞一個java物件引數
當引數比較多,但是具體有多少個引數我們是確定的時候,我們可以將這些引數放在一個javabean物件中,這樣也有利于理解,知道需要傳遞那些引數,不想map一樣對于傳遞的引數不是很明確,
如我們想通過userId和userName查詢,可以定義一個dto物件,屬性添加對應的get、set方法,如:
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserFindDto {
private Long userId;
private String userName;
}
傳遞java物件的方式相對于map的方式更清晰一些,可以明確知道具體有哪些引數,而傳遞map,我們是不知道這個map中具體需要哪些引數的,map對引數也沒有約束,引數可以隨意傳,建議多個引數的情況下選擇通過java物件進行傳參,
傳遞多個引數
上面我們介紹的都是傳遞一個引數,那么是否可以傳遞多個引數呢?我們來試試吧,
多引數mybatis的處理
mybatis處理多個引數的時候,會將多個引數封裝到一個map中,map的key為引數的名稱,java可以通過反射獲取方法引數的名稱,下面這個方法:
UserModel getByIdOrName(Long id, String name);
編譯之后,方法引數的名稱通過反射獲取的并不是id、name,而是arg0、arg1,也就是說編譯之后,方法真實的引數名稱會丟失,會變成arg+引數下標的格式,
所以上面傳遞的引數相當于傳遞了下面這樣的一個map:
Map<String,Object> map = new HashMap<>();
map.put("arg0",id);
map.put("arg1",name);
所以說我們的方法真實的引數名稱會丟失,如果要想使用真實的引數名稱,就需要在編譯java代碼使用javac命令的時候帶上-parameters引數,當編譯代碼的時候加上這個引數,方法的實際名稱會被編譯到class位元組碼檔案中,當通過反射獲取方法名稱的時候就不是arg0、arg1這種格式了,而是真實的引數名稱:id、name了,
我們來修改一下maven的配置讓maven編譯代碼的時候加上這個引數,修改pom.xml中的build元素,這個元素中加入下面代碼:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
idea中編譯代碼也加一下這個引數,操作如下:
點擊File->Settings->Build,Execution,Deployment->Java Compiler,如下圖:

下面我們將xml中的getByIdOrName對應的sql修改成下面這樣:
SELECT * FROM t_user WHERE id=#{arg0} OR name = #{arg1} LIMIT 1
使用maven命令重新編譯一下chat01的代碼,cmd命令中mybatis-demo/pom.xml所在目錄執行下面命令:
mvn clean compile -pl :chat01
引數名稱變成了真實的名稱了,但是還是有param1、param2,方法引數名稱不管怎么變,編譯方式如何變化,param1, param2始終在這里,這個param1, param2就是為了應對不同的編譯方式導致引數名稱而發生變化的,mybatis內部除了將引數按照名稱->值的方式放入map外,還會按照引數的順序放入一些值,這些值的key就是param+引數位置,這個位置從1開始的,所以id是第一個引數,對應的key是param1,name對應的key是param2,value對應的還是引數的值,所以mybatis對于引數的處理相當于下面程序:
Map<String,Object> map = new HashMap<>();
map.put("反射獲取的引數id的名稱",id);
map.put("反射獲取的引數name的名稱",name);
map.put("param1",id);
map.put("param2",name);
使用注意
- 使用引數名稱的方式對編譯環境有很強的依賴性,如果編譯中加上了
-parameters引數,引數實際名稱可以直接使用,如果沒有加,引數名稱就變成arg下標的格式了,這種很容易出錯 - sql中使用
param1、param2、paramN這種方式來參考多引數,對引數的順序依賴性特別強,如果有人把引數的順序調整了或者調整了引數的個數,后果就是災難性的,所以這種方式不建議大家使用,
多引數中用@param指定引數名稱
剛才上面講了多引數傳遞的使用上面,對引數名稱和順序有很強的依賴性,容易導致一些嚴重的錯誤,
mybatis也為我們考慮到了這種情況,可以讓我們自己去指定引數的名稱,通過@param(“引數名稱”)來給引數指定名稱,
/**
* 通過id或者name查詢
*
* @param id
* @param name
* @return
*/
UserModel getByIdOrName(@Param("userId") Long id, @Param("userName") String name);
上面我們通過@Param注解給兩個引數明確指定了名稱,分別是userId、userName,對應的user.xml中也做一下調整,如下:
<!-- 通過id或者name查詢 -->
<select id="getByIdOrName" resultType="zhonghu.mybatis.chat01.UserModel">
<![CDATA[
SELECT * FROM user WHERE id=#{userId} OR name = #{userName} LIMIT 1
]]>
</select>
ResultHandler作為引數
用法
查詢的數量比較大的時候,回傳一個List集合占用的記憶體還是比較多的,比如我們想匯出很多資料,實際上如果我們通過jdbc的方式,遍歷ResultSet的next方法,一條條處理,而不用將其存到List集合中再取處理,
mybatis中也支持我們這么做,可以使用ResultHandler物件,猶如其名,這個介面是用來處理結果的,先看一下其定義:
public interface ResultHandler<T> {
void handleResult(ResultContext<? extends T> resultContext);
}
里面有1個方法,方法的引數是ResultContext型別的,這個也是一個介面,看一下原始碼:
public interface ResultContext<T> {
T getResultObject();
int getResultCount();
boolean isStopped();
void stop();
}
4個方法:
- getResultObject:獲取當前行的結果
- getResultCount:獲取當前結果到第幾行了
- isStopped:判斷是否需要停止遍歷結果集
- stop:停止遍歷結果集
ResultContext介面有一個實作類org.apache.ibatis.executor.result.DefaultResultContext,mybatis中默認會使用這個類,
最后
- 如果覺得看完有識訓,希望能關注一下,順便給我點個贊,這將會是我更新的最大動力,感謝各位的支持
- 歡迎各位關注我的公眾號【java冢狐】,專注于java和計算機基礎知識,保證讓你看完有所識訓,不信你打我
- 求一鍵三連:點贊、轉發、在看,
- 如果看完有不同的意見或者建議,歡迎多多評論一起交流,感謝各位的支持以及厚愛,
——我是冢狐,和你一樣熱愛編程,
歡迎關注公眾號“Java冢狐”獲取最新訊息
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/259095.html
標籤:Java
上一篇:在QT C++中呼叫 Python并將軟體打包發布(裸機可運行)
下一篇:超詳細 DNS 協議決議
