Mybatis深入

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表

  1. 表结构
    在这里插入图片描述

  2. 表名
    在这里插入图片描述

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的注解开发说明

  1. 注解开发 只适用于 单表CURD操作. 多表操作一定出问题
  2. 如果设计到复杂标签时 where/set/foreach 等标签时,不可以使用注解.
  3. 所以应该熟练掌握xml映射文件的写法,注解开发只是辅助的作用.

5. 总结

  1. Mybatis 的集合操作
    1.1 数组 foreach collection=“array”
    1.2 list集合 foreach collection=“list”
    1.3 Map集合 foreach collection=“map中的KEY”
  2. foreach 用法
    1.collection 表示遍历的集合类型
        1.1 数组 关键字 array
        1.2 List集合 关键字 list
        1.3 Map集合 关键字 Map中的key
    2.open 循环开始标签,close 循环结束标签 包裹循环体
    3.separator 分割符
    4.item 当前循环遍历的数据的变量
  3. 动态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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值