一文搞懂Mybatis中Mapper配置文件獲取參數(shù)的五種方式
前提提要
本系列Mybatis筆記基于mybatis3.5.2 , https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.2中有詳細的文檔說明,可以進行下載閱讀,本文只是對Mybatis的一些常用操作進行匯總總結(jié)。
- IDE: IntelliJ IDEA 2021.3
- 構(gòu)建工具: apache-maven-3.6.3
- MySQL版本:MySQL 5.7.35
- MyBatis版本:MyBatis 3.5.7
對于mybatis框架的使用,按照上次介紹的,我們配置的映射文件中,通過namespace將映射文件和接口關(guān)聯(lián)起來了。
具體方法通過id精確的對應。然后,方法對應的具體數(shù)據(jù)操作,在mapper文件中的<insert><select>.... 書寫具體的SQL語句來進行實現(xiàn)。
但是,對于一些需要傳輸數(shù)據(jù)的行為,如條件查詢,插入操作等等,都需要將用戶調(diào)用接口的實際參數(shù)數(shù)據(jù),落實到具體的mapper文件中的各個方法中。
問題來了?
給接口的實際參數(shù),mapper實際操作如何取對應的數(shù)據(jù), 數(shù)據(jù)是以什么方式傳遞給mapper中各標簽實現(xiàn)數(shù)據(jù)的CRUD操作的呢?
一,IDEA中設置各種配置文件的模板
這節(jié)內(nèi)容主要就是平時開發(fā)過程中的技巧性操作。
1. 設置mybatis-config.xml文件模板
模板內(nèi)容:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"></properties> <typeAliases> <package name=""></package> </typeAliases> <!--設置連接數(shù)據(jù)庫的環(huán)境--> <environments default="development"> <environment id="development"> <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> <!--引入映射文件--> <mappers> <package name=""/> </mappers> </configuration>
在IDEA
中添加mybatis-config.xml
文件模板的具體操作:
最后的效果如圖所示,新建完上述模板之后,就可以按照上述你創(chuàng)建的模板創(chuàng)建一個mybatis-config.xml
文件。
2. 設置 **mapper.xml映射文件模板
和上述mybatis-confg.xml
設置文件模板一樣,模板內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace=""> </mapper>
具體的操作和設置mybatis-config.xml
操作是一樣的。
二,獲取參數(shù)的兩種方式
在談將調(diào)用接口的實際參數(shù)傳給mapper
中各個標簽實際操作是什么樣之前,我們先看看mapper
中獲取參數(shù)的兩種方式,我們知道JDBC
中有兩種設置參數(shù)的方式:
通過參數(shù)預處理的方式 2. 通過拼接SQL的方式
@Test public void testJDBC() throws SQLException, ClassNotFoundException { String username = "cherry"; Class.forName(""); Connection connection = DriverManager.getConnection("", "", ""); // 1. 字符串拼接 ->獲得預編譯對象 -》sql注入問題 PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where username = '" + username + "'"); // 2. 占位符 PreparedStatement ps2 = connection.prepareStatement("select * from t_user where username = ?"); ps2.setString(1, username); }
對應于MyBatis
中,我們也有這兩種方式:1. 字符串拼接 2. 占位符
MyBatis獲取參數(shù)值的兩種方式:${}
和#{}
,就和JDBC
中的兩種方式一脈相承。
${}
的本質(zhì)就是字符串拼接#{}
的本質(zhì)就是占位符賦值
${}
使用字符串拼接的方式拼接sql
,若為字符串類型或日期類型的字段進行賦值時,需要手動加單引號;
但是#{}
使用占位符賦值的方式拼接sql
,此時為字符串類型或日期類型的字段進行賦值時,可以自動添加單引號(盡量使用這一種)。
三,MyBatis獲取參數(shù)值的五種情況
通過了上述說明了Mybatis
中兩種獲取基本方式的區(qū)別。下面通過給接口
床傳遞實參不同的形式來劃分為一下五種情況進行一一的說明。
3.1 單個字面量類型的參數(shù)
也就是如果調(diào)用的形式是:
getUserById(1)
若mapper
接口中的方法參數(shù)為單個的字面量類。此時可以使用${}
和#{}
以任意的名稱獲取參數(shù)的值,注意${}
需要手動加單引號。
如下所示:
public interface ParameterMapper { /** * 單個的字面量類型: * 根據(jù)用戶名查詢用戶信息 */ User getUserByUserName(String username); }
在對應的配置類中進行配置,按照上述的方式,都可以進行配置,如下:
Notice:使用#{}
,里面內(nèi)容可以隨便寫,都是傳進來的username
的值。
方式一:
<!-- User getUserByUserName(String username);--> <!-- 使用#{},里面內(nèi)容可以隨便寫,都是傳進來的username的值--> <select id="getUserByUserName" resultType="User"> select * from t_user where username = #{username} </select>
方式二:
<!-- User getUserByUserName(String username);--> <select id="getUserByUserName" resultType="User"> <!-- select * from t_user where username = ${username} 如果使用這種方式,得到的sql語句是: Preparing: select * from t_user where username = RUOYI 而其中username的值‘RUOYI'沒有單引號,語句不正確,會報錯。 因此要手動添加單引號 --> select * from t_user where username = '${username}' </select>
測試類:
/** * MyBatis獲取參數(shù)值的各種情況: * 情況1: mapper接口方法的參數(shù)為單個字面量的參數(shù) * 可以通過${} #{}以任意的字符串獲得參數(shù)值,但需要注意${}的單引號問題 */ @Test public void testgetUserByUserName(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = mapper.getUserByUserName(""); System.out.println(user); }
3.2 多個字面量類型的參數(shù)
若在mapper
接口的方法中有多個參數(shù)的時候,我們MyBatis
的操作是會自動的將這些參數(shù)放到一個Map
集合中。通過以arg0, arg1, arg2... argn
,以參數(shù)值為值。還有一種就是通過param1, param2...
,以參數(shù)為值。
因此,只要通過#{}
或者是${}
訪問map
集合中的鍵就可以獲取到對應的值。但是需要注意的是${}
需要手動加上單引號。
public interface ParameterMapper { /** * 驗證登錄 */ User checkLogin(String username, String password); }
對應在mapper
映射文件中:
<!-- User checkLogin(String username, String password);--> <select id="checkLogin" resultType="User"> <!-- 寫:select * from t_user where username = #{username} and password = #{password} 會報錯:Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2] 因為sql語句沒有解析成功--> <!--以map集合形式存儲,arg0->param0, arg1->param1,這時直接用鍵arg訪問就好了,用param訪問也行。 以下兩種方式選一個:--> select * from t_user where username = #{arg0} and password = #{arg1} select * from t_user where username = '${param1}' and password = '${param2}' </select>
測試類:
/** * 情況2:mapper接口方法的參數(shù)為多個時 * 此時MyBatis會將這些參數(shù)放在一個map集合中,以兩種方式進行存儲 * a》以arg0,arg1。。為鍵,參數(shù)為值 * b》以param0,param1。。為鍵,參數(shù)位置 * 因此只需要通過#{}和${}以鍵的方式訪問值即可,但需要注意${}的單引號問題 */ @Test public void testCheckLogin(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = mapper.checkLogin("fangshaolei","123456"); System.out.println(user); }
Notice: 寫:select * from t_user where username = #{username} and password = #{password}
會報錯:Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
因為sql
語句沒有解析成功
3.3 Map集合類型的參數(shù)
我們大概有了一些思路,基本上對于所有的參數(shù)。Mybatis
的操作都是先將所有的參數(shù)都封裝到一個map
中,然后在mapper
中使用#{}
或者是${}
來進行取。
如果mapper
接口中的方法需要的參數(shù)為多個時,此時可以手動創(chuàng)建map集合,也就是我們不在通過mybatis
來進行創(chuàng)建參數(shù),而是手動的自己傳過去一個map
。
所以,將這些數(shù)據(jù)放在map
中只需要通過${}
和#{}
訪問map
集合的鍵就可以獲取相對應的值,注意${}
需要手動加單引號.
public interface ParameterMapper { /** * 驗證登錄 */ User checkLoginByMap(Map<String, Object> map); }
在對應的map
中進行取用的操作。
<!-- User checkLoginByMap(Map<String, Object> map);--> <select id="checkLoginByMap" resultType="User"> select * from t_user where username = #{username} and password = #{password} </select>
測試類:
/** * 情況3:若mapper接口方法的參數(shù)有多個時,可以手動將這些參數(shù)放在一個map中存儲 * 只需要通過#{} ${}以鍵的方式訪問值即可,但是需要注意${}的單引號問題 */ @Test public void testCheckLoginByMap(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); Map<String, Object> map = new HashMap<>(); map.put("username","RUOYI"); map.put("password","123456"); User user = mapper.checkLoginByMap(map); System.out.println(user); }
Notice:但是需要注意的是,對于自己封裝的map
的形式,在使用兩種方式進行取用的時候,需要指定在map
中的鍵,也就是我們自己存在map
數(shù)據(jù)中的鍵。
3.4 實體類參數(shù)
如果mapper
接口中的方法參數(shù)是實體類對象的時候,此時可以使用 #{}
和${}
,通過訪問實體類對象中的屬性名獲取屬性值,同樣需要注意的是:${}
需要手動加上單引號。
其實,實體類對象參數(shù),在mybatis
中會被封裝成map
對象的形式。Mapper
對應的接口:
public interface ParameterMapper { /** * 添加用戶信息 */ int insertUser(User user); }
Mapper.xml
文件中的配置:
<!-- int insertUser(User user);--> <!-- 找到相對應的get方法,如username->找getUsername(),看get/set方法--> <insert id="insertUser"> insert into t_user values(null, #{username}, #{password}, #{age}, #{gender}, #{email}) </insert>
測試類:
/** * 情況4:mapper接口方法的參數(shù)是實體類類型的參數(shù)(web從control層傳過來的) * 只需要通過#{} ${}以屬性的方式訪問屬性值即可,但是需要注意${}的單引號問題 */ @Test public void testInsertUser(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = new User(null, "fangshaolei", "123456", 66, "m", "sl.fang@gmail.com"); mapper.insertUser(user); }
Notice:同樣需要注意的是,#{}
中的參數(shù)名稱不能隨意的寫,要和屬性名稱一致。
3.5 使用@Param標識參數(shù)
通過上述的四種方法,我們知道,除了只有一個字面量參數(shù)之外。其他的參數(shù)通過#{}
或者是${}
取用的值都需要正確的給定Mybatis
內(nèi)部map
的鍵。
如果是多個字面量,按照Mybatis
內(nèi)部默認的鍵來進行取用。如果傳過來的參數(shù)是自己定義的Map
或者是實體類對象
的形式。則在取用的時候,指定參數(shù)名稱和自定義Map
的鍵一致和如果參數(shù)是實體類對象,則需要和對象的屬性名一致。
但是,我們能夠自定義Mybatis
內(nèi)部已經(jīng)封裝好的Map
的key
,從而通過#{}
或者是${}
的形式,利用我們自定義的key
來進行取用呢?
這就需要通過@Param
來實現(xiàn)。
可以通過@Param
注解標識mapper
接口中的方法參數(shù)。此時,會將這些參數(shù)放在map
集合中,以@Param
注解的value
屬性值為鍵,以參數(shù)為值;
以 param1,param2...
為鍵,以參數(shù)為值;
只需要通過${}
和#{}
訪問map
集合的鍵就可以獲取相對應的值, 注意${}
需要手動加單引號。
public interface ParameterMapper { /** * 驗證登錄 (使用@Param) */ User checkLoginByParam(@Param("username") String username, @Param("password") String password); }
對應的mapper.xml
配置:
<!-- 以@Param的值為鍵,參數(shù)為值; 或以"param1"/"param2"為鍵,參數(shù)為值--> <!-- User checkLoginByParam(@Param("username") String username, @Param("password") String password);--> <select id="checkLoginByParam" resultType="User"> select * from t_user where username = #{username} and password = #{password} </select>
測試類:
/** * 情況5:使用@Param注解來命名參數(shù) * 此時MyBatis會將這些參數(shù)放在一個map集合中,以兩種方式進行存儲 * a》以@Param的值為鍵,參數(shù)為值; @Param(value = "xxx") * b》以param0,param1...為鍵,參數(shù)為值 */ @Test public void testCheckLoginByParam(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = mapper.checkLoginByParam("fangshaolei","123456"); System.out.println(user); }
四,總結(jié)
以上就是一文搞懂Mybatis中Mapper配置文件獲取參數(shù)的五種方式的詳細內(nèi)容,更多關(guān)于Mybatis Mapper獲取參數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
- Mybatis之mapper接口多參數(shù)方式
- Mybatis往Mapper.xml文件中傳遞多個參數(shù)問題
- MyBatis在mapper中傳遞參數(shù)的四種方式
- Mybatis中關(guān)于自定義mapper.xml時,參數(shù)傳遞的方式及寫法
- MyBatis在Mapper中傳遞多個參數(shù)的四種方法詳解
- Mybatis?Mapper中多參數(shù)方法不使用@param注解報錯的解決
- mybatis?mapper.xml?注釋帶參數(shù)的坑及解決
- MyBatis Mapper接受參數(shù)的四種方式代碼解析
- 解決Mybatis?mappe同時傳遞?List?和其他參數(shù)報錯的問題
相關(guān)文章
vscode開發(fā)maven的javaweb項目并部署到tomcat及配置指南
這篇文章主要給大家介紹了關(guān)于vscode開發(fā)maven的javaweb項目并部署到tomcat及配置的相關(guān)資料,在vscode中創(chuàng)建maven項目,需要逐一操作下面的環(huán)節(jié),文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-12-12Mybatis collection查詢集合屬性報錯的解決方案
這篇文章主要介紹了Mybatis collection查詢集合屬性報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09