1. 程式人生 > >MyBatis中的@Param註解和引數

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的屬性。