MyBatis——MyBatis 参数处理

一、单个简单类型参数

简单类型包括:

  • byte short int long float double char

  • Byte Short Integer Long Float Double Character

  • String

  • java.util.Date

  • java.sql.Date

parameterType 属性:告诉 MyBatis 参数的类型

MyBatis 自带类型自动推断机制,所以大部分情况下 parameterType 属性可以不写

对于部分类型 MyBatis 内置已经起了别名,可以直接使用别名

参考文档:https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases

<select id="selectById" resultType="Account" parameterType="java.lang.String">
    select * from t_act where actno = #{actno};
</select>

二、Map 参数 

这种方式是手动封装 Map 集合,将每个条件以 key 和 value 的形式存放到集合中。

在使用的时候通过 #{map集合的key} 来取值。

/**
* 根据name和age查询
* @param paramMap
* @return
*/
List<Student> selectByParamMap(Map<String,Object> paramMap);
@Test
public void testSelectByParamMap(){
    // 准备Map
    Map<String,Object> paramMap = new HashMap<>();
    paramMap.put("nameKey", "张三");
    paramMap.put("ageKey", 20);

    List<Student> students = mapper.selectByParamMap(paramMap);
    // students.forEach(student -> System.out.println(student));
    students.forEach(System.out::println);
}
<select id="selectByParamMap" resultType="student">
  select * from t_student where name = #{nameKey} and age = #{ageKey}
</select>

三、实体类参数 

这里需要注意的是:#{} 里面写的是属性名字。这个属性名其本质上是:set/get 方法名去掉 set/get 之后的名字。  

/**
 * 保存学生数据
 * @param student
 * @return
 */
