【MyBatis】mybatis参数传递方式及源码分析

本文介绍了MyBatis中不同类型的参数传递方式,包括单个参数、多个参数、命名参数、POJO、Map和Collection/Array,并通过源码分析讲解了参数处理过程。同时,讨论了查询结果的不同返回类型,如单个对象、对象集合、Map及Map集合。此外,还提到了参数获取方式和安全性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【MyBatis系列】基础篇——curd语法

【MyBatis系列】基础篇——参数传递

【MyBatis系列】基础篇——ResultMap自定义映射

【MyBatis系列】基础篇——动态sql

【MyBatis系列】基础篇——一级缓存 二级缓存

【MyBatis系列】基础篇——驼峰式命名配置

【MyBatis系列】插件篇——逆向工程(代码生成器)

【MyBatis系列】插件篇——PageHelper分页



一、参数传递方式

1) 单个普通类型参数

  • MyBatis可直接使用这个参数,不需要经过任何处理;
  • 因为只有一个参数,表达式参数名称(#{id})可以任意起名
    <select id="getEmployeeById" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{id}
    </select>

2) 多个参数

a)Mybatis 3.4版本

  • mybatis底层会将参数封装为map,map的key是固定值【0,1,2…或 param1,param2,param3,…】
	<select id="getEmployeeCondition" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{0} and lastname = #{1}
    </select><select id="getEmployeeCondition" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{param1} and lastname = #{param2}
    </select>

b)Mybatis3.5版本

  • mybatis底层会将这些参数封装为map,map的key是固定值【arg0,arg1,…或 param1,param2,param3,…】
    <select id="getEmployeeCondition" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{arg0} and lastname = #{arg1}
    </select><select id="getEmployeeCondition" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{param1} and lastname = #{param2}
    </select>

底层是key value值:
在这里插入图片描述

3) 命名参数

可以使用@Param注解,自定义参数名称,MyBatis会将这些参数封装进map中,key就是我们自己指定的名字;
在这里插入图片描述
接口类:

 /**
     * 根据多个条件查询
     * @param id
     * @return
     */
    public Employee getEmployeeCondition(@Param(value = "ids") Integer id, @Param(value = "lastnames") String lastname);

mapper.xml:

    <select id="getEmployeeCondition" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{ids} and lastname = #{lastnames}
    </select>

4) POJO

POJO(Plain Old Java Objects,普通的java对象);
当这些参数属于我们业务POJO时,可以直接传递POJO;

接口类:

    /**
     * 增加员工信息
     * @param employee
     * @return
     */
    public Integer insertEmployee(Employee employee);

mapper.xml:

    <!--增加-->
    <insert id="insertEmployee" parameterType="com.mybatislearn.entity.Employee" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO tbl_employee(lastname,email,gender) VALUES(#{lastname},#{email},#{gender})
    </insert>

5) Map

可以封装多个参数为map,直接传递;

接口类:

/**
     * 使用map传递参数
     * @param map
     * @return
     */
    public Employee getEmployeeMap(Map<String,Object> map);

mapper.xml:

    <select id="getEmployeeMap" parameterType="hashmap" resultType="com.mybatislearn.entity.Employee">
        select * from tbl_employee where id = #{id} and lastname = #{lastname}
    </select>

6) Collection/Array

会被MyBatis封装成一个map传入,Collection对应的key是collection,Array对应的key是array,如果确定是List集合,key还可以是list;

二、参数传递源码分析

以命名参数为例:

代码:

public Employee getEmployeeByIdAndLastName
(@Param("id")Integer id, @Param("lastName")String lastName);

源码:

public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
    if (args == null || paramCount == 0) {
      return null;
    } else if (!hasParamAnnotation && paramCount == 1) {
      return args[names.firstKey()];
    } else {
      //new一个map集合 
      final Map<String, Object> param = new ParamMap<Object>();
      int i = 0;
      //遍历传过来的map集合,获得key和value的值
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
        param.put(entry.getValue(), args[entry.getKey()]);
        // add generic param names (param1, param2, ...)
        final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
        // ensure not to overwrite parameter named with @Param
        if (!names.containsValue(genericParamName)) {
          param.put(genericParamName, args[entry.getKey()]);
        }
        i++;
      }
      //返回该map
      return param;
    }
  }

三、参数处理

  1. 参数位置支持的属性:
javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression
  1. 实际上通常被设置的是:可能为空的列名指定 jdbcType ,例如:
insert into orcl_employee(id,last_name,email,gender) values(employee_seq.nextval,#{lastName,jdbcType=NULL },#{email},#{gender})

四、参数的获取方式

  1. #{key}:预编译方式。获取参数的值,预编译到SQL中。安全
  2. ${key}:非预编译方式。获取参数的值,拼接到SQL中。有SQL注入问题。

五、查询返回不同类型

1) 查询单行数据返回单个对象

    public Employee getEmployeeById(int id);
	
    <select id="getEmployeeById" resultType="com.atguigu.entity.Employee" >
        select * from tbl_employee where id = #{id}
    </select>

2) 查询多行数据返回对象的集合

  public List<Employee> getAll();
	
    <select id="getAll" resultType="com.atguigu.entity.Employee">
        select * from tbl_employee
    </select>

3) 查询单行数据返回Map集合

如果直接返回map类型,要求只能返回一条记录

    public Map<String,Object> getAllMap(int id);

	<select id="getAllMap" resultType="hashmap">
        select * from tbl_employee where id=#{id}
    </select>

4) 查询多行数据返回Map集合

	public List<Map<String,Object>> getAllMapList();

	<select id="getAllMapList" resultType="hashmap">
         select * from tbl_employee
    </select>


5) 查询返回某个值

	public int getCount();

    <select id="getCount" resultType="int">
        select count(*) from tbl_employee
    </select>


感谢阅读哇~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我真爱敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值