专注Java领域技术
我们一直在努力

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

原文始发于: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> 

赞(0) 打赏
未经允许不得转载:Java小咖秀 » 12. Mybatis 参数引用-${}与#{}的差异
免责声明

抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专注Java技术 100年

联系我们联系我们

你默默的关注就是最好的打赏~

支付宝扫一扫打赏

微信扫一扫打赏