12. Mybatis 参数引用-${}与#{}的差异

Mybatis sql 映射文件中, 可以通过#{} 或 KaTeX parse error: Expected 'EOF', got '#' at position 34: …参数. 通常情况下, 优先使用#̲{}, 对于#{} 不能解决的…{}.

1. ${} 与 #{} 的区别

  • #{} 采用的是预编译sql, 使用的是JDBC的PrepareStatment, 可防止sql注入. 但是占位符只能在sql的where,set 之后出现.
  • ${} 采用的是字符串替换, 直接将变量内容替换成字符串,拼接成sql, 可在sql的任何位置出现
  • ${} 不支持位置参数, 只能通过@param 指定参数名称或直接从javaBean 中获取属性值.

1.1 sql 映射文件

编写sql文件时, 分别使用${} 和 #{} 各引用一个变量, 并观察Mybatis的日志输出.

<!-- 通过id 查询实体  -->
<select id="findById" resultType="UserPO">
    select * from t_user_${createYear} where id = #{id}
</select>

1.2 mapper 方法签名

由于是多个参数, 所以需要采用命名方式传参.

UserPO findById(@Param("id") Integer id, @Param("createYear") String createYear);

1.3 测试

@Test
public void test_find(){
    UserMapper userMapper = SqlSessionFactoryUtil.getMapper(UserMapper.class);
    UserPO userPO = userMapper.findById(1, "2018");
    System.out.println(userPO);
}

1.4 日志输出

从日志打印的sql拼接结果来看, ${createYear} 直接替换成了2018, 而#{id} 则是采用sql预编译的方式, 以占位符? 代替.

2019-05-27 15:20:57:411][main][DEBUG][o.z.l.m.l.mapper.UserMapper.findById]- ==>  Preparing: select * from t_user_2018 where id = ? 
[2019-05-27 15:20:57:450][main][DEBUG][o.z.l.m.l.mapper.UserMapper.findById]- ==> Parameters: 1(Integer)
[2019-05-27 15:20:57:476][main][DEBUG][o.z.l.m.l.mapper.UserMapper.findById]- <==      Total: 1

2. ${} 的应用举例

由于#{}只能出现在sql语句中的where, set, values 等位置, 所以对于数据库分表, 动态排序等均无法很好的支持, 只能通过复杂的动态SQL方式来实现.

2.1 动态表名

<insert id="save" useGeneratedKeys="true" keyProperty="id">
    insert into t_user_${createYear}  values (null , #{username}, #{password}, #{createYear})
</insert>

2.2 动态排序

<select id="queryAll" resultType="UserPO">
    select * from t_user_${createYear} order by id ${orderType}
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值