target
掌握MyBatis的入参处理
掌握如何把select记录封装成map
掌握#{}和${}的区别
了解mybatis内置参数
1. 入参处理
1)单个参数
当映射接口传入一个参数给mybatis映射文件的时候,其实很好处理:只要在xml映射文件中用#{xx}
去接收就可以,xx可以是任意字符。
比如:要根据id查询某个用户信息。
UserMapper接口定义一个参数为INTEGER类型:
public interface UserMapper {
public User selectUserById(Integer id);//根据id查询用户
}
UserMapper.xml 中接收:
select * from user where uid = #{uid}
注意:不是必须用uid字符,随意字符都可以。
Junit测试:
@Test
public void testQuery() {
UserMapper userMapper = session.getMapper(UserMapper.class);
// 查询一个用户
User user = userMapper.selectUserById(1);
System.out.println(user);
// 提交事务
session.commit();
}
2)多个参数
在实际开发中,查询 SQL 语句经常需要多个参数,例如多条件查询。当传递多个参数时, 元素、
等的 parameterType 属性值的类型是什么呢?
① @Param
可以在映射接口的入参属性加@Param,用来和xml映射文件的参数进行匹配。
UserMapper.java接口:
public interface UserMapper {
public int updateUser(@Param("id")Integer uid,@Param("name")String uname,@Param("sex")String usex);//修改一个用户
}
UserMapper.xml可以直接接收匹配的字段:
update user set uname = #{name},usex = #{sex} where uid = #{id}
junit测试:
@Test
public void testUpdate() {
UserMapper userMapper = session.getMapper(UserMapper.class);
// 添加一个用户
int update = userMapper.updateUser(1,"张晓仨","男");
System.out.println("修改了" + update + "条数据!");
// 提交事务
session.commit();
}
② map
只需要把相应的字段和数据封装到map中,key就是映射文件中对应的字段名。
UserMapper.java
public interface UserMapper {
public int updateUser(Map map);//修改一个用户
}
UserMapper.xml:
update user set uname =#{name},usex = #{sex} where uid = #{id}
junit测试:
@Test
public void testUpdate() {
UserMapper userMapper = session.getMapper(UserMapper.class);
// User user = new User(1,"张晓仨","男");
// 添加一个用户
Map map = new HashMap();
map.put("id", 1);
map.put("name", "xiao张三");
map.put("sex", "女");
int update = userMapper.updateUser(map);
System.out.println("修改了" + update + "条数据!");
// 提交事务
session.commit();
}
③ TO/PO类
可以直接把pojo类当做参数进行传递,xml映射文件中用pojo类中的属性值去接收即可。
UserMapper.java
public interface UserMapper {
public int addUser(User user);//添加一个用户
}
UserMapper.xml
insert into user (uname,usex) values(#{uname},#{usex})
Junit测试:
@Test
public void testAdd() {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User(null,"李四","男");
// 添加一个用户
int add = userMapper.addUser(user );
System.out.println("添加了" + add + "条数据!");
// 提交事务
session.commit();
}
2. select记录封装map
1)单条记录封装
select查询到的记录,大多情况下会选择用pojo去封装,其实也可以用map进行封装。
UserMapper.java接口用的返回值类型为Map:
public interface UserMapper {
public Map selectUserById(Integer id);//根据id查询用户
}
UserMapper.xml的resultType为map:
select * from user where uid = #{id}
JUnit测试:
@Test
public void testQuery() {
UserMapper userMapper = session.getMapper(UserMapper.class);
// 查询一个用户
Map map = userMapper.selectUserById(1);
System.out.println(map);
}
2)多条记录封装
① list方式
多条记录封装在多个map中,然后将多个map封装在list中:
UserMapper.java 接口:
package com.mybatis.mapper;
public interface UserMapper {
public List
UserMapper.xml:
select * from user
Junit测试:
@Test
public void testQueryAll() {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 查询所有用户
List
输出:
[User [uid=1, uname=张三, usex=女], User [uid=2, uname=李晓四, usex=女], User [uid=4, uname=赵晓六, usex=男]]
② @MapKey()方式
多条记录封装到一个map中:Map,key是这条记录的键,value是这条记录的值。
UserMapper.java 接口:
public interface UserMapper {
//需要加@MapKey("uid")来指定主键,否则会封装成多个map
@MapKey("uid")
public Map selectAllUser();//查询所有
}
UserMapper.xml:注意resultType是模型对象
select * from user
Junit测试:
@Test
public void testQueryAll() {
UserMapper userMapper = session.getMapper(UserMapper.class);
// 查询所有用户
Map map = userMapper.selectAllUser();
System.out.println(map);
}
输出:
{1=User [uid=1, uname=张三, usex=女], 2=User [uid=2, uname=李晓四, usex=女], 4=User [uid=4, uname=赵晓六, usex=男]}
上面的例子用的id作为map的key,也可以使用其他属性作为key,比如uname:
public interface UserMapper {
//需要加@MapKey("uname")来指定主键,否则会封装成多个map
@MapKey("uname")
public Map selectAllUser();//查询所有
}
输出:
{赵晓六=User [uid=4, uname=赵晓六, usex=男], 张三=User [uid=1, uname=张三, usex=女], 李晓四=User [uid=2, uname=李晓四, usex=女]}
3. #和$的区别
表面上用法是差不多的,都是#{属性名}
或者${属性名}
。有一些差别的:
1)是否预编译
-
#{}
会被预编译,通过preparedstatement的方式给占位符赋值:
update user set uname = ?,usex = ? where uid = ?
可以在debug阶段看到:

-
${}
不会预编译,在preparing阶段就给SQL语句赋值了:
select * from user where uid = ${value}
debug阶段,发现根本没有parameters,但是我们确实传了参数,就是因为没有预编译阶段,直接将传的参数解析在SQL语句上。

2)是否带有引号
#{}
是带有引号的,${}
不带引号。
所以我们在根据某个字段进行排序的时候,或者模糊查询的时候,可以使用${}
。其他时候用的最多的还是#{}.
3)安全性
由于#{}
支持preparedstatement预编译的方式,所以更安全,不会被SQL注入。
${}
有被SQL注入的风险。
4. mybatis内置参数
mybatis具有内置参数,所谓内置参数就是不是用户传的参数,是mybatis自带的参数,就像Javaweb中九大内置对象一样。
1)_parameter
代表传过来的整个参数,可以有单个,可以有多个,比如Employee对象。
单个参数:_parameter 表示这个参数。
多个参数:参数会被封装成一个map,_parameter表示这个map。
2)_databaseId
如果在mybatis全局配置文件中配置了databaseIdProvider标签,在xml映射文件中可以通过_databaseId取数据库名字。
3)实例
mybatis-config.xml配置文件:
xml映射文件:
select * from emp_mysql
where name = #{_parameter.name}
select * from emp_orcl