Mybatis基础: 常见问题与FAQ

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
翻译人员: 铁锚

时间: 2024-10-17 22:42:00

Mybatis基础: 常见问题与FAQ的相关文章

mybatis基础(二)

上接mybatis基础(二) 开发规范: 1.在mapper.xml中namespace等于mapper接口地址 2.mapper.java接口中的方法名和mapper.xml中statement的id一致 3.mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致. 4.mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致. 9.properties

FusionCharts导出图表常见问题(FAQ)汇总---FusionCharts常见问题大全

在前面几篇文章中,我们介绍了FusionCharts生成Flash图表常见问题FAQ以及使用中的一些常见报错及调试/解决方法.本文继续介绍FusionCharts导出图表时的一些常见问题(FAQ). 问题描述:我尝试使用Download Package > Code > ExportChartSamples中导出FusionCharts图表时,到最后一步的时候总是报错? 解决方法:在运行下载包中的示例时,你需要进行下列安装步骤: 当运行服务器端示例时,确定你已把相关导出处理程序 (服务器端)

MyBatis基础入门《五》核心配置文件

MyBatis基础入门<五>核心配置文件 描述: 在前面的章节中,简单的学习使用了一下mybatis,对于配置文件没有过多详细说明. 这里先描述项目中的一个核心配置文件:mybatis-config.xml 文件. 资料参考:http://www.mybatis.org/mybatis-3/ 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUB

MyBatis基础入门《七》查询参数传入对象

MyBatis基础入门<七>查询参数传入对象 描述: 在执行查询语句的时候,传入的参数是一个对象,依据对象的属性,进行检索数据.此时,书写SQL语句中的条件时,其参数需要和对象中的属性保持一致. 实体类:TblClient.java 接口方法 注意: 接口中定义了一个新的方法(根据对象属性进行查询数据),方法的参数传入的是一个对象. xml文件 注意: >>> parameterType="baitang" resultType="baitang

MyBatis基础入门《十五》ResultMap子元素(collection)

MyBatis基础入门<十五>ResultMap子元素(collection) 描述: 见<MyBatis基础入门<十四>ResultMap子元素(association )> >>collection >> 复杂类型集合,一对多 >> 内部嵌套 > 映射一个嵌套结果集到一个列表 >> 属性 > property : 映射数据库列的实体对象的属性 > ofType : 完整java类名或别名(集合所包括的

MyBatis基础入门《十七》动态SQL

MyBatis基础入门<十七>动态SQL 描述: >> 完成多条件查询等逻辑实现 >> 用于实现动态SQL的元素主要有: > if > trim > where > set > choose( when , otherwise ) > foreach 动态SQL为Mybatis重要部分,项目也重新新建了一个:mybatis-dynamic-sql 项目结构: TblClient.java 1 package com.charles.e

mybatis基础系列(一)&mdash;&mdash;mybatis入门

好久不发博客了,写博文的一个好处是能让心静来,整理下之前学习过的一些知识一起分享,大神路过~ mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.传统的 JDBC代码通常存在如下问题: 1. 频繁对数据库进行连接和关闭,造成资源浪费,性能下降. 2. SQL代码.preparedStatement参数.占位符号等硬编码到代码中,不方便维护. 3. 遍历结果集数据时,硬编码解析表字段成java属性,不方便维护. MyBatis 避免了几乎所有的

Mybatis基础(一)

mybatis概述: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型.接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录. 安装mybatis: 1.方式一:直接将mybatis-x.x.x.jar文件放置在classpath中,一般情况不用这种.

Mybatis基础入门(四)——与springMVC的集成

前面的增删改查还没有融入到一个web项目中,这里在前面的基础上,集成spring管理相关的bean,并在web层集成springmvc.同样会有源码的下载. 一.目录结构: 二.集成spring: 因为是一个web项目,且使用了spring作为粘合剂,相关的jar包就不多解释了,详见源码.项目上篇文章中的结构,这里把映射文件单独放到一个目录,而且添加了Controller的包,映射文件内容不变.注意到这里讲其他配置文件整合到了config包中.因为使用spring,所以Configuration