Mybatis-02

Mybatis-02

12、mybatis的参数传递

参数的传递指的是 mapper 接口中方法的参数值,如何传递到 mapper.xml配置文件的 #{} 占位符中

12.1、一个普通数据类型

Mapper接口

1
2
3
4
5
public interface UserMapper {

public User queryUserById(Integer id);

}

mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
<mapper namespace="com.atguigu.mapper.UserMapper">

<!-- public User queryUserById(Integer id);

当接口参数类型为一个普通类型的时候,则#{}中可以写任意内容,一般推荐写上参数名.从而提高可读性
-->
<select id="queryUserById" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where id = #{id}
</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
package com.atguigu.mapper.test;

import com.atguigu.mapper.UserMapper;
import com.atguigu.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

public class UserMapperTest {

static SqlSessionFactory sqlSessionFactory;

@Before
public void setUp() throws Exception {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}

@Test
public void queryUserById() {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

User user = mapper.queryUserById(1);

System.out.println(user);
} finally {
sqlSession.close();
}

}
}

12.2、多个普通数据类型

Mapper接口

1
2
3
4
5
6
7
/**
* 根据用户名或性别查询用户
* @param name
* @param sex
* @return
*/
public List<User> queryUsersByNameOrSex(String name,Integer sex);

mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!--    /**
* 根据用户名或性别查询用户
* @param name
* @param sex
* @return
*/
public List<User> queryUsersByNameOrSex(String name,Integer sex);
当参数是多个普通数据类型的时候,默认有两个方法可以传递参数值.
方案一:
arg0 表示第一个参数
arg1 表示第二个参数
....,以此类推
argN 表示第N+1个参数
方案二( 推荐使用下面这种,兼容性好 ):
param1 表示第一个参数
param2 表示第二个参数
....,以此类推
paramN 表示第N个参数
-->
<select id="queryUsersByNameOrSex" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where last_name = #{param1} or sex = #{param2}
</select>

测试的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
public void queryUsersByNameOrSex() {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);


for (User user : mapper.queryUsersByNameOrSex("wzg168", 1)) {
System.out.println(user);
}

} finally {
sqlSession.close();
}
}

@Param注解命名参数

Mapper接口:

1
2
3
4
5
6
7
8
9
10
/**
* 根据用户名或性别查询用户
* @param name
* @param sex
* @return
*/
public List<User> queryUsersByNameOrSex(
@Param("name") String name,
@Param("sex") Integer sex
);

mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--  
/**
* 根据用户名或性别查询用户
* @param name
* @param sex
* @return
*/
public List<User> queryUsersByNameOrSex(
@Param("name") String name,
@Param("sex") Integer sex
);

当我们在mapper接口的参数中使用注解@Param("name") String name,
则 我们在 sql 语句中,就可以使用 #{ name } 来表示注解参数name的值

@Param("sex") Integer sex 则 #{} 中就可以写成为 #{sex}
-->
<select id="queryUsersByNameOrSex" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where last_name = #{name} or sex = #{sex}
</select>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
public void queryUsersByNameOrSex() {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);


for (User user : mapper.queryUsersByNameOrSex("wzg168", 1)) {
System.out.println(user);
}

} finally {
sqlSession.close();
}
}

12.3、传递一个Map对象作为参数

Mapper接口:

1
2
3
4
5
6
/**
* 需要在map中放名称,和性别 来进行查询用户
* @param paramMap
* @return
*/
public List<User> queryUsersByMap(Map<String,Object> paramMap);

Mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--    /**
* 需要在map中放名称,和性别 来进行查询用户
* @param paramMap
* @return
*/
public List<User> queryUsersByMap(Map<String,Object> paramMap);

如果参数的类型是一个map,我们只需要让Map中的key和#{} 占位符中的参数名一致即可.

Map<String,Object> paramMap = new HashMap<>();
paramMap.put("name","wzg168");
paramMap.put("sex", 1);
for (User user : mapper.queryUsersByMap(paramMap)) {
System.out.println(user);
}

paramMap.put("name","wzg168"); ==>>> #{name}
paramMap.put("sex", 1); ===>>> #{sex}

-->
<select id="queryUsersByMap" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where last_name = #{name} or sex = #{sex}
</select>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void queryUsersByMap() {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

Map<String,Object> paramMap = new HashMap<>();
paramMap.put("name","wzg168");
paramMap.put("sex", 1);
for (User user : mapper.queryUsersByMap(paramMap)) {
System.out.println(user);
}
} finally {
sqlSession.close();
}
}

