MyBatis学习-(三)参数

本文最后更新于:December 27, 2021 am

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

目录

MyBatis 中文文档:https://mybatis.org/mybatis-3/zh/index.html

从 java 代码中把数据传入到 mapper 文件的 SQL 语句中。

1. parameterType

是写在 mapper 文件中的一个属性。表示 dao 接口中方法的参数的数据类型。

示例:
在 StudentDao 接口中

1
public Student selectStudentById(Integer id);

在 StudentDao.xml 配置文件中

1
2
3
<select id="selectStudentById" parameterType="java.lang.Integer" resultType="com.loong.test.USER">
select * from test where id =#{id};
</select>

其中,parameterType 是可以省略的。
parameterType:是 dao 接口中方法参数的数据类型。它的值是 java 的数据类型全限定名称(java.lang.Integer),或者是 mybatis 定义的别名。parameterType 不说强制的,mybatis 通过反射机制能够发现接口参数的类型。所以可以不写,但一般也不写。

MyBatis 定义的别名表:

  1. 基本类型
类型 别名
int _int
int _integer
short _short
double _double
byte _byte
long _long
float _float
boolean _boolean
  1. 包装类型
类型 别名
String string
Long long
Integer int
Integer integer
Double double
Boolean boolean
Object object
List list
Map map
Iterator iterator
Byte byte
Short short
Float float
Date date
Collection collection
ArrayList arraylist
HashMap hashmap
数组 array

2.一个类型参数

mybatis 把 java 的基本数据类型和 String 都叫简单类型。在 mapper 文件中获取简单类型的一个参数的值,用#{任意字符名称},它叫做占位符

如:

1
2
3
4
<select id="selectStudentById" parameterType="java.lang.Integer" resultType="com.loong.test.USER">
select * from test where id =#{userid};
<!-- 这里的 userid 就是任意的字符名称 -->
</select>

使用 #{} 之后, mybatis 执行 SQL 是使用的 JDBC 中的 PreparedStatement 对象。

3. 多个类型参数-命名参数(@Param)

当 Dao 接口方法多个参数,需要通过名称使用参数。在方法形参前面加入 @Param("自定义参数名")mapper 文件使用 #{自定义参数名}
示例:
接口中

1
public List<Student> selectParm(@Param("myname") String name,@Param("myage") Integer age)

mapper 文件中

1
2
3
<select>
select * from student where name = #{myname} or age = #{myage}
</seletct>

在 mapper 文件中的 mynamemyage 对应的就是在接口中的 mynamemyage

具体示例:

1
2
3
4
5
6
7
/*接口文件*/
List<Student> selectParm(@Param("myname") String name,@Param("myage") Integer age);
/*mapper文件*/
<select id="selectParm" resultType="com.xxx.xxx.Student">
select * from student where name = #{myname} or age = #{myage};
</select>

4. 多个类型参数-使用对象

使用 java 对象传递参数,java 的属性值就是 SQL 需要的参数值。每一个属性就是一个参数。语法格式:#{属性名,javaType=java 中数据类型名,jdbcType=数据库中数据类型名} ,例如:#{parname,javaType=java.lang.String,jdbcType=VARCHAR}。

示例:
类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ew {
private String parname;
private Integer parage;

public String getParname() {
return parname;
}

public void setParname(String parname) {
this.parname = parname;
}

public Integer getParage() {
return parage;
}

public void setParage(Integer parage) {
this.parage = parage;
}
}

mapper 文件

1
2
3
4
5
<select id="Dao中的方法名" resultType="com.xxx.xxx.Student">
select * from student where
name = #{parname,javaType=java.lang.String,jdbcType=VARCHAR}
or age = #{parage,javaType=java.lang.Integer,jdbcType=INTEGER}
</select>

其中,parnameparage 是类中属性的名称。

这是标准的写法,但是太繁琐了。简化格式为:#{属性名} ,而 javaType,和 jdbcType的值mybatis反射能获取。

所以,简化为:

1
2
3
<select id="Dao中的方法名" resultType="com.xxx.xxx.Student">
select * from student where name = #{parname} or age = #{parage}
</select>

5. 多个参数-按位置(了解)

参数位置从 0 开始,引用参数语法 #{arg位置编号},第一个参数是 #{arg0},第二个是 #{arg1} 。但是,在 mybatis-3.3 及其之前的版本使用 #{0},#{1}的方式,从 mybatis3.4 开始才是使用的 #{arg0} 的方式。

示例:
接口

1
List<Student> se(String name,int age);

mapper 文件

1
2
3
<select id="se">
select * from student where name = #{arg0} or age = #{arg1}
</select>

6. 多个参数-使用Map(了解)

Map 集合可以存储多个值,使用 Map 向 mapper 文件一次传入多个参数。Map 集合使用 String 的 key,Object 类型的值存储参数。mapper 文件使用 #{key} 引用参数值。

示例:
接口

1
2
3
4
5
6
7
8
List<Student> se(Map<String,Object> map);

/**
Map<String,Object> data = new HashMap<String,Object>();
data.put("myname","lise");
data.put("myage",23);

*/

mapper 文件

1
2
3
<select>
select * from student where name = #{myname} or age = #{myage};
</select>

7. # 和 $ 的区别

7.1 占位符(#)

#:是告诉mybatis使用实际的参数值代替。并使用 PrepareStatement 对象执行 SQL 语句,#{····} 代替 SQL
语句的 "?" ,这样可以防止SQL注入,更加安全,更迅速,通常也是首选做法。

7.2 字符串替换($)

$:告诉mybatis使用 $ 包含的 “字符串”替换所在位置。使用Statement 把 SQL 语句和 ${} 的内容连接起来。主要用在替换表名,列名,不同列排序等操作。

理解:

1
2
3
4
5
6
7
8
/* studentid=1001 */

/* #的运行结果 */
select * from student where id=#{studentid}
select * from student where id=?
/* $的运行结果 */
select * from student where id=${studentid}
select * from student where id=1001

总结

从 java 代码中把实际的值传入到 mapper 文件中。

  1. 一个简单类型的参数,使用: #{任意字符}
  1. 多个简单类型的参数,使用: @Param("自定义名称")
  1. 使用一个 java 对象,对象的属性值作为 mapper 文件找到参数: #{java 对象的属性名称}
  1. 使用参数的位置,语法:#{arg0}#{arg1} ,mybatis3.4 之前的版本,使用的 #{0}、#{1} 。
  1. 使用 Map 作为参数: #{map的key}

# 和 $ 的区别

  1. # 是占位符,表示列值的,放在等号右侧。
  1. $ 是占位符,表示字符串的连接,把 SQL 语句连接成一个字符串。
  1. # 占位符使用的 JDBC 指定 PreparedStatement 对象执行 SQL 语句,效率高,没有 SQL 注入的风险。
  1. $ 使用的是 Statement 对象执行 SQL,效率低,有 SQL注入风险。