1. Mybatis中集合操作
1.1 业务说明
需求 查询id号 1,2,4,5,7的数据
Sql: select * from demo_user where id in (1,2,4,5,7…)
1.1 array集合操作
1.1.1 编辑测试代码
/**
* 业务: 查询id号 1,2,4,5,7的数据
*/
@Test
public void testFindIn(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper2 userMapper2 = sqlSession.getMapper(UserMapper2.class);
//将数据封装为数组
int[] ids = {1,2,4,5,7};
List<User> userList = userMapper2.findIn(ids);
System.out.println(userList);
sqlSession.close();
}
1.1.2 编辑Mapper接口
1.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="findIn" resultType="User">
select * from demo_user where id in
<foreach collection="array" open="(" close=")"
separator="," item="id">
#{id}
</foreach>
</select>
1.2 List集合操作
1.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集合
Integer[] ids = {1,2,4,5,7};
List list = Arrays.asList(ids);
List<User> userList = userMapper2.findInList(list);
System.out.println(userList);
sqlSession.close();
}
1.2.2 编辑接口方法
List<User> findInList(List list);
1.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>
1.3 Map集合操作
1.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 = new HashMap();
map.put("ids",ids);
map.put("sex",sex);*/
List<User> userList = userMapper2.findInMap(ids,sex);
System.out.println(userList);
sqlSession.close();
}
1.3.2 编辑Mapper接口
1.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>
2. 动态Sql
2.1 动态 sql-where-if
2.1.1 业务需求
说明: 用户传递了一个user对象, 要求根据user中不为null的属性查询数据.
例子1:
User {name:“张三”}
Sql: select * from demo_user where name = “张三”
例子2:
User {name:“张三”, age: 18}
Sql: select * from demo_user where name = “张三” and age=18
2.1.2 编辑测试方法
/**
* 动态Sql练习 根据对象中不为null的元素查询数据
*/
@Test
public void testSqlWhere(){
User user = new User(null,"黑熊精",3000, "男");
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper2 userMapper2 = sqlSession.getMapper(UserMapper2.class);
List<User> userList = userMapper2.findSqlWhere(user);
System.out.println(userList);
sqlSession.close();
}
2.1.3 问题说明
User对象中的数据可能为null.但是如果sql不做处理,则将会把null当做参数.导致程序查询异常.
例子:
2.1.4 编辑mapper接口
List<User> findSqlWhere(User user);
2.1.5 编辑xml映射文件
<!-- 动态Sql语句
核心思想: 自动判断是否为null,
如果为null,该字段不参与sql
动态Sql规则:
1. <if test="写判断条件,可以直接获取属性值"></if>
true: 会拼接 字段条件
false: 不会拼接字段条件
2. 多余的关键字
由于动态sql拼接必然会导致多余的and 或者 or
3. where标签说明 可以去除 where后边多余的and 或者 or
-->
<select id="findSqlWhere" resultType="User">
select * from demo_user
<where>
<if test="id != null"> id = #{id}</if>
<if test="name != null">and name = #{name}</if>
<if test="age != null ">and age = #{age}</if>
<if test="sex != null ">and sex = #{sex}</if>
</where>
</select>
2.2 动态 sql-set-if
2.2.1 编辑测试类
/**
* 需求: 实现用户数据修改, 根据对象中不为null的数据完成修改操作
*/
@Test
public void testSqlSet(){
SqlSession sqlSession =
sqlSessionFactory.openSession(true);
UserMapper2 userMapper = sqlSession.getMapper(UserMapper2.class);
User user = new User(1,"守山使者",3000, null);
int rows = userMapper.updateSqlSet(user);
System.out.println("影响"+rows+"行");
sqlSession.close();
}
2.2.2 编辑Mapper接口
int updateSqlSet(User user);
2.2.3 编辑Mapper 映射文件
<!--
set标签用法: 去除set条件中多余的,号
-->
<update id="updateSqlSet">
update demo_user
<set>
<if test="name !=null"> name=#{name}, </if>
<if test="age !=null"> age = #{age}, </if>
<if test="sex !=null"> sex = #{sex} </if>
</set>
where id = #{id}
</update>
2.3 动态 sql-分支结构语法
2.3.1 业务说明
需求: 根据属性查询数据, 如果name有值 按照name查询,否则按照年龄查询,如果name,age都没有 按照sex查询
需求分析:
if(name !=null ){
name = #{name}
}else if( age !=null){
age = #{age}
}else{
sex = #{sex}
}
2.3.2 编辑测试方法
@Test
public void testChoose(){
SqlSession sqlSession =
sqlSessionFactory.openSession();
UserMapper2 userMapper = sqlSession.getMapper(UserMapper2.class);
User user = new User(null,null,null,"男");
List<User> userList = userMapper.findChoose(user);
System.out.println(userList);
sqlSession.close();
}
2.3.3 编辑Mapper接口
List<User> findChoose(User user);
2.3.4 编辑Mapper映射文件
<!--
如果只需要一个条件有效,则使用分支结构用法.
-->
<select id="findChoose" resultType="User">
select * from demo_user
<where>
<choose>
<when test="name !=null">
name = #{name}
</when>
<when test="age !=null">
age = #{age}
</when>
<otherwise>
sex = #{sex}
</otherwise>
</choose>
</where>
</select>
3. resultMap说明
3.1 创建dog表
-
表结构
-
表名
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 resultType 和resultMap的区别
<?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>
4 关于Mybatis 注解开发说明
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 关于Mybatis的注解开发说明
- 注解开发 只适用于 单表CURD操作. 多表操作一定出问题
- 如果设计到复杂标签时 where/set/foreach 等标签时,不可以使用注解.
- 所以应该熟练掌握xml映射文件的写法,注解开发只是辅助的作用.
5. 总结
- Mybatis 的集合操作
1.1 数组 foreach collection=“array”
1.2 list集合 foreach collection=“list”
1.3 Map集合 foreach collection=“map中的KEY” - foreach 用法
1.collection 表示遍历的集合类型
1.1 数组 关键字 array
1.2 List集合 关键字 list
1.3 Map集合 关键字 Map中的key
2.open 循环开始标签,close 循环结束标签 包裹循环体
3.separator 分割符
4.item 当前循环遍历的数据的变量 - 动态Sql
1.where if
<!-- 动态Sql语句
核心思想: 自动判断是否为null,
如果为null,该字段不参与sql
动态Sql规则:
1. <if test="写判断条件,可以直接获取属性值"></if>
true: 会拼接 字段条件
false: 不会拼接字段条件
2. 多余的关键字
由于动态sql拼接必然会导致多余的and 或者 or
3. where标签说明 可以去除 where后边多余的and 或者 or
-->
<select id="findSqlWhere" resultType="User">
select * from demo_user
<where>
<if test="id != null"> id = #{id}</if>
<if test="name != null">and name = #{name}</if>
<if test="age != null ">and age = #{age}</if>
<if test="sex != null ">and sex = #{sex}</if>
</where>
</select>
2.set-if set标签用法: 去除set条件中多余的,号
3.choose-when-otherwise 标识都是互斥事件,只有一个有效.
4.resultMap 字段与属性名称不一致时,使用resultMap
5.Mybatis的注解开发 @insert @update @delete @select