12.4、一个Pojo数据类型

Mapper接口:

1
public int saveUser(User user);

Mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--
public int saveUser(User user);

当参数是一个javaBean对象( pojo对象 ),只需要在 #{} 中写上相应的属性名即可.

public class User {
private Integer id; ====>>>>> #{id}
private String lastName; ====>>>>> #{lastName}
private Integer sex; ====>>>>> #{sex}
-->
<insert id="saveUser" parameterType="com.atguigu.pojo.User">
insert into t_user(`last_name`,`sex`) values(#{lastName} , #{sex});
</insert>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void saveUser() {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

mapper.saveUser(new User(null,"bbj168",0));

sqlSession.commit();
} finally {
sqlSession.close();
}
}

12.5、模糊查询

需求:现在要根据用户名查询用户对象。 也就是希望查询如下: select * from t_user where last_name like ‘%张%’

Mapper接口:

1
2
3
4
5
/**
* 根据给定的参数名执行select查询语句<br/>
* select * from t_user where last_name like %name%
*/
public List<User> queryUsersLikeName(@Param("name") String name);

Mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--    /**
* 根据给定的参数名执行select查询语句<br/>
* select * from t_user where last_name like %name%
*/
public List<User> queryUsersLikeName(String name);

select `id`,`last_name` lastName,`sex` from t_user where last_name like #{name}

#{} 是占位符 ?
如果只有一个参数的时候,可以随意填写,推荐写成参数名,提高可读性
#{} 一般用于参数的占位符.

${} 它的作用是把指定参数的值输出,然后和sql中的内容做字符串拼接操作
${}里可以使用@Param(“xxx”)注解来给参数命名使用.然后在${xxx}中使用
${}一般用在替换表
-->
<select id="queryUsersLikeName" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where last_name like '%${name}%'
</select>

测试的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 根据给定的参数名执行select查询语句<br/>
* select * from t_user where last_name like %name%
*/
@Test
public void queryUsersLikeName(){

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

String name = "b";

for (User user : mapper.queryUsersLikeName(name )) {
System.out.println(user);
}

} finally {
sqlSession.close();
}

}

12.6、MySQL的字符串拼接,concat函数实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--    /**
* 根据给定的参数名执行select查询语句<br/>
* select * from t_user where last_name like %name%
*/
public List<User> queryUsersLikeName(String name);

select `id`,`last_name` lastName,`sex` from t_user where last_name like #{name}

#{} 是占位符 ?
如果只有一个参数的时候,可以随意填写,推荐写成参数名,提高可读性
#{} 一般用于参数的占位符.

${} 它的作用是把指定参数的值输出,然后和sql中的内容做字符串拼接操作
${}里可以使用@Param注解来给参数命名使用.然后在${}中使用
${}一般用在替换表
-->
<select id="queryUsersLikeName" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where last_name like concat('%',#{name},'%')
</select>

13、自定义结果集

13.1、<resultMap>的作用。

它可以把查询得到的结果集映射成为需要的数据返回.

resultMap 可以将查询回来的列和JavaBean中的属性做映射( 建立他们的对应关系 )

在使用resultMap标签之前,我们都是使用的resultType属性.指定返回值的类型.这个时候Mybatis的底层是做的自动映射.

自动映射示意图:

resultMap标签手动映射结果集

Mapper接口:

1
2
3
public interface UserMapper {

public List<User> queryUsers();

}

Mapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    <!--
resultMap标签可以做自动映射
id表示一个唯一的标识
type发展指定对哪个类做映射
-->
<resultMap id="resultMap1" type="com.atguigu.pojo.User">
<!--
id 标签专门用来给主键列做映射关系
column 指定列名
property指定属性名
-->
<id column="id" property="id" />
<!--
result标签用于非主键列做映射关系
-->
<result column="last_name" property="lastName"/>
<result column="sex" property="sex"/>
</resultMap>
<!-- public List<User> queryUsers(); resultMap="resultMap1" -->
<select id="queryUsers" resultMap="resultMap1">
select `id`,`last_name`,`sex` from t_user
</select>

测试的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void queryUsers(){
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

for (User queryUser : mapper.queryUsers()) {
System.out.println(queryUser);
}

} finally {
sqlSession.close();
}
}

一般情况下.我们的resultMap并不是应用在简单的JavaBean对象上.

