1.概述
在大多数业务场景中,我们需要查询的数据条件都是多值的,很少会有单值的条件查询,上一章节我们学习了使用map集合及@Param
注解进行多条件查询的条件封装,本章节我们来学习更多多条件查询的实际开发用例。
首先我们在对应目录下创建UserMapper2.interfac
与UserMapper2.xml
文件
UserMapper2.xml:
<?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">
<!--namespace是mybaits映射文件的唯一标识,与接口对应-->
<mapper namespace="com.study.mapper.UserMapper2">
</mapper>
UserMapper2.interfa:
package com.study.mapper;
import com.study.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface UserMapper2 {
}
并且在mybatis.config.xml配置文件中增加UserMapper2配置:
<!--Mybatis加载Mapper映射文件-->
<mappers>
<mapper resource="mybatis/mappers/UserMapper.xml"/>
<mapper resource="mybatis/mappers/UserMapper2.xml"/>
</mappers>
2.Mybatis中的集合操作
需求:查询id号 1,2,4,5,7的数据
Sql: select * from demo_user where id in (1,2,4,5,7…)
2.1 array集合操作
2.1.1 编辑测试代码
/**
* 业务: 查询id号 1,2,4,5,7的数据
*/
@Test
public void testFindInArrys(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper2 userMapper2 = sqlSession.getMapper(UserMapper2.class);
//将数据封装为数组
int[] ids = {1,2,4,5,7};
List<User> userList = userMapper2.findInArrys(ids);
System.out.println(userList);
sqlSession.close();
}
2.1.2 编辑Mapper接口
//查询id号 1,2,4,5,7的数据
List<User> findInArrys(int[] ids);
2.1.3 编辑Mapper.xml映射文件
<!-- mybatis的集合操作
知识点: 如果遇到集合参数传递,需要将集合遍历
标签: foreach 循环遍历集合
标签属性说明:
1.collection 表示遍历的集合类型
1.1 数组 关键字 array
1.2 List集合 关键字 list
1.3 Map集合 关键字 Map中的key
2. open 循环开始标签
close 循环结束标签 包裹循环体
3. separator 分割符
4. item 当前循环遍历的数据的变量
-->
<select id="findInArrys" resultType="User">
select * from demo_user where id in
<foreach collection="array" open="(" close=")"
separator="," item="id">
#{id}
</foreach>
</select>
如果遇到集合参数传递,需要使用 foreach标签将集合进行遍历,标签中的属性对应如下:
- collection 表示遍历的集合类型
- 数组:关键字 array
- List集合:关键字 list
- Map集合 :关键字 Map中的key
- 使用循环标签包裹循环体
- open 循环开始标签
- close 循环结束标签
- separator 分割符
- item 当前循环遍历的数据的变量
2.2 List集合操作
2.2.1 编辑测试代码
/*
* 业务: 查询id号 1,2,4,5,7的数据
* 知识点: 数组转化时,需要使用包装类型.
* 根源: 基本类型没有get/set方法
* 包装类型是对象 对象中有方法
*/
@Test
public void testFindInList(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper2 userMapper2 = sqlSession.getMapper(UserMapper2.class);
//将数据封装为list
/* List list = new ArrayList();
list.add(1);
list.add(2);
list.add(4);
list.add(5);
list.add(7);*/
//将数据转化为list集合
//这里要注意,数据转化时,数组需要的是包装类型
Integer[] ids = {1,2,4,5,7};
List list = Arrays.asList(ids);
List<User> userList = userMapper2.findInList(list);
System.out.println(userList);
sqlSession.close();
}
我们这里需要注意,如果需要将数组转换为list集合,那么数组需要使用包装类型,而不能使用基本类型。基本类型没有get/set方法,包装类型是对象,其默认存在方法,所以导致在将数组传入list集合时,list集合会获取数组的值,基本类型list集合获取的是其地址值,而包装类型,list才会获取到正确的保存的值。
2.2.2 编辑接口方法
List<User> findInList(List list);
2.2.3 编辑Mapper映射文件
<select id="findInList" resultType="User">
select * from demo_user where id in
<foreach collection="list" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</select>
2.3 Map集合操作
2.3.1 编辑测试类
/**
* 需求:
* 查询id=1,3,5,6,7 并且sex="男"的用户
* Sql:
* select * from demo_user where id in (1,3....)
* and sex = "男"
*/
@Test
public void testFindInMap(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper2 userMapper2 = sqlSession.getMapper(UserMapper2.class);
int[] ids = {1,3,5,6,7};
String sex = "男";
//Map方式实现
/* Map map = new HashMap();
map.put("ids",ids);
map.put("sex",sex);
List<User> userList = userMapper2.findInMap(map);*/
//多值方式实现
List<User> userList = userMapper2.findInMap(ids,sex);
System.out.println(userList);
sqlSession.close();
}
2.3.2 编辑Mapper接口
//多值需要封装为map集合
//List<User> FindInMap(Map map);
//多值方式实现
List<User> FindInMap(@Param("ids") int[] ids, @Param("sex") String sex);
2.3.3 编辑Mapper xml映射文件
<select id="findInMap" resultType="User">
select * from demo_user where id in (
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>
)
and sex = #{sex}
</select>
我们在编写sql时,也可以将小括号手动写到外边,对遍历的值进行包裹,最终实现的效果是一致的。
3. resultMap说明
3.1 创建dog表
- 表结构:选中table文件夹右键选择创建表,可以使用可视化工具直接创建表
- 表数据添加
打开新创建的表,可直接在表结构中输入表数据
完成后点击此处保存更改:
3.2 构建POJO对象
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dog implements Serializable {
private Integer dogId;
private String dogName;
}
3.3 编辑测试类
public class TestDog {
private SqlSessionFactory sqlSessionFactory;
@BeforeEach
public void init() throws IOException {
String resource = "mybatis/mybatis-config.xml";
InputStream inputStream =
Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
//查询所有dog表的数据
@Test
public void testResultMap(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DogMapper dogMapper = sqlSession.getMapper(DogMapper.class);
List<Dog> dogList = dogMapper.findAll();
System.out.println(dogList);
sqlSession.close();
}
}
3.4 编辑Mapper接口
public interface DogMapper {
List<Dog> findAll();
}
3.5 修改mybatis-config.xml文件
<!--Mybatis加载Mapper映射文件-->
<mappers>
<mapper resource="mybatis/mappers/UserMapper.xml"/>
<mapper resource="mybatis/mappers/UserMapper2.xml"/>
<mapper resource="mybatis/mappers/DogMapper.xml"/>
</mappers>
在mybatis-config.xml文件中新增Mapper映射文件。
3.6 新增mapper映射文件
<?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.jt.mapper.DogMapper">
<!--
resultType:
要求: 对象的属性名称与表中的字段一一对应.
对象: User(id,name,age,sex)
表: demo_user(id,name,age,sex)
总结: resultType适合单表映射,并且属性名称一致.
resultMap:
功能: 如果发现表中的字段与属性名称不一致时,使用resultMap映射
对象: Dog(dogId,dogName)
表: dog(dog_id,dog_name) 属性不匹配.所以映射失败
-->
<select id="findAll" resultMap="dogRM">
select * from dog
</select>
<!--
id: rm的唯一标识 type:封装之后的POJO对象
-->
<resultMap id="dogRM" type="com.jt.pojo.Dog">
<!--1.标识主键-->
<id column="dog_id" property="dogId"/>
<!--2.映射其它属性-->
<result column="dog_name" property="dogName"/>
</resultMap>
</mapper>
- resultType:
- 要求: 对象的属性名称与表中的字段一一对应.
- 对象: User(id,name,age,sex)
- 表: demo_user(id,name,age,sex)
- 总结: resultType适合单表映射,并且属性名称一致.
- resultMap:
- 功能: 如果发现表中的字段与属性名称不一致时,使用resultMap映射
- 对象: Dog(dogId,dogName)
- 表: dog(dog_id,dog_name) 属性不匹配.所以映射失败
4.关于Mybatis 注解开发说明
首先新建UserAnnoMapper接口文件。
4.1 编辑测试方法
//测试注解功能
@Test
public void testAnno(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserAnnoMapper userAnnoMapper =
sqlSession.getMapper(UserAnnoMapper.class);
List<User> userList = userAnnoMapper.findAll();
System.out.println(userList);
sqlSession.close();
}
4.2 编辑注解的接口
public interface UserAnnoMapper {
/**
* 注解使用规则:
* 1.注解标识接口方法. 接口方法调用,直接注解的内容.
* 2.注解将查询的结果集,根据方法的返回值类型动态映射.
*/
//查询user表的数据记录
@Select("select * from demo_user")
//新增 @Insert("sql")
//修改 @Update("sql")
//删除 @Delete("sql")
List<User> findAll();
}
4.3 Mybatis管理接口
<!--Mybatis加载Mapper映射文件-->
<mappers>
<mapper resource="mybatis/mappers/UserMapper.xml"/>
<mapper resource="mybatis/mappers/UserMapper2.xml"/>
<mapper resource="mybatis/mappers/DogMapper.xml"/>
<!-- 使用注解时 mybatis需要管理mapper的接口 -->
<mapper class="com.jt.mapper.UserAnnoMapper"></mapper>
</mappers>
4.4 创建UserAnnoMapper.xml
配置文件
虽然我们SQL通过注解直接标注了,但还是需要创建UserAnnoMapper.xml
文件来与接口进行对应的:
<?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">
<!--namespace是mybaits映射文件的唯一标识,与接口对应-->
<mapper namespace="com.study.mapper.UserAnnoMapper">
</mapper>
4.5 测试运行
运行我们的测试类便可以在控制台查看查询到的数据:
4.4 关于Mybatis的注解开发说明
1. 注解开发 只适用于 单表CURD操作. 多表操作一定出问题
2. 如果设计到复杂标签时 where/set/foreach 等标签时,不可以使用注解.
3. 所以应该熟练掌握xml映射文件的写法,注解开发只是辅助的作用.