- Mybatis参数处理
- 单个简单类型参数
- Map参数
- 实体类参数
- 多参数
- @Param注解(命名参数)
十、★★★Mybatis参数处理
10.1 ★单个简单类型参数
简单类型包括:
- byte short int long float double char
- Byte Short Integer Long Float Double Character
- String
- java.util.Date
- java.sql.Date
需求:根据
id
查、根据name
查、根据birth
查、根据sex
查。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.f.mybatis.mapper;
import com.f.mybatis.pojo.Student;
import java.util.Date;
import java.util.List;
/**
* @author fzy
* @date 2024/1/9 22:14
*/
public interface StudentMapper {
/**
* 当接口中的方法的参数只有一个,并且参数的数据类型都是简单类型
* 根据 `id` 查、根据 `name` 查、根据 `birth` 查、根据 `sex` 查
*/
List<Student> selectById(Long id);
List<Student> selectByName(String name);
List<Student> selectByBirth(Date birth);
List<Student> selectBySex(Character sex);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<mapper namespace="com.f.mybatis.mapper.StudentMapper">
<select id="selectById" resultType="Student">
SELECT * FROM t_student WHERE id = #{id}
</select>
<select id="selectByName" resultType="Student">
SELECT * FROM t_student WHERE name = #{name}
</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>
</mapper>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62package com.f.mybatis.test;
import com.f.mybatis.mapper.StudentMapper;
import com.f.mybatis.pojo.Student;
import com.f.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @author fzy
* @date 2024/1/9 22:18
*/
public class StudentMapperTest {
public void testSelectById() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectById(1L);
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}
public void testSelectByName() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectByName("李四");
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}
public void testSelectByBirth() throws Exception {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Date birth = new SimpleDateFormat("yyyy-MM-dd").parse("1980-10-01");
List<Student> students = mapper.selectByBirth(birth);
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}
public void testSelectBySex() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectBySex('男');
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}
}其实 SQL 映射文件中的配置比较完整的写法是:
1
2
3<select id="selectByName" resultType="Student" parameterType="java.lang.String">
select * from t_student where name = #{name, javaType=String, jdbcType=VARCHAR}
</select>其中 sql 语句中的
javaType
,jdbcType
,以及 select 标签中的parameterType
属性,都是用来帮助 mybatis 进行类型确定的。不过这些配置多数是可以省略的,因为 mybatis 它有强大的自动类型推断机制。
注意:三步走:
- 第一步:写
Mapper
接口中的方法。 - 第二步:写
SqlMapper.xml
配置文件中的 SQL 语句。 - 第三步:写测试类对 SQL 语句进行测试。
- 第一步:写
10.2 Map参数
需求:根据
name
和age
查询。还是三步走:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.f.mybatis.mapper;
import com.f.mybatis.pojo.Student;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author fzy
* @date 2024/1/9 22:14
*/
public interface StudentMapper {
/**
* 当接口中的方法的参数只有一个,并且参数的类型是Map
*/
List<Student> selectByNameAndSex(Map<String, Object> paramMap);
}1
2
3
4
5
6
7
8
9
<mapper namespace="com.f.mybatis.mapper.StudentMapper">
<select id="selectByNameAndSex" resultType="Student">
SELECT * FROM t_student WHERE name = #{name} AND sex = #{sex}
</select>
</mapper>1
2
3
4
5
6
7
8
9
10
11
12
13
public void testSelectByNameAndSex() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("name", "张三");
paramMap.put("sex", '男');
List<Student> students = mapper.selectByNameAndSex(paramMap);
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}这种方式是手动封装 Map 集合,将每个条件以
key
和value
的形式存放到集合中。然后在使用的时候通过#{map集合的key}
来取值。
10.3 ★实体类参数
需求:插入一条 Student 数据。
依然三步走:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.f.mybatis.mapper;
import com.f.mybatis.pojo.Student;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author fzy
* @date 2024/1/9 22:14
*/
public interface StudentMapper {
/**
* 当接口中的方法的参数只有一个,并且参数的类型是实体类POJO
*/
int insert(Student student);
}1
2
3
4
5
6
7
8
9
10
<mapper namespace="com.f.mybatis.mapper.StudentMapper">
<insert id="insert">
INSERT INTO t_student (id, name, age, height, birth, sex)
VALUES (#{id}, #{name}, #{age}, #{height}, #{birth}, #{sex})
</insert>
</mapper>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35package com.f.mybatis.test;
import com.f.mybatis.mapper.StudentMapper;
import com.f.mybatis.pojo.Student;
import com.f.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author fzy
* @date 2024/1/9 22:18
*/
public class StudentMapperTest {
public void testInsert() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = new Student();
student.setName("李清");
student.setAge(23);
student.setHeight(1.78);
// 创建Date对象时,年需减去1900,月从0开始
student.setBirth(new Date(2010 - 1900, 9, 10, 0, 0, 0));
student.setSex('女');
int count = mapper.insert(student);
sqlSession.commit();
SqlSessionUtil.close(sqlSession);
}
}这里需要注意的是:
#{}
里面写的是属性名字。这个属性名为:set/get
方法名去掉set/get
之后的名字。
10.4 多参数
需求:通过
name
和age
查询,并且传入参数为多参数。三步走:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.f.mybatis.mapper;
import com.f.mybatis.pojo.Student;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author fzy
* @date 2024/1/9 22:14
*/
public interface StudentMapper {
/**
* 接口中的方法的参数有多个
* 这里根据name和age查询Student的信息
* 如果是多个参数的话,mybatis框架底层是怎么做的呢
* mybatis框架会自动创建一个Map集合,并且Map集合是以这种方式存储参数的:
* map.put("arg0", name); map.put("param1", name);
* map.put("arg1", age); map.put("param2", age);
*
* @param name
* @param age
* @return
*/
List<Student> selectByNameAndAge(String name, Integer age);
}1
2
3
4
5
6
7
8
9
10
<mapper namespace="com.f.mybatis.mapper.StudentMapper">
<select id="selectByNameAndAge" resultType="Student">
# 传值时要使用 arg0、arg1 或者 param1、param2
SELECT * FROM t_student WHERE name = #{arg0} AND age = #{arg1}
</select>
</mapper>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30package com.f.mybatis.test;
import com.f.mybatis.mapper.StudentMapper;
import com.f.mybatis.pojo.Student;
import com.f.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author fzy
* @date 2024/1/9 22:18
*/
public class StudentMapperTest {
public void testSelectByNameAndAge() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectByNameAndAge("张三", 20);
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}
}当传入多参数时,实际上在 mybatis 底层会创建一个
map
集合,以arg0
和param1
为第一个参数的key
,以参数值为value
,类似以下代码:1
2
3
4
5
6
7
8Map<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}其本质就是
#{map集合的key}
,只不过这里的key
变成了arg0/param1
、arg1/param2
……注意:使用 mybatis3.4.2 之前的版本时:在
SqlMapper.xml
中要用#{0}
和#{1}
这种形式。
10.5 ★@Param注解(命名参数)
可以不用
10.4
节中的arg0
、arg1
、param1
、param2
吗?这个map
集合的key
我们自定义可以吗?当然可以,使用
@Param
注解即可,这样可以增强可读性。需求:通过
name
和age
查询,并且传入参数为多参数,并且使用@Param
注解。三步走:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29package com.f.mybatis.mapper;
import com.f.mybatis.pojo.Student;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author fzy
* @date 2024/1/9 22:14
*/
public interface StudentMapper {
/**
* Param注解
* mybatis框架底层实现原理由
* map.put("arg0", name);
* map.put("arg1", age);
* 转变为 map.put("name", name);
* map.put("age", age);
*
* @param name
* @param age
* @return
*/
List<Student> selectByNameAndAgeUsingParamAnnotation(; String name, Integer age)
}1
2
3
4
5
6
7
8
9
10
<mapper namespace="com.f.mybatis.mapper.StudentMapper">
<select id="selectByNameAndAgeUsingParamAnnotation" resultType="Student">
# 使用了@Param注解之后,arg0、arg1失效了,但是param1、param2还能用
SELECT * FROM t_student WHERE name = #{name} AND age = #{age}
</select>
</mapper>1
2
3
4
5
6
7
8
9
10
public void testSelectByNameAndAgeUsingParamAnnotation() {
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectByNameAndAge("张三", 20);
students.forEach(student -> {
System.out.println(student);
});
SqlSessionUtil.close(sqlSession);
}其实,
@Param("这里填写的就是map集合的key")
。