而是应用在复杂的JavaBean对象上做手动映射会达到很好的效果.

简单的JavaBean对象就是它的属性都是普通的类型

复杂的Bean对象,它的属性还有Bean对象类型的情况,或者是集合类型,集合中每个元素又是Bean对象的情况,叫复杂Bean对象.

13.2、创建一对一数据库表

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
## 一对一数据表
## 创建锁表
create table t_lock(
`id` int primary key auto_increment,
`name` varchar(50)
);


## 创建钥匙表
create table t_key(
`id` int primary key auto_increment,
`name` varchar(50),
`lock_id` int ,
foreign key(`lock_id`) references t_lock(`id`)
);


## 插入初始化数据
insert into t_lock(`name`) values('阿里巴巴');
insert into t_lock(`name`) values('华为');
insert into t_lock(`name`) values('联想');

insert into t_key(`name`,`lock_id`) values('马云',1);
insert into t_key(`name`,`lock_id`) values('任正非',2);
insert into t_key(`name`,`lock_id`) values('柳传志',3);

13.3、创建实体对象

1
2
3
4
5
6
7
8
9
10
public class Lock {
private Integer id;
private String name;
}
public class Key {
private Integer id;
private String name;
private Lock lock;
}

Mapper接口

1
2
3
4
5
6
7
public interface KeyMapper {
/**
* 根据指定的id值查询出key的信息,以及它对应的Lock锁的信息.
*/
public Key queryKeyById(Integer id);

}

Mapper.xml配置文件:

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
    <!--
id表示唯一的标识
type属性表示和哪个javaBean对象做列的映射关系
-->
<resultMap id="resultMap1" type="com.atguigu.pojo.Key">
<id column="id" property="id" />
<result column="name" property="name" />
<!--
级联属性映射
-->
<result column="lock_id" property="lock.id" />
<result column="lock_name" property="lock.name" />
</resultMap>
<!-- /**
* 根据指定的id值查询出key的信息,以及它对应的Lock锁的信息.
*/
public Key queryKeyById(Integer id);-->
<select id="queryKeyById" resultMap="resultMap1">
select
t_key.id as id,
t_key.name as name,
t_lock.id as lock_id,
t_lock.name as lock_name
from
t_key left join t_lock
on
t_lock.id = t_key.lock_id
where
t_key.id = #{id}
</select>

13.4.2、<association /> 嵌套结果集映射配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    <resultMap id="resultMap1" type="com.atguigu.pojo.Key">
<id column="id" property="id" />
<result column="name" property="name" />
<!--
级联属性映射
<result column="lock_id" property="lock.id" />
<result column="lock_name" property="lock.name" />
-->
<!--
使用association 映射子对象的属性
property 设置哪个子对象( 子对象属性名 )
javaType 是指定子对象的类型
-->
<association property="lock" javaType="com.atguigu.pojo.Lock">
<result column="lock_id" property="id"/>
<result column="lock_name" property="name"/>
</association>

</resultMap>

13.4.3、<association /> 定义分步查询立即加载

Mapper接口

1
2
3
4
5
6
7
public interface LockMapper {
/**
* 根据lock的id查询lock信息
*/
public Lock queryLockById(Integer id);

}

LockMapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
<mapper namespace="com.atguigu.mapper.LockMapper">

<!-- /**
* 根据lock的id查询lock信息
*/
public Lock queryLockById(Integer id);-->
<select id="queryLockById" resultType="com.atguigu.pojo.Lock">
select `id`,`name` from t_lock where id = #{id}
</select>

</mapper>

KeyMapper接口:

1
2
3
4
5
6
7
8
9
10
11
public interface KeyMapper {

/**
* 这里只是简单地把key中的数据查询出来<br/>
* 然后当需要用到Lock数据的时候再调用另一个查询去查lock的数据
* @param id
* @return
*/
public Key queryKeyByIdForSimple(Integer id);

}

KeyMapper.xml配置文件:

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
   <resultMap id="resultMap2" type="com.atguigu.pojo.Key">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
association标签可以用来映射一个子对象
一种是通过调用一个查询来得到子对象
一种是通过建立查询好的列和子对象的属性来进行映射

