映射文件中SQL获取参数值的多种情况

在JDBC操作时,我们面对SQL语句中未知的量时,一是用String字符串拼接出SQL语句,交给statement对象处理,二是用?作为SQL语句的占位符,再通过PrepareStatement的各种set方法把值注入到SQL语句中。

在mybatis中SQL获取参数方式也分两种:${}(本质就是字符拼接),#{}(本质就是占位符赋值)。理论上来说,为了防止SQL注入,我们通常都应该选择使用#{}来作为占位符。但还是不同情况不同对待:

一、mapper接口方法的参数为单个的简单类型(8个基本类型+String)

Emp selectEmpById(int id);

可以通过#{任意值}(建议与参数名称一致),例如:

 

<select id="selectEmpById" resultType="pojo.Emp">
select * from employeeinfo where eid=#{aaa}
</select>

 

或${value},其中标识符必须为value,并且需要注意单引号问题(因为是字符串拼接),如:

 

<select id="selectEmpByName" resultType="pojo.Emp" parameterType="java.lang.String">
select * from employeeinfo where ename = '${value}'
</select>

 

二、Mapper接口方法的参数为多个时

Emp selectEmpByIdAndName(Integer id,String name);

我们可不可以采用参数名对应的方式来获取对应的值?

<select id="selectEmpByIdAndName" resultType="pojo.Emp">
select * from employeeinfo where eid = #{id} and ename = #{name}
</select>

答案是不可以:

org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [0, 1, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [0, 1, param1, param2]

错误报告可以看出,当我们有多个参数时,mybatis会将这些参数放在一个map集合 [0, 1, param1, param2]中,以两种方式进行存储:

a>以0,1..为键,以参数为值(不同版本的mybatis可能是 [arg0, arg1, param1, param2])

b>以param1,param2..为键,以参数为值

因此我们只需要通过#{键}或${键}的方式就可以访问到值

 

<select id="selectEmpByIdAndName" resultType="pojo.Emp">
select * from employeeinfo where eid = #{0} and ename = #{1}
</select>

 

三、Mapper接口方法的参数为多个时,也可手动将参数放在一个自定义map中存储

我们需要数据的时候就可以通过自定义的键值对来获取:

Emp selectEmpByMap(Map<String,Object> map);

 

<select id="selectEmpByMap" resultType="pojo.Emp">
select * from employeeinfo where eid = #{id} and ename = #{name}
</select>
@Test
public void selectEmpByMap() throws IOException {
SqlSession session = this.getConn();
UserMapper mapper = session.getMapper(UserMapper.class);
//自定义键值对
Map<String,Object> map = new HashMap<>();
map.put("id",1);
map.put("name","曹卫东");
Emp emp = mapper.selectEmpByMap(map);
System.out.println(emp);
}

 

四、mapper接口方法的参数是实体类对象

只需要通过#{属性名}或${属性名}的方式就能访问对应值

int insertEmp(Emp emp);
<insert id="insertEmp" parameterType="pojo.Emp">
insert into employeeinfo values (DEFAULT,#{ename},#{gender},#{age},#{dept})
</insert>

五、使用@Param注解命名参数

 

Emp selectEmpByParam(@Param("eid") Integer id,@Param("ename") String name);
@Param("eid")等同于@Param( value = "eid")

 

这种方式可以理解为起别名,此时mybatis会将参数放在一个map集合中,以两种方式进行存储:

因此在SQL中我们只需要通过#{}或${}中写键的方式访问值即可

a>以@Param注解的值为键,以参数为值

 

<select id="selectEmpByParam" resultType="pojo.Emp">
select * from employeeinfo where eid = #{eid} and ename = #{ename}
</select>

 

b>以param1,param2为键,以参数为值

 

<select id="selectEmpByParam" resultType="pojo.Emp">
select * from employeeinfo where eid = #{param1} and ename = #{param2}
</select>

 

实际开发中,建议分为两种情况,一种是参数是实体类的情况,按照四来处理,其余情况的参数全都使用@Param注解来起别名,这样可以规范代码

 

 

 

 

 

 

 

 

 

 


posted @ 2023-08-22 23:21  去公司搞点薯条  阅读(91)  评论(0)    收藏  举报