Mybatis获取sql参数的两种方式:${ }和#{ }

440 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天

Mybatis获取sql参数的两种方式:${ }和#{ }

我们在映射文件中的mapper标签里会配置对应的数据库操作语句,在学习中我们使用的是固定语句,例如:

select * from mytable where id=1;

这里的id固定为1,但在实际开发中,我们并不确定用户输入的参数,所以我们需要在执行语句时进行参数获取操作。

在定义接口中的方法时,就需要定义好需要传入的参数👇

User getUserById(int id);

接下来我们看如何将传入的id替换至sql语句中:

Mybatis中替换参数有两种方式,一种是字符串拼接(${ }),一种是占位符赋值(#{ })

字符串拼接(${ })

字符串拼接类似于:

"select * from mytable where id=" + param + ";"//param是拼接的内容

使用${ },程序会将参数内容直接拼接进执行代码中:

select * from mytable where id=${param};
//这样,当我们执行查询操作时,id参数会自动传入param内,在只有一个参数时,param可以任意取名,可以是id,也可以不是id,但我们一般习惯性取与方法中参数同名
//假设param的参数值为1,就相当于执行了如下查询👇
select * from mytable where id=1;
​
//如果查询的内容为字符串,则要注意拼接时加上单引号
select * from mytable where username=${param};
//假设param的参数值为'hexiaoxing',这里没有加单引号,则相当于执行如下查询👇
select * from mytable where username=hexiaoxing;//这里会因为没有加单引号报错//正确的应该这样写
select * from mytable where username='${param}';

占位符赋值(#{ })

占位符赋值与字符串拼接最明显的区别就是:没有单引号问题,可以直接传入,相当于占位符可以判断数据类型,做出相应的传入。

相比于字符串拼接,占位符赋值减少了SQL注入的风险。因此,占位符赋值方式是首选

获取参数值的各种情况

  1. mapper接口方法的参数为单个的字面量类型:可以通过{}和#{}以任意的名称获取参数值,但是需要注意{}的单引号问题

  2. mapper接口方法的参数为多个时,此时Mybatis会将这些参数放在一个map集合中,以两种方式进行存储

    [arg0, arg1, ..., param1, param2, ...]
    //通过arg和param均可获取参数,arg0和param1对应第一个参数,arg1和param2对应第二个参数,以此类推
    

    然后我们就可以通过#{param1}或${arg0}等方式获取参数

  3. 若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储:与第二种情况类似,只是map键为自定义设置的,通过自定义的键来获取参数

  4. mapper接口方法的参数是pojo实例,我们就可以通过实例中的属性来获取参数(底层是通过构造函数来进行传值,需要有getter和setter,如果没有,且成员变量为private,就会导致取不到值的情况)

  5. 通过@param注解定义参数:

    //接口方法中
    User checkLoginByParam(@Param("username") String username, @Param("password") String password);
    

    这样通过@Param定义参数,就可以将参数以map形式传入,键为@Param内定义的值,就相当于第二种和第三种方式的结合,param定义的参数替换了第二种形式里的arg,但param1、2仍然可用