property属性指定要映射哪个子对象
select 属性指定要使用哪个查询得到子对象
column 表示把结果集中的哪个列做为参数给调用的方法使用.
-->
<association property="lock" column="lock_id"
select="com.atguigu.mapper.LockMapper.queryLockById" />
</resultMap>
<!-- /**
* 这里只是简单地把key中的数据查询出来<br/>
* 然后当需要用到Lock数据的时候再调用另一个查询去查lock的数据
* @param id
* @return
*/
public Key queryKeyByIdForSimple(Integer id);-->
<select id="queryKeyByIdForSimple" resultMap="resultMap2">
select `id`,`name`,`lock_id` from t_key where id = #{id}
</select>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void queryKeyByIdForSimple(){

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
KeyMapper mapper = sqlSession.getMapper(KeyMapper.class);

Key key = mapper.queryKeyByIdForSimple(1);

System.out.println( key );
} finally {
sqlSession.close();
}

}

13.5、延迟加载

延迟加载在一定程序上可以减少很多没有必要的查询。给数据库服务器提升性能上的优化。

要启用延迟加载,需要在mybatis-config.xml配置文件中,添加如下两个全局的settings配置。

1
2
3
4
5
<!-- 打开延迟加载的开关 -->  
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为消极加载 按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>

13.6、多对一、一对多的使用示例

13.6.1、创建一对多数据库

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
## 一对多数据表
## 创建班级表
create table t_clazz(
`id` int primary key auto_increment,
`name` varchar(50)
);

## 插入班级信息
insert into t_clazz(`name`) values('javaEE');
insert into t_clazz(`name`) values('C++');
insert into t_clazz(`name`) values('H5');
insert into t_clazz(`name`) values('LUA');

## 创建学生表
create table t_student(
`id` int primary key auto_increment,
`name` varchar(50),
`clazz_id` int,
foreign key(`clazz_id`) references t_clazz(`id`)
);

## 插入班级信息
insert into t_student(`name`,`clazz_id`) values('javaEE_1',1);
insert into t_student(`name`,`clazz_id`) values('javaEE_2',1);
insert into t_student(`name`,`clazz_id`) values('java_EE_3',1);
insert into t_student(`name`,`clazz_id`) values('C++_1',2);
insert into t_student(`name`,`clazz_id`) values('C++_2',2);
insert into t_student(`name`,`clazz_id`) values('H5_1',3);

13.6.2、<collection/> 一对多,立即加载

1
2
3
4
5
6
7
8
9
public class Student {
private Integer id;
private String name;

public class Clazz {
private Integer id;
private String name;
private List<Student> studentList;
}

Mapper接口:

1
2
3
4
5
public interface ClazzMapper {
// 一次性,根据id查询出对应班级,以及班级所有学生信息
public Clazz queryClazzById(Integer id);

}

Mapper.xml配置文件:

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
<?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.atguigu.mapper.ClazzMapper">

<resultMap id="resultMap1" type="com.atguigu.pojo.Clazz">
<id column="id" property="id" />
<result column="name" property="name" />
<!--
collection 表示集合
property表示集合的属性名
ofType 是集合中每个元素的具体类型
-->
<collection property="studentList"
ofType="com.atguigu.pojo.Student">
<id column="stu_id" property="id" />
<result column="stu_name" property="name" />
</collection>

</resultMap>
<!--
// 一次性,根据id查询出对应班级,以及班级所有学生信息
public Clazz queryClazzById(Integer id);
-->
<select id="queryClazzById" resultMap="resultMap1">
select
t_clazz.*,
t_student.id stu_id,
t_student.name stu_name
from
t_clazz left join t_student
on
t_clazz.id = t_student.clazz_id
where
t_clazz.id = #{id}
</select>


</mapper>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void queryClazzById() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);

Clazz clazz = mapper.queryClazzById(1);

System.out.println(clazz);
} finally {
sqlSession.close();
}
}

13.6.3、一对多,分步查询,赖加载

StudentMapper接口

1
2
3
4
5
6
7
public interface StudentMapper {
/**
* 根据班级编号查询学生信息
*/
public List<Student> queryStudentsByClazzId(Integer clazzId);

}

StudentMapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
<mapper namespace="com.atguigu.mapper.StudentMapper">

<!-- /**
* 根据班级编号查询学生信息
*/
public List<Student> queryStudentsByClazzId(Integer clazzId);-->
<select id="queryStudentsByClazzId" resultType="com.atguigu.pojo.Student">
select `id`,`name` from t_student where clazz_id = #{clazzid}
</select>

</mapper>

ClazzMapper接口:

