Mybatis之#{}与${}的区别

1.两种取值方式的差异

mapper.xml映射文件

<select id="selectEmployeeByCondition2" resultMap="empResultMap" databaseId="mysql">
        select * from t_emp WHERE emp_id=${id} and emp_name=#{name}
    </select>

java查询代码 params 为 id=1 ,name=”小红”

@Test
    public void testSelect() {
        InputStream resourceAsStream = ConfigTest.class.getResourceAsStream("../classes/mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmployeeMapper mapper2 = sqlSession.getMapper(EmployeeMapper.class);

        Employee employee2 = mapper2.selectEmployeeByCondition2(1,"xiaohong");
        System.out.println(employee2);
    }

结果

==>  Preparing: select * from t_emp WHERE emp_id=1 and emp_name=? 
==> Parameters: xiaohong(String)
<==    Columns: emp_id, emp_name, emp_email, emp_tel, emp_dep, emp_status
<==        Row: 1, xiaohong , 123@qq.com, 123, 1, 0
<==      Total: 1

1.1 #{}

从上述代码可以看出 #{} 在原生jdbc语句中会用 ?占位符来表示。这样做可以防止sql注入

1.2${}

从上述代码可以看出 ${} 是直接把param 拼到原生sql上

2.什么时候该使用什么方式

从上述示例可以看出 #{} 与${}的作用都是取值,同时#{}还可以防止sql注入更安全。是否表示在以后代码中就用#{}呢? 当然不是这样的,比如某电商系统的订单表数据量太庞大,不得以分表来保存数据。该电商的工程师最后决定将该表按年月进行分表(t_order_201701,t_order_201702…)。这个时候我们该采用那个中方式进行查询呢,如我要查询17年6月份的全部订单?
你可能想当然的认为这个容易,只要把年月动态传入到sql中就可以了如下:

<select id="selectOrderByCondition" resultMap="orderResultMap" databaseId="mysql">
        select * from t_order_#{createYM} WHERE  DATE_FORMAT(create_date,'%Y%m')=${createYM}+''
    </select>

结果

==>  Preparing: select * from from t_order_? WHERE DATE_FORMAT(create_date,'%Y%m')='201706'
==> Parameters: 201706(Integer)

很显然该语句是执行不了的,此时就要采用${}

<select id="selectOrderByCondition" resultMap="orderResultMap" databaseId="mysql">
        select * from t_order_${createYM} WHERE  DATE_FORMAT(create_date,'%Y%m')=${createYM}+''
    </select>

拼装的原生jdbcsql

==>  Preparing: select * from from t_order_201706 WHERE DATE_FORMAT(create_date,'%Y%m')='201706'
==> Parameters: 201706(Long)

很显然这条sql可以执行。

3.总结

3.1 #{} 与${}都是为了去变量的值

3.2在大多数的情况下是用#{}为了安全

3.3 在原生jdbc的sql 用占位符会出错的情况下用${}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值