原文:https://blog.csdn.net/mrqiang9001/article/details/79520436
關於Mybatis的@Param注解
Mybatis 作為一個輕量級的數據持久化框架,目前(2018)的應用非常廣泛,基本可以取代Hibernate。關於 @param 這個注解的使用,作者這里整理了一些筆記。
關於Mybatis @Param 注解,官方文檔: http://www.mybatis.org/mybatis-3/zh/java-api.html
其中關於 @param部分的說明是:
@Param Parameter N/A 如果你的映射器的方法需要多個參數, 這個注解可以被應用於映射器的方法 參數來給每個參數一個名字。否則,多 參數將會以它們的順序位置來被命名 (不包括任何 RowBounds 參數) 比如。 #{param1} , #{param2} 等 , 這 是 默 認 的 。 使 用 @Param(“person”),參數應該被命名為 #{person}。
也就是說如果有多個參數的時候,可以使用@Param 這個注解,但是不是一定需要用到 @Param 這個注解呢?作者在這里列出以下幾種情景
1.傳遞單個參數,不使用 @Param 注解
代碼如下:
DAO 層 CommodityDao.java
package com.ljq.cs.dao;
/**
* @description: 商品信息 DAO 接口
* @author: lujunqiang
* @email: flying9001@gmail.com
* @date: 2017/12/17
*/
@Repository
public interface CommodityDao {
// 查詢某一件商品
Commodity queryOne(Commodity commodity);
// 省略其他方法
}
Mapper 文件: commoditymapper.xml
<?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="com.ljq.cs.dao.CommodityDao" >
<select id="queryOne" resultType="Commodity">
select *
from t_commodity com
where id = #{id}
</select>
</mapper>
這里只有一個參數,java 接口不使用 @Param 注解,同時 mapper 文件也不需要使用 parameterType 這個參數,Mybatis會 根據實體類(entity)的類型自動識別並匹配javaBean(這一部分在 spring配置文件關於數據源那一部分)
2.傳遞單個參數,使用@Param注解
代碼如下:
DAO 層 CommodityDao.java
package com.ljq.cs.dao;
/**
* @description: 商品信息 DAO 接口
* @author: lujunqiang
* @email: flying9001@gmail.com
* @date: 2017/12/17
*/
@Repository
public interface CommodityDao {
// 查詢某一件商品
Commodity queryOne(@Param("commodity")Commodity commodity);
// 省略其他方法
}
Mapper 文件: commoditymapper.xml
<?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="com.ljq.cs.dao.CommodityDao" >
<select id="queryOne" parameterType="com.ljq.cs.entity.Commodity" resultType="Commodity">
select *
from t_commodity com
where id = #{commodity.id}
</select>
</mapper>
當使用javaBean作為對象的時候,在寫 SQL 語句的時候,必須指定參數類型 parameterType="com.ljq.cs.entity.Commodity"
,同時在 #{ }
取值的時候不能直接填入 javaBean
的屬性,必須這樣使用 commodity.id
;否則,會拋出參數類型不匹配異常
如果不是 javaBean
,則需要在寫 SQL 語句的時候, #{ }
中的屬性必須與 @Param中定義的一致,eg: @Param("username")
, #{username}
,這樣才可以
3.傳遞多個參數,使用 @Param 注解
為了精簡代碼,作者這里只寫關鍵部分
DAO 層, UserInfoDao.java
// 用戶登錄
UserInfo signin(@Param("account")String account,@Param("passcode")String passcode);
mapper文件userInfomapper.xml
<!-- 用戶登錄 -->
<select id="signin" resultType="UserInfo">
select *
from t_userinfo info
where account=#{account} and passcode=#{passcode}
</select>
這里 @Param 中定義的變量名必須和 mapper 中保持一致才可以
4.傳遞多個參數,不使用 @Param 注解
其實從第一種場景中已經可以實現傳遞多個參數了,即把多個參數封裝到一個 javaBean
中就可以實現了,但是如果是兩個或者多個 javaBean
的時候,可以通過使用@Param注解的方式來實現,但是需要把每個 javaBean
中的屬性全部拆分出來,這樣就增加了巨大的代碼量,因此不推薦這么做
那么有沒有可以不使用@Param注解,同樣也可以傳遞多個參數(尤其是多個 javaBean
)呢?答案是有的,廢話不多說,直接上代碼
同上,這里只貼出關鍵部分
DAO 層, UserInfoDao.java
// 搜索用戶,對結果進行分頁
List searchUser(Map<String,Object>);
使用DAO,UserService.java
UserInfo userInfo = new UserInfo();
Pagination page = new Pagination();
Map<String,Object> map = new HashMap<>;
map.put("userInfo",userInfo);
pam.put("page",page);
userService.searchUser(map);
mapper文件userInfomapper.xml
<select id="searchUser" parameterType="java.util.Map" resultType="UserInfo">
select *
from t_userinfo user
where 1 =1
<if test="user.uname != null and ''!= user.uname ">
and user.uname like '%${userInfo.uname}$%'
</if>
<if test="page.order != null and page.order == 10" >
order by user.id asc
</if>
limit ${page.pagenum * page.limitnum}, #{page.limitnum}
</select>
作者通過上邊的4種情況,主要是為了說明,Mybatis無論是傳單個參數,還是傳遞多個參數,沒有必要使用@Param注解啊
使用@param 注解增添了不少代碼不說,還容易導致錯誤,尤其是在 mapper 文件中(paraterType
屬性)
以上只是作者的列舉的部分代碼,源碼請看這里: https://github.com/Flying9001/campustore