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
源码分析: