MyBatis 中 @Param 注解的使用场景:多参数、$、动态SQL、取别名

第一种:方法有多个参数,需要 @Param 注解

例如下面这样:

@Mapper
public interface UserMapper {
    Integer insert(@Param("username") String username, @Param("address") String address);
}

对应的 XML 文件如下:

<insert id="insert" parameterType="org.javaboy.helloboot.bean.User">
    insert into user (username,address) values (#{username},#{address});
</insert>

这是最常见的需要添加 @Param 注解的场景。

 

第二种:方法参数要取别名,需要 @Param 注解

当需要给参数取一个别名的时候,我们也需要 @Param 注解,例如方法定义如下:

@Mapper
public interface UserMapper {
    User getUserByUsername(@Param("name") String username);
}

对应的 XML 定义如下:

<select id="getUserByUsername" parameterType="org.javaboy.helloboot.bean.User">
    select * from user where username=#{name};
</select>

老实说,这种需求不多,费事。

第三种:XML 中的 SQL 使用了 $ ,那么参数中也需要 @Param 注解

$ 会有注入漏洞的问题,但是有的时候你不得不使用 $ 符号,例如要传入列名或者表名的时候,这个时候必须要添加 @Param 注解,例如:

@Mapper
public interface UserMapper {
    List<User> getAllUsers(@Param("order_by")String order_by);
}

对应的 XML 定义如下:

<select id="getAllUsers" resultType="org.javaboy.helloboot.bean.User">
    select * from user
    <if test="order_by!=null and order_by!=''">
        order by ${order_by} desc
    </if>
</select>

前面这三种,都很容易懂,相信很多小伙伴也都懂,除了这三种常见的场景之外,还有一个特殊的场景,经常被人忽略。

 

第四种,那就是动态 SQL ,如果在动态 SQL 中使用了参数作为变量,那么也需要 @Param 注解,即使你只有一个参数。

如果我们在动态 SQL 中用到了 参数作为判断条件,那么也是一定要加 @Param 注解的,例如如下方法:

@Mapper
public interface UserMapper {
    List<User> getUserById(@Param("id")Integer id);
}

定义出来的 SQL 如下:

<select id="getUserById" resultType="org.javaboy.helloboot.bean.User">
    select * from user
    <if test="id!=null">
        where id=#{id}
    </if>
</select>

这种情况,即使只有一个参数,也需要添加 @Param 注解,而这种情况却经常被人忽略!

org.apache.ibatis.binding.BindingException: Parameter 'XXXX' not found.报错

首先,要明确一点的是,Dao层的抽象方法中的参数一般情况下默认的是一个参数或者一个对象;

1.

public interface StudentDao {
 
    int selectById(int id);
    
    int insert(Student stu);
    
}
这两种是正常的方式,不会出现什么问题,mappper中的对应取值都是用#{}这种方式;
例如:

<select id="selectById" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from student
        where 1=1 and id = #{id}
    </select>
<insert id="insert" parameterType="com.yoho.crm.dal.model.student"><!--注意参数的类型要与对象类对应,也就是这个类的路径-->
        insert into inbox_template (name,age)
        values (#{name},#{age})
    </insert>

上面如果是student对象作为参数,那么mapper中不能少了parameterType,否则会找不对应的属性

2、当传多个参数时,就容易出现问题了,问题重现,如果像下面那样写就会出现标题中的错误,找不到参数;

public interface StudentDao {
    int selectBySelective(int id,String name);
}


解决办法就是在每个参数前加上@param注解,括号中注解的名称就是mapper中映射的值,如下:
import org.apache.ibatis.annotations.Param;
 

public interface StudentDao {
    int selectBySelective(@Param("id")int id,@Param("name")String name);
}

//mapper中还是那样写,可以使用${}或者#{}任意一种方式:
<select id="selectBySelective" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from student
        where name = #{pname} and id = #{pid}
    </select>



3.既有参数又有对象时,对象也需要注解,一般参数的直接取,对象的需要对象.属性,如下:

public interface StudentDao {
    
    int selectBySelective(@Param("page")int page,@Param("stu")Student stu);
    
}

mapper:
    <select id="selectBySelective" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from student
        where name = #{stu.name} and id = #{stu.id} limit 0 ,#{page}
    </select>


4.像这种有公共的属性

 

例如分页都要传开始的index和pagesize,然后还要在传对象,就是3中的案例,可以为了方便管理,自己再新建一个类,里面封装了page的属性,同时又有对象,如下:
建一个page类:

public class Page {
    
    private int pageNo;
    
    private int pageSize;
    
    private Object obj;
    
    public Page(int page,int pageSize,Object obj){
        this.pageNo=page;
        this.pageSize=pageSize;
        this.obj=obj;
    }
 
    public int getPageNo() {
        return pageNo;
    }
 
    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }
 
    
    public int getPageSize() {
        return pageSize;
    }
 
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
 
    public Object getObj() {
        return obj;
    }
 
    public void setObj(Object obj) {
        this.obj = obj;
    }
    
    
}

在处理时直接new page对象中自己定义好的构造函数,然后直接把page作为参数传到dao:

Student stu = new Student();
        stu.setName("aa");
        stu.setId(1);
        stu.setAge(12);
        Page page = new Page(1, 10,stu);

dao:

public interface StudentDao {
 
    int update(Page page);
    
}

mapper:
<update id="update" parameterType="com.yoho.crm.dal.model.student"><!--此时obj则是对应page中的属性了-->
        update inbox_template
        set 
        name = #{obj.name},
        age = #{obj.age}
        where id = #{obj.id}
    </update>

 

转自:https://www.cnblogs.com/lenve/p/11229590.html

https://blog.csdn.net/qq_33142257/article/details/53202443 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值