MyBatis中的@Param註解和引數
Mybatis 作為一個輕量級的資料持久化框架,目前應用非常廣泛,基本可以取代Hibernate。
關於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: [email protected]
* @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: [email protected]
* @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 屬性)
Public User selectUser(@param(“userName”) String name,@param(“userpassword”) String password);
xml對映檔案
<select id=" selectUser" resultMap="BaseResultMap">
select * from user_user_t
where user_name = #{userName,jdbcType=VARCHAR}
and user_password=#{userPassword,jdbcType=VARCHAR}
</select>
注意:採用#{}的方式把@Param註解括號內的引數進行引用(括號內參數對應的是形參如 userName對應的是name);
public List<user> getUserInformation(@Param("user") User user);
xml對映
<select id="getUserInformation" parameterType="com.github.demo.vo.User" resultMap="userMapper">
select
<include refid="User_Base_Column_List" />
from mo_user t where 1=1
<!-- 因為傳進來的是物件所以這樣寫是取不到值得 -->
<if test="user.userName!=null and user.userName!=''"> and t.user_name = #{user.userName} </if>
<if test="user.userAge!=null and user.userAge!=''"> and t.user_age = #{user.userAge} </if>
</select>
當你使用了使用@Param註解來宣告引數時,如果使用 #{} 或 ${} 的方式都可以。
當你不使用@Param註解來宣告引數時,必須使用使用 #{}方式。如果使用 ${} 的方式,會報錯。
2,不使用@Param註解
不使用@Param註解時,引數只能有一個,並且是Javabean。在SQL語句裡可以引用JavaBean的屬性,而且只能引用JavaBean的屬性。