Skip to content

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]}
 */

Released under the MIT License.