尚硅谷MyBatis6_获得参数值的方式

MyBatis 获取参数值的两种方式:${}#{}

  • ${}

    本质就是字符串拼接,使用字符串拼接的方式拼接 sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号

  • #{}

    本质就是占位符赋值,使用占位符赋值的方式拼接 sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。该方式可以避免 sql 注入

单个字面量类型的参数

若 mapper 接口中的方法参数为单个的字面量类型 此时可以使用 ${}#{}以任意的名称获取参数的值,注意 ${}需要手动加单引号

使用 #{}

<!--User getUserByUsername(String username);-->
<select id="getUserByUsername" resultType="User">
    select * from t_user where username = #{username}
</select>

事实上,#{}里面写啥都行,比如写 #{aaa}也是可以的,重点的是获取到值,但是建议还是写对应的名字,比较清楚

在底层中可以看到:

DEBUG 03-19 16:53:31,884 ==>  Preparing: select * from t_user where username = ? (BaseJdbcLogger.java:135) 

实际上也就是说采用了原生的占位符的方式

使用 ${}

<select id="getUserByUsername" resultType="User">
    select * from t_user where username = '${username}'
</select>

注意使用 ${} 需要手动添加单引号,因为本质是字符串拼接

多个字面量类型的参数

若 mapper 接口中的方法参数为多个时,此时 MyBatis 会自动将这些参数放在一个 map 集合中,以 arg0,arg1...为键,以参数为值;以 param1,param2...为键,以参数为值;因此只需要通过 ${}#{}访问 map 集合的键就可以获取相对应的值,注意 ${}需要手动加单引号

一个错误示范及解决方案

<!--User checkLogin(String username, String password);-->
<select id="checkLogin" resultType="User">
    select * from t_user where username = #{username} and password = #{password}
</select>
Error querying database.  Cause: org.apache.ibatis.binding.BindingException: 
Parameter 'username' not found.
Available parameters are [arg1, arg0, param1, param2]

连 sql 语句都没有输出,说明解析 sql 语句出错了,应该通过 arg0、arg1 或者 param1、param2 获取

<!--User checkLogin(String username, String password);-->
<select id="checkLogin" resultType="User">
    select * from t_user where username = #{arg0} and password = #{arg1}
    -- 也可以这么写
    -- select * from t_user where username = #{param1} and password = #{arg1}
</select>

arg 和 param 可以混着用,注意参数是第几个就行

map 集合类型的参数

若 mapper 接口中的方法需要的参数为多个时,此时可以手动创建 map 集合,将这些数据放在 map 中

只需要通过 ${}#{} 访问 map 集合的键就可以获取相对应的值,注意 ${} 需要手动加单引号

<!--User checkLoginByMap(Map<String, Object> map);-->
<select id="checkLoginByMap" resultType="User">
    select *
    from t_user
    where username = #{username}
      and password = #{password}
</select>
@Test
public void testParamByMap() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    Map<String,Object> map = new HashMap<>();
    map.put("username","admin");
    map.put("password","123456");
    User user = mapper.checkLoginByMap(map);
    System.out.println(user);
}

相当于是 map 使用的是自定义的键名

实体类类型的参数

若 mapper 接口中的方法参数为实体类对象时

此时可以使用 ${}#{},通过访问实体类对象中的属性名获取属性值,注意 ${} 需要手动加单引号

<!--int insertUserByEntity(User user);-->
<insert id="insertUserByEntity">
    insert into t_user
    values(null, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>
@Test
public void testInsertUser() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = new User(null,"hello","123456",16,"男","1234@qq.com");
    int result = mapper.insertUserByEntity(user);
    System.out.println(result);
}

使用 @Param 标识参数

可以通过 @Param 注解标识 mapper 接口中的方法参数,此时,会将这些参数放在 map 集合中,以 @Param("属性值") 为键,以参数为值;以 param1,param2...为键,以参数为值;只需要通过 ${}#{}访问 map 集合的键就可以获取相对应的值,注意 ${}需要手动加单引号

使用 @Param 要注意,如果 #{} 内写的不是 @Param("")指定的属性名会报错:

image

意思是说要么用 param1 和 param2 这两个键;要么用 username 和 password 这两个键

<!--User checkLoginByParam(@Param("username") String username, @Param("password") String password);-->
<select id="checkLoginByParam" resultType="User">
    select *
    from t_user
    where username = #{username}
      and password = #{password}
</select>

image

注:建议要么传入实体类型,要么使用 @Param 注解

posted @ 2023-03-19 19:34  ShaunY  阅读(8)  评论(0编辑  收藏  举报