Mybatis基金会: #{...} 和 ${...} 差额

MyBatis将 #{…} 解释为JDBC prepared statement 参数标记。而将 ${…} 解释为一个字符串替换。非常实用的, 由于在某些SQL语句中并不能使用參数标记(parameter markers)。

比方,我们不能在表名(table name)的位置使用參数标记。
如果有以下的代码:

Map<String, Object> parms = new HashMap<String, Object>();
parms.put("table", "foo"); // 表名
parms.put("criteria", 37); // 查询过滤条件
List<Object> rows = mapper.generalSelect(parms);
<select id="generalSelect" parameterType="map">
select * from ${table} where col1 = #{criteria}
</select>

MyBatis生成的SQL语句(prepared statement)例如以下所看到的:

select * from foo where col1 = ?

重要提示: 请注意,使用$ {…} (字符串替换)时可能会有SQL注入攻击的风险。

另外,字符串替换在处理复杂类型也可能经常发生故障,如日期类型。由于这些因素,我们建议您尽可能地使用 #{…} 这样的方式。

要使用LIKE语句该怎么写?

有两种使用LIKE的方法。(推荐使用)第一种方法是,在Java代码中加入SQL通配符。

演示样例一:

String wildcardName = "%Smi%";
List<Name> names = mapper.selectLike(wildcardName);
<select id="selectLike">
select * from foo where bar like #{value}
</select>

另外一种方式是在SQL语句中拼接通配符。

这样的方法相对来说安全性要低一些,由于可能会被SQL注入攻击。
演示样例二:

String wildcardName = "Smi";
List<Name> names = mapper.selectLike(wildcardName);
<select id="selectLike">
select * from foo where bar like '%' || '${value}' || '%'
</select>

重要提示: 请注意两种方式中 $# 的使用!

怎样运行批量插入?

首先,创建一个简单的insert语句:

<insert id="insertName">
insert into names (name) values (#{value})
</insert>

然后在Java代码中像以下这样运行批处理插入:

List<String> names = new ArrayList<String>();
names.add("Fred");
names.add("Barney");
names.add("Betty");
names.add("Wilma"); // 注意这里 ExecutorType.BATCH
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
NameMapper mapper = sqlSession.getMapper(NameMapper.class);
for (String name : names) {
mapper.insertName(name);
}
sqlSession.commit();
} finally {
sqlSession.close();
}

怎样获取自己主动生成的(主)键值?

insert 方法总是返回一个int值 - 这个值代表的是插入的行数。而自己主动生成的键值在 insert 方法运行完后能够被设置到传入的參数对象中。
演示样例:

