映射文件中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注解来起别名,这样可以规范代码
浙公网安备 33010602011771号