1
2
3
4
5
6
7
8
public interface ClazzMapper {

/**
* 要两步查询班级信息,一次只查班级,一次只查学生<br/>
*/
public Clazz queryClazzByIdForTwoStep(Integer id);

}

ClazzMapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    <resultMap id="resultMap2" type="com.atguigu.pojo.Clazz">
<id column="id" property="id" />
<result column="name" property="name" />
<!--
collection标签不仅可以把查询回来的结果映射成为一个集合
也可以调用一个查询,得到一个集合的结果

property 是集合的属性名
select 属性指定调用哪个查询( 包名+类名+方法名 || 名称空间 + id )
column 指定哪个列做为调用方法的参数值
-->
<collection property="studentList" column="id"
select="com.atguigu.mapper.StudentMapper.queryStudentsByClazzId"
/>
</resultMap>
<!-- /**
* 要两步查询班级信息,一次只查班级,一次只查学生<br/>
*/
public Clazz queryClazzByIdForTwoStep(Integer id);-->
<select id="queryClazzByIdForTwoStep" resultMap="resultMap2">
select `id`,`name` from t_clazz where id = #{id}
</select>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void queryClazzByIdForTwoStep() throws InterruptedException {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);

Clazz clazz = mapper.queryClazzByIdForTwoStep(1);

System.out.println( clazz.getName() );

Thread.sleep(6666);

System.out.println( clazz.getStudentList() );
} finally {
sqlSession.close();
}

}

从个参数,值传递

StudentMapper接口

1
2
3
4
5
6
7
/**
* 根据班级编号查询,同时对学生姓名做模糊查询
*/
public List<Student> queryStudentsByClazzIdAndLikeName(
@Param("clazzId") Integer clazzId,
@Param("name") String name
);

StudentMapper.xml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--    /**
* 根据班级编号查询,同时对学生姓名做模糊查询
*/
public List<Student> queryStudentsByClazzIdAndLikeName(
@Param("clazzId") Integer clazzId,
@Param("name") String name
);-->
<select id="queryStudentsByClazzIdAndLikeName"
resultType="com.atguigu.pojo.Student">
select
`id`,`name`
from
t_student
where
clazz_id = #{clazzId}
and
name like concat('%',#{name},'%')
</select>

修改ClazzMapper.xml配置文件:

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
<resultMap id="resultMap2" type="com.atguigu.pojo.Clazz">
<id column="id" property="id" />
<result column="name" property="name" />
<!--
collection标签不仅可以把查询回来的结果映射成为一个集合
也可以调用一个查询,得到一个集合的结果

property 是集合的属性名
select 属性指定调用哪个查询( 包名+类名+方法名 || 名称空间 + id )
column 指定哪个列做为调用方法的参数值


/**
* 根据班级编号查询,同时对学生姓名做模糊查询
*/
public List<Student> queryStudentsByClazzIdAndLikeName(
@Param("clazzId") Integer clazzId,
@Param("name") String name
);

以上方法需要两个参数.他们在sql语句中刚好是 #{clazzId} 和 #{name}

多列赋值的格式如下:
{clazzId=值,name=值}
{clazzId=id,name=name}

-->
<collection property="studentList" column="{clazzId=id,name=name}"
select="com.atguigu.mapper.StudentMapper.queryStudentsByClazzIdAndLikeName"
/>
</resultMap>

<!-- /**
* 要两步查询班级信息,一次只查班级,一次只查学生<br/>
*/
public Clazz queryClazzByIdForTwoStep(Integer id);-->
<select id="queryClazzByIdForTwoStep" resultMap="resultMap2">
select `id`,`name` from t_clazz where id = #{id}
</select>


测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void queryClazzByIdForTwoStep() throws InterruptedException {

SqlSession sqlSession = sqlSessionFactory.openSession();
try {
ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);

Clazz clazz = mapper.queryClazzByIdForTwoStep(1);

System.out.println( clazz.getName() );

Thread.sleep(6666);

System.out.println( clazz.getStudentList() );
} finally {
sqlSession.close();
}

}

一对一

一对多看着很多

一对一或一对多拆解之后.

其实都是两个单表的查询

select属性 调用第二次的查询( 查询子对象,子集合对象 )

column 属性指定将哪个列的值做为调用的方法的参数值使用.


Mybatis-02
http://www.kju147.com/2021/07/23/Mybatis-02/
作者
个人学习
发布于
2021年7月23日
许可协议