第五章 参数处理

时间:2021-6-4 作者:qvyue

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> selectAllUser();//查询所有
}   

UserMapper.xml:



  select * from user

Junit测试:

@Test
public void testQueryAll() {
  UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  // 查询所有用户
  List> map = userMapper.selectAllUser();
  System.out.println(map);
}

输出:

[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
  

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。