04.参数处理
1.单个参数
{arg}: 直接取出参数值;只有一个参数时可以随便写
接口方法
java
// 单个参数
User getOneParam(int id);
方法映射
xml
<select id="getOneParam" resultType="org.hong.pojo.User">
select * from user where id = #{user_id}
</select>
测试用例
java
@Test
public void testOneParam(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User oneParam = mapper.getOneParam(1);
System.out.println(oneParam);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
控制台打印
shell
## 正常运行
[main] [org.hong.mapper.UserMapper.getOneParam]-[DEBUG] ==> Preparing: select * from user where id = ?
[main] [org.hong.mapper.UserMapper.getOneParam]-[DEBUG] ==> Parameters: 1(Integer)
[main] [org.hong.mapper.UserMapper.getOneParam]-[DEBUG] <== Total: 1
User(id=1, name=谢禹宏, pwd=123456)
2.多个参数
MyBatis 会做特殊处理,多个参数会被封装成一个**map**
**key:**<font color='red'>`param1...paramN`</font> **or** <font color='red'>`arg0...argN-1 `</font>
**value:**传入的参数
接口方法
java
// 多个参数
User getParams(String name, String pwd);
方法映射
xml
<select id="getParams" resultType="org.hong.pojo.User">
<!--
参数name可以使用 #{arg0} 或 #{param1} 取出
参数pwd可以使用 #{arg1} 或 #{param2} 取出
-->
select * from user where name = #{arg0} and pwd = #{param2}
</select>
测试用例
java
@Test
public void testParams(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User user = mapper.getParams("Tom", "123456");
System.out.println(user);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
控制台打印
shell
## 正常运行
[main] [org.hong.mapper.UserMapper.getParams]-[DEBUG] ==> Preparing: select * from user where name = ? and pwd = ?
[main] [org.hong.mapper.UserMapper.getParams]-[DEBUG] ==> Parameters: Tom(String), 123456(String)
[main] [org.hong.mapper.UserMapper.getParams]-[DEBUG] <== Total: 1
User(id=2, name=Tom, pwd=123456)
3.命名参数
使用注解 @Param
指定参数的 key
多个参数会被封装成一个 map
key:param1...paramN
or arg0...argN-1
**value:**传入的参数
接口方法
java
// 命名参数
User getAnnoParam(@Param("name") String name,
String pwd);
方法映射
xml
<select id="getAnnoParam" resultType="org.hong.pojo.User">
select * from user where name = #{name} and pwd = #{param2}
</select>
测试用例
java
@Test
public void testAnnoParam(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User user = mapper.getAnnoParam("Tom", "123456");
System.out.println(user);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
控制台打印
shell
## 正常运行
[main] [org.hong.mapper.UserMapper.getAnnoParam]-[DEBUG] ==> Preparing: select * from user where name = ? and pwd = ?
[main] [org.hong.mapper.UserMapper.getAnnoParam]-[DEBUG] ==> Parameters: Tom(String), 123456(String)
[main] [org.hong.mapper.UserMapper.getAnnoParam]-[DEBUG] <== Total: 1
User(id=2, name=Tom, pwd=123456)
4.POJO
**多个参数正好是业务逻辑的数据模型(实体类),直接传入pojo(对象)**
#{属性名}: 取出传入的pojo对应属性的值
接口方法
java
// pojo
int updatePojo(User user);
方法映射
xml
<update id="updatePojo">
update user set name = #{name}, pwd = #{pwd} where id = #{id}
</update>
测试用例
java
@Test
public void testUpdatePojo(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User user = mapper.getOneParam(1);
user.setPwd("654321");
int i = mapper.updatePojo(user);
System.out.println(i);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
控制台打印
shell
## 正常运行
[main] [org.hong.mapper.UserMapper.getOneParam]-[DEBUG] ==> Preparing: select * from user where id = ?
[main] [org.hong.mapper.UserMapper.getOneParam]-[DEBUG] ==> Parameters: 1(Integer)
[main] [org.hong.mapper.UserMapper.getOneParam]-[DEBUG] <== Total: 1
[main] [org.hong.mapper.UserMapper.updatePojo]-[DEBUG] ==> Preparing: update user set name = ?, pwd = ? where id = ?
[main] [org.hong.mapper.UserMapper.updatePojo]-[DEBUG] ==> Parameters: 谢禹宏(String), 654321(String), 1(Integer)
[main] [org.hong.mapper.UserMapper.updatePojo]-[DEBUG] <== Updates: 1
1
5.Map
如果多个参数不是业务模型中的数据模型, 没有对应的 pojo, 可以传入 map
\#{key}: 取出map中key对应的值
接口方法
java
//map
User getMapParam(Map<String, Object> map);
方法映射
xml
<select id="getMapParam" resultType="org.hong.pojo.User">
select * from user where name = #{name} and pwd = #{pwd}
</select>
测试用例
java
@Test
public void testMap(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
Map<String, Object> map = new HashMap<>();
map.put("name", "Tom");
map.put("pwd", "123456");
User mapParam = mapper.getMapParam(map);
System.out.println(mapParam);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
控制台打印
shell
## 正常运行
[main] [org.hong.mapper.UserMapper.getMapParam]-[DEBUG] ==> Preparing: select * from user where name = ? and pwd = ?
[main] [org.hong.mapper.UserMapper.getMapParam]-[DEBUG] ==> Parameters: Tom(String), 123456(String)
[main] [org.hong.mapper.UserMapper.getMapParam]-[DEBUG] <== Total: 1
User(id=2, name=Tom, pwd=123456)
6. TO
多个参数不是业务模型中的数据, 但经常要使用, 推荐编写 TO(Transfer Object)数据传输对象, 就是再专门写个类
7.#{} 和 ${} 的区别
#{}是占位符,${}是拼接符。
#{}是预编译处理,${}是字符串替换。
Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的set 方法来赋值。
Mybatis 在处理$ {}时,就是把${}替换成变量的值。
使用#{}可以有效的防止 SQL 注入,提高系统安全性。
接口方法
java
// #{}和${}的区别
List<User> getOrderBy(String order);
方法映射
xml
<!-- #{}和${}的区别 -->
<select id="getOrderBy" resultType="org.hong.pojo.User">
select * from user order by id ${order}
</select>
测试用例
java
@Test
public void test$(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
List<User> desc = mapper.getOrderBy("desc");
desc.forEach(System.out :: println);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
控制台打印
shell
## 使用${}方式取值不会被预编译, 而是将${xxx}替换成对应的值, 再发送sql, 通常用来动态拼接sql, 比如排序
[main] [org.hong.mapper.UserMapper.getOrderBy]-[DEBUG] ==> Preparing: select * from user order by id desc
[main] [org.hong.mapper.UserMapper.getOrderBy]-[DEBUG] ==> Parameters:
[main] [org.hong.mapper.UserMapper.getOrderBy]-[DEBUG] <== Total: 5
User(id=5, name=SAVE ID, pwd=123)
User(id=4, name=SAVE ID, pwd=123)
User(id=3, name=Jerry, pwd=123456)
User(id=2, name=Tom, pwd=123456)
User(id=1, name=谢禹宏, pwd=987654)
8.最终版
8.1 Mapper 接口
java
package org.hong.mapper;
import org.apache.ibatis.annotations.Param;
import org.hong.pojo.User;
import java.util.Map;
public interface UserMapper {
// 单个参数
User getOneParam(int id);
// 多个参数
User getParams(String name, String pwd);
// 命名参数
User getAnnoParam(@Param("name") String name,
String pwd);
// pojo
int updatePojo(User user);
//map
User getMapParam(Map<String, Object> map);
// #{}和${}的区别
List<User> getOrderBy(String order);
}
8.2 Mapper.xml 文件
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.hong.mapper.UserMapper">
<!-- 单个参数 -->
<select id="getOneParam" resultType="org.hong.pojo.User">
select * from user where id = #{user_id}
</select>
<!-- 多个参数 -->
<select id="getParams" resultType="org.hong.pojo.User">
<!--
参数name可以使用 #{0} 或 #{param1} 取出
参数pwd可以使用 #{1} 或 #{param2} 取出
-->
select * from user where name = #{arg0} and pwd = #{param2}
</select>
<!-- 命名参数 -->
<select id="getAnnoParam" resultType="org.hong.pojo.User">
select * from user where name = #{name} and pwd = #{param2}
</select>
<!-- pojo -->
<update id="updatePojo">
update user set name = #{name}, pwd = #{pwd} where id = #{id}
</update>
<!-- map -->
<select id="getMapParam" resultType="org.hong.pojo.User">
select * from user where name = #{name} and pwd = #{pwd}
</select>
<!-- #{}和${}的区别 -->
<select id="getOrderBy" resultType="org.hong.pojo.User">
select * from user order by id ${order}
</select>
</mapper>
8.3 测试用例
java
package org.hong.test;
import org.apache.ibatis.session.SqlSession;
import org.hong.mapper.UserMapper;
import org.hong.pojo.User;
import org.hong.util.MyBatisUtil;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class CRUDTest {
@Test
public void testOneParam(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User oneParam = mapper.getOneParam(1);
System.out.println(oneParam);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
@Test
public void testParams(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User oneParam = mapper.getParams("Tom", "123456");
System.out.println(oneParam);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
@Test
public void testAnnoParam(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User user = mapper.getAnnoParam("Tom", "123456");
System.out.println(user);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
@Test
public void testUpdatePojo(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
User user = mapper.getOneParam(1);
user.setPwd("654321");
int i = mapper.updatePojo(user);
System.out.println(i);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
@Test
public void testMap(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
Map<String, Object> map = new HashMap<>();
map.put("name", "Tom");
map.put("pwd", "123456");
User mapParam = mapper.getMapParam(map);
System.out.println(mapParam);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
@Test
public void test$(){
// 1.获取sqlSession对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 2.获取需要的mapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 3.调用对应的方法执行操作
List<User> desc = mapper.getOrderBy("desc");
desc.forEach(System.out :: println);
// 4.提交事务
sqlSession.commit();
// 5.关闭sqlSession
sqlSession.close();
}
}
9.总结
java
public User getEmp(@Param("id")Integer id, Strig name);
// 取值: id-->#{id|param1} name-->#{param2}
public User getEmp(Integer id, @Param("e")Emp emp);
// 取值: id-->#{param1} name-->#{param2.name|e.name}
public User getEmpById(List<Integer> ids);
/*
##特别注意:
如果是Collection(List, Set) or Array, 也会特殊处理, 把传入的list或数组封装在map中。
Key: Collection(collection) | List(list) | Array(array) | Set(set)
取值: 取出第一个id的值: #{list[0]}
*/