[000-01-011].第08节:MyBatis参数处理

我的后端学习大纲

MyBatis学习大纲


1.环境准备:

  • 1.新建模块:模块名:mybatis-006-param
  • 2.新建数据库表:t_student
    在这里插入图片描述
  • 3.新建pojo类:
public class Student {
 private Long id;
 private String name;
 private Integer age;
 private Double height;
 private Character sex;
 private Date birth;
 // constructor
 // setter and getter
 // toString
}

2.单个简单类型参数:

2.1.简单类型都有哪些:

  • 1.byte short int long float double char
  • 2.Byte Short Integer Long Float Double Character
  • 3.String
  • 4.java.util.Date
  • 5.java.sql.Date

2.2.参数接收:

a.参数接收:

  • 1.当是单字面量的时候,此时可以使用${}和#{},以任意的名称获取参数的值,注意${}需要手动加单引号

b.编码测试:

  • 1.在接口中定义抽象方法:
/**
 * 学⽣数据Sql映射器
 */
public interface StudentMapper {
 /**
 * 根据name查询
 * @param name
 * @return
 */
 List<Student> selectByName(String name);
 /**
 * 根据id查询
 * @param id
 * @return
 */
 Student selectById(Long id);
 /**
 * 根据birth查询
 * @param birth
 * @return
 */
 List<Student> selectByBirth(Date birth);
 /**
 * 根据sex查询
 * @param sex
 * @return
 */
 List<Student> selectBySex(Character sex);
}
  • 2.查询:
<?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="com.powernode.mybatis.mapper.StudentMapper">
 <select id="selectByName" resultType="student">
 	select * from t_student where name = #{name}
 </select>
 <select id="selectById" resultType="student">
 	select * from t_student where id = #{id}
 </select>
 <select id="selectByBirth" resultType="student">
 	select * from t_student where birth = #{birth}
 </select>
 <select id="selectBySex" resultType="student">
 	select * from t_student where sex = #{sex}
 </select>
 <select id="selectBySex" resultType="student">
 	select * from t_student where sex = '${sex}'
 </select>
</mapper>
  • 3.测试:
public class StudentMapperTest {
 StudentMapper mapper = SqlSessionUtil.openSession().getMapper(StudentMapper.class);
 

 @Test
 public void testSelectByName(){
	 List<Student> students = mapper.selectByName("张三");
	 students.forEach(student -> System.out.println(student));
 }



 @Test
 public void testSelectById(){
	 Student student = mapper.selectById(2L);
	 System.out.println(student);
 }



@Test
 public void testSelectByBirth(){
	 try {
	 	Date birth = new SimpleDateFormat("yyyy-MM-dd").parse("2022-08-16");
	 	List<Student> students = mapper.selectByBirth(birth);
	 	students.forEach(student -> System.out.println(student));
	 } catch (ParseException e) {
	 throw new RuntimeException(e);
	 }
 }



 @Test
 public void testSelectBySex(){
 	List<Student> students = mapper.selectBySex('男');
	students.forEach(student -> System.out.println(student));
 }
}
  • 4.说明:
    • 通过测试得知,简单类型对于mybatis来说都是可以⾃动类型识别的
    • 也就是说对于mybatis来说,它是可以⾃动推断出ps.setXxxx()⽅法的,ps.setString()还是ps.setInt()。它可以⾃动推断。
    • 其实SQL映射⽂件中的配置⽐较完整的写法是:
<select id="selectByName" resultType="student" parameterType="java.lang.String">
 	select * from t_student where name = #{name, javaType=String, jdbcType=VARCHAR}
</select>
  • 5.其中sql语句中的javaType,jdbcType,以及select标签中的parameterType属性,都是⽤来帮助mybatis进⾏类型确定的。不过这些配置多数是可以省略的。因为mybatis它有强⼤的⾃动类型推断机制。javaType:可以省略,jdbcType:可以省略,parameterType:可以省略

3.Map参数:

3.1.参数接收:

  • 1.若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合
  • 2.将这些数据放在map中,只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号

3.2.编码测试Map参数:

a.案例1:数据库表里插入一条数据:

  • 1.定义mapper接口:
    在这里插入图片描述
  • 2.映射配置文件:在这里插入图片描述
  • 3.单元测试:在这里插入图片描述

b.案例2:需求根据name和age查询

  • 1.定义StudentMapper接⼝
/**
* 根据name和age查询
* @param paramMap
* @return
*/
List<Student> selectByParamMap(Map<String,Object> paramMap);
  • 2.编写
<select id="selectByParamMap" resultType="student">
 	select * from t_student where name = #{nameKey} and age = #{ageKey}
</select>
  • 3.测试:
@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));
}

说明:这种⽅式是⼿动封装Map集合,将每个条件以key和value的形式存放到集合中。然后在使⽤的时候通过#{map集合的key}来取值。


4.实体类参数:

4.1.参数接收:

  • 1.若 mapper接口中的方法参数为实体类对象时,此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值(其实看的是set和get方法),注意${}需要手动加单引号;

4.2.编码测试:

a.测试案例:

  • 1.定义mapper接口中的抽象方法
    在这里插入图片描述
  • 2.映射文件
    在这里插入图片描述
  • 3.测试
    在这里插入图片描述

注意:#{} ⾥⾯写的是属性名字。这个属性名其本质上是:set/get⽅法名去掉set/get之后的名字。


5.多参数:

5.1.参数接收:

  • 1.当mapper接口方法的参数有多个的时候,此时MyBatis会把这些参数放在一个mapper集合中,以两种方式存储
    • 以arg0,arg1…为键,以参数为值;
    • 以param1,param2…为键,以参数为值;
  • 2.因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号

5.2.编码测试:

a.案例1:根据参数查询数据:

  • 1.定义接口方法:
    在这里插入图片描述
  • 2.映射配置文件:在这里插入图片描述
  • 3.单元测试:
    在这里插入图片描述

b.案例2:通过name和sex查询

  • 1.StudentMapper接⼝
/**
 * 根据name和sex查询
 * @param name
 * @param sex
 * @return
 */
 List<Student> selectByNameAndSex(String name, Character sex);
  • 2.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>
  • 3.StudentMapperTest.testSelectByNameAndSex
@Test
public void testSelectByNameAndSex(){
 	List<Student> students = mapper.selectByNameAndSex("张三", '⼥');
 	students.forEach(student -> System.out.println(student));
}

5.3.MyBatis底层原理说明:

  • 1.实现原理:实际上在mybatis底层会创建⼀个map集合,以arg0/param1为key,以⽅法上的参数为value,例如以下代码
    在这里插入图片描述
  • 2.通过源码发现,上面的SQL更改成如下写法也是可以的:
<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>

6.参数中含有@Param注解:

6.1.参数接收:

  • 1.在上一节中,我们获取参数需要时arg0 arg1 param1 param2,这个map集合的key不是⾃定义的,可读性差,我们可使用@Param注解解决这个问题
  • 2.通过@Param注解标识mapper接口中的方法参数,此时,会将这些参数放在map集合中,有两种方式存储;
    • @Param注解的value属性值为键,以参数为值
    • param1,param2...为键,以参数为值
  • 3.我们只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号

6.2.编码测试:

a.编码测试案例1:

  • 1.mapper接口方法:
    在这里插入图片描述
  • 2.映射文件:
    在这里插入图片描述
  • 3.测试:
    在这里插入图片描述

b.案例测试2:根据name和age查询

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

6.3.源码分析(暂时先跳过):

  • 1.核⼼:@Param("这⾥填写的其实就是map集合的key"
  • @Param源码分析: 在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值