<insert id="insertName" useGeneratedKeys="true" keyProperty="id">
insert into names (name) values (#{name})
</insert>
Name name = new Name();
name.setName("Fred"); int rows = mapper.insertName(name);
// 完毕后,id已经被设置到对象中
System.out.println("rows inserted = " + rows);
System.out.println("generated key value = " + name.getId());

在mapper中怎样传递多个參数?

Java的反射机制并不能让框架获取到參数的名字(方法签名中仅仅有參数类型,能够说是为了优化,也能够说设计就是如此,总之名字无意义), 所以MyBatis默认的命名为: param1,param2……
如果想给他们指定名称,能够使用 @param 注解:

import org.apache.ibatis.annotations.Param;
public interface UserMapper {
User selectUser(@Param("username") String username,
@Param("hashedPassword") String hashedPassword);
}

然后,就能够在xml像以下这样使用(推荐封装为一个Map,作为单个參数传递给Mapper):

<select id=”selectUser” resultType=”User”>
select id, username, hashedPassword
from some_table
where username = #{username}
and hashedPassword = #{hashedPassword}
</select>

原文链接: What is the difference between #{...} and ${...}?

原始日期: 2013-11-10
翻译日期: 2014-09-28
翻译者: 锚的

Mybatis基金会: 经常问的问题FAQ的更多相关文章

  1. Mybatis经常被问到的面试题

    1. #{}和${}的区别是什么? #{}是预编译处理,${}是字符串替换. Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值: ...

  2. 整合最优雅SSM框架:SpringMVC + Spring + MyBatis

    我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...

  3. 最优雅SSM框架:SpringMVC + Spring + MyBatis

    在写代码之前我们先了解一下这三个框架分别是干什么的? 相信大以前也看过不少这些概念,我这就用大白话来讲,如果之前有了解过可以跳过这一大段,直接看代码! SpringMVC:它用于web层,相当于con ...

  4. 手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis

    在写代码之前我们先了解一下这三个框架分别是干什么的? 相信大以前也看过不少这些概念,我这就用大白话来讲,如果之前有了解过可以跳过这一大段,直接看代码! SpringMVC:它用于web层,相当于con ...

  5. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)

    1. 前言 最近在写毕设过程中,重新梳理了一遍SSM框架,特此记录一下. 附上源码:https://gitee.com/niceyoo/jeenotes-ssm 2. 概述 在写代码之前我们先了解一下 ...

  6. 整合最优雅SSM框架:SpringMVC + Spring + MyBatis 基础

    在写代码之前我们先了解一下这三个框架分别是干什么的? 相信大以前也看过不少这些概念,我这就用大白话来讲,如果之前有了解过可以跳过这一大段,直接看代码! SpringMVC:它用于web层,相当于con ...

  7. 一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程重要

    前言 SSM(Spring+SpringMVC+Mybatis)是目前较为主流的企业级架构方案,不知道大家有没有留意,在我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教 ...

  8. PHP连接sql server 2005环境配置

    一.Windows下PHP连接SQLServer 2005 设定:安装的Windows操作系统(Win7 或XP均可.其它系统暂未測试),在C盘下:PHP的相关文件位于c:/PHP以下,其配置文件ph ...

  9. 手把手教你 基础 整合最优雅SSM框架:SpringMVC + Spring

    我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...

随机推荐

  1. 辛格尔顿和Android

    辛格尔顿(Singleton) .singleton.h,定义类的基本成员及接口 #ifndef SINGLETON_H_INCLUDE #define SINGLETON_H_INCLUDE cla ...

  2. POJ 2250 Compromise (UVA 531)

    LCS问题.基金会DP. 我很伤心WA非常多.就在LCS问题,需要记录什么路. 反正自己的纪录path错误,最后,就容易上当. 没有优化,二维阵列,递归打印,cin.eof() 来识别 end of ...

  3. bootstrap的popover在trigger设置为hover时不隐藏popover

    使用bootstrap的popover,trigger设置为hover时,可以实现当鼠标放置到目标元素上时显示popover,可是无法实现当鼠标移动到popover上时不隐藏popover,在网上找了 ...

  4. 部署Win Server 2012十项注意

    博文来自 http://server.zol.com.cn/351/3511746.html Windows Server 2012是微软公司在2012年推出的面向中小企业应用一款全新的服务器操作系统 ...

  5. ios-上拉电阻负载许多其他接口

    想尝试拉加载意识到有多少开始了他的研究之旅,我看了两天做出最终的界面. 之所以这么慢是由于,我不知道要将上拉出现的view放在哪.就能在scrollView拉究竟部的时候被拉出来.还有就是怎么拉出来之 ...

  6. dm8148 jpeg编解码器测试

    测试过程: 1)于A8将jpeg传送到videoM3解码,然后,videoM3编码.在编译jpeg图像传输到A8,主要是测试jpeg编码的图像需要多少时间: 1000w像素:  编码时间:43ms. ...

  7. 新浪微博id的62进制转换

    某条微博链接 某条微博的链接如下,同样省略了后面的无关参数 http://weibo.com/2803301701/CeaOU15IT CeaOU15IT为这条微博的mid,与之相对应的还有一个id, ...

  8. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  9. 【PHP】PHP获得第一章

    一,PHP上部和下部壳体敏感 1)所有的用户定义的函数.类和keyword敏感. 例如以下结果输出一致: echo  "hello world" Echo  "hello ...

  10. Java线(一个):线程安全的和不安全

    当我们看JDK API什么时候,总是找一些类描述说:,线程安全或线程安全,例如StringBuilder在,么一句,"将StringBuilder 的实例用于多个线程是不安全的.假设须要这种 ...