int insert(Student student);
<insert id="insert">
  insert into t_student values(null,#{name},#{age},#{height},#{birth},#{sex})
</insert>
@Test
public void testInsert(){
    Student student = new Student();
    student.setName("李四");
    student.setAge(30);
    student.setHeight(1.70);
    student.setSex('男');
    student.setBirth(new Date());
    int count = mapper.insert(student);
    SqlSessionUtil.openSession().commit();
}

四、多参数 

/**
 * 根据name和sex查询
 * @param name
 * @param sex
 * @return
 */
List<Student> selectByNameAndSex(String name, Character sex);
@Test
public void testSelectByNameAndSex(){
    List<Student> students = mapper.selectByNameAndSex("张三", '女');
    // students.forEach(student -> System.out.println(student));
    students.forEach(System.out::println);
}
<select id="selectByNameAndSex" resultType="student">
  select * from t_student where name = #{name} and sex = #{sex}
</select>

执行结果:

异常信息描述了:name 参数找不到,可用的参数包括 [arg1, arg0, param1, param2]

修改 StudentMapper.xml 配置文件:尝试使用 [arg1, arg0, param1, param2] 取参数

<select id="selectByNameAndSex" resultType="student">
  <!--select * from t_student where name = #{name} and sex = #{sex}-->
  select * from t_student where name = #{arg0} and sex = #{arg1}
</select>

执行结果:

再次尝试修改 StudentMapper.xml 文件  

<select id="selectByNameAndSex" resultType="student">
  <!--select * from t_student where name = #{name} and sex = #{sex}-->
  <!--select * from t_student where name = #{arg0} and sex = #{arg1}-->
  <!--select * from t_student where name = #{param1} and sex = #{param2}-->
  select * from t_student where name = #{arg0} and sex = #{param2}
</select>

通过测试可以看到:

  • arg0 是第一个参数

  • param1 是第一个参数

  • arg1 是第二个参数

  • param2 是第二个参数

实现原理:实际上在 mybatis 底层会创建一个 map 集合,以 arg0/param1 为 key,以方法上的参数为 value

// mybatis 部分源码
Map<String,Object> map = new HashMap<>();
map.put("arg0", name);
map.put("arg1", sex);
map.put("param1", name);
map.put("param2", sex);

// 所以可以这样取值:#{arg0} #{arg1} #{param1} #{param2}
// 其本质就是 #{map集合的key}

注意:使用 mybatis 3.4.2 之前的版本时:要用 #{0} 和 #{1} 这种形式。

五、@Param 注解(命名参数) 

map 集合的 key 可以自定义:使用使用 @Param 注解即可  

@Param("这里填写的其实就是 map 集合的 key")

使用注解之后 arg0 arg1 失效了,但是 param1 param2 还可以用  

/**
 * 根据name和age查询
 * @param name
 * @param age
 * @return
 */
List<Student> selectByNameAndAge(@Param(value="name") String name, 
                                 @Param("age") int age);
@Test
public void testSelectByNameAndAge(){
    List<Student> stus = mapper.selectByNameAndAge("张三", 20);
    // stus.forEach(student -> System.out.println(student));
    stus.forEach(System.out::println);
}
<select id="selectByNameAndAge" resultType="student">
  select * from t_student where name = #{name} and age = #{age}
</select>

六、@Param 源码分析 

MyBatis 框架中的 @Param 注解主要用于在 SQL 语句中传递参数,并且可以指定参数的名称,以便在 SQL 语句中引用

下面是 @Param 注解的核心原理解析:

  • 参数绑定: 当使用 @Param 注解时,MyBatis 会将注解中指定的参数名与参数值进行绑定,这样在 XML 映射文件或者注解中就可以通过参数名引用对应的参数值。

  • 构建参数Map: 在处理带有 @Param 注解的方法参数时,MyBatis 会将这些带有 @Param 注解的参数构建成一个参数 Map,在执行 SQL 语句时,会将这个参数 Map 传递给 SQL 语句,以便提供参数值。

  • 参数替换: MyBatis 在解析 SQL 语句时,会检测到带有 @Param 注解的参数,并将参数值替换到 SQL 语句中对应的位置,从而构建最终可执行的 SQL 语句。

  • 参数处理: MyBatis 在执行 SQL 语句时,会根据参数 Map 中的参数名和值来替换 SQL 语句中的参数占位符,从而执行 SQL 查询操作。

  • 参数传递: 使用 @Param 注解可以明确指定参数的名称,避免参数不明确导致的错误,同时也可以方便地在 SQL 语句中引用具体的参数值。

总的来说,@Param 注解的核心原理是通过将带有注解的参数与参数值进行绑定,并构建参数 Map,以便在 SQL 语句中引用参数值并执行查询操作。这样可以提高代码的可读性和准确性。

一  叶  知  秋,奥  妙  玄  心

  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,我可以回答你关于MyBatis中if标签的使用方式。 在MyBatis中,if标签通常用于动态生成SQL语句。它可以用来判断某个字段是否为空,从而根据不同情况生成不同的SQL语句。 以下是一些使用if标签的示例: 1. 判断一个参数是否为null或空字符串: ``` <select id="selectUser" parameterType="java.lang.String" resultType="User"> SELECT * FROM users <where> <if test="username != null and username != ''"> AND username = #{username} </if> </where> </select> ``` 这个例子中,如果传入的username参数不为null或空字符串,则会将其加入到SQL语句中,生成类似于“AND username = 'xxx'”这样的条件语句。 2. 判断一个对象的某个属性是否为null: ``` <select id="selectUser" parameterType="User" resultType="User"> SELECT * FROM users <where> <if test="email != null"> AND email = #{email} </if> </where> </select> ``` 这个例子中,如果传入的User对象的email属性不为null,则会将其加入到SQL语句中,生成类似于“AND email = 'xxx'”这样的条件语句。 3. 判断一个集合是否为空: ``` <select id="selectUser" parameterType="java.util.Map" resultType="User"> SELECT * FROM users <where> <if test="ids != null and ids.size() > 0"> AND id IN <foreach item="id" collection="ids" open="(" separator="," close=")"> #{id} </foreach> </if> </where> </select> ``` 这个例子中,如果传入的Map对象中包含一个名为ids的集合属性且不为空,则会将其加入到SQL语句中,生成类似于“AND id IN (1,2,3)”这样的条件语句。 以上是一些if标签的使用示例,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

QX_Java_Learner

祝老板生意兴隆,财源广进!

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

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

打赏作者

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

抵扣说明:

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

余额充值