MyBatis笔记 | 青训营笔记

54 阅读2分钟

MyBatis

0. 什么是Mybatis

  • MyBatis是一个持久层框架,用于简化JDBC开发
  • 持久层:负责将数据保存到数据库的那一层代码
  • JavaEE三层架构:表现层,业务层,持久层
  • 框架:一个半成品的软件,是一套可重用的,通用的,软件基础代码模型
  • 在框架基础上进行开发更加高效,规范,通用,可拓展
  1. JDBC的缺点

    • 硬编码 => 配置文件

Screenshot_20221205_161514.jpg

*   操作繁琐 => 自动完成

    手动设置参数

    手动封装结果集

1. Mapper代理开发

  • 目的

    • 解决原生方法中的硬编码
    • 简化后期执行sql
  • 步骤 (Mapper代理规则)

    1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下

    2. 设置SQL映射文件的namespace属性为Mapper接口全限定名

    3. 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

    4. 编码

      1. 通过SqlSession的getMapper方法获取Mapper接口的代理对象
      2. 调用对应方法完成sql的执行
    5. 细节:如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载

      <mappers>
          <!--加载sql的映射文件 -->
          <package name="com.yx.mapper"/>
      </mappers>
      

2. MyBatis核心配置文件详解

image-20221208200042400.png

  • typeAliases类型别名

    	<typeAliases>
            <package name="com.yx.pojo"/> <!--typeAliases起了别名之后,这里就可以直接写包下的类名了 -->
        </typeAliases>
    

P.S.配置各个标签时,需遵循前后顺序

3. 动态条件查询

SQL语句会随着用户的输入或外部条件的变化而变化(动态SQL)

<!--
        多条件动态条件查询
        * if:条件判断
            * test:逻辑表达式
        * 问题:
            * 恒等式:比如加一条(1 = 1)让where后面的式子永远满足不会出现sql语法错误的情况
            * <where> 替换 where 关键字
    -->
    <select id="selectByCondition" resultMap="brandResultMap">
        select * from tb_brand
        <where>
            <if test="status != null">
                status = #{status}
            </if>
            <if test="company_name != null and company_name != ''">
                and company_name like #{company_name}
            </if>
            <if test="brand_name != null and brand_name != ''">
                and brand_name like #{brand_name};
            </if>
        </where>

    </select>
	<select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from tb_brand
        where
            <choose><!--相当于switch -->
                <when test="status != null"><!--相当于case -->
                    status = #{status}
                </when>
                <when test="company_name != null and company_name != ''">
                    company_name like #{company_name}
                </when>
                <when test="brand_name != null and brand_name != ''">
                    brand_name like #{brand_name};
                </when>
                <otherwise><!--相当于default --> <!--这里也可以用<where>标签 -->
                    1 = 1
                </otherwise>
            </choose>
    </select>

4. 添加 - 主键返回

<insert id="add" useGeneratedKeys="true" keyProperty="id"> <!--返回添加数据的主键 -->

5. 修改 - 修改动态字段

<update id="update">
        update tb_brand
        <set>
            <if test="brand_name != null and brand_name != ''">
                brand_name = #{brand_name},
            </if>
            <if test="company_name != null and company_name != ''">
                company_name = #{company_name},
            </if>
            <if test="ordered != null">
                ordered = #{ordered},
            </if>
            <if test="description != null and description != ''">
                description = #{description},
            </if>
            <if test="status != null ">
                status = #{status}
            </if>
        </set>

        where id = #{id};
    </update>

6. 删除 - 批量删除

	<delete id="deleteByIds">
        delete from tb_brand where id
        in (
            <foreach collection="array" item="id" separator="," open="(" close=")"> 
                <!--collection表示需要用foreach标签遍历的数组,seperator表示每个元素之间的分隔符,
				open表示开头写的内容 -->
                #{id}
            </foreach>
                                       );
    </delete>

7. MyBatis参数传递

MyBatis接口方法中可以接受各种各样的参数,MyBatis底层对于这些参数进行不同的封装方式

  • 单个参数

    • POJO参数
    • Map集合
    • Collection
    • List
    • Array
    • 其他
  • 多个参数:封装成Map集合,可以使用@Param注解,替换Map集合中默认的arg键名

    map.put("arg0",参数值1);
    map.put("param1",参数值1);
    map.put("param2",参数值2);
    map.put("arg1",参数值2);
    

    MyBatis提供了ParamNameResolver类来对参数进行封装

在brandMapper.xml中
数据库字段名称 与 实体类属性名称 不一致, 则不能自动封装数据
* 起别名(e.g. brand_name as brandName)
    * 缺点:每次查询都要定义一次别名
        * sql片段
            * 缺点:不灵活
* resultMap:
    1. 定义<resultMap>标签
    2. 在<select>标签中,使用resultMap属性替换 resultType属性
    
	<!--
        resultMap
    -->
    <resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brand_name"/>
        <result column="company_name" property="company_name"/>

8. 注解完成增删改查

@Select(select * from tb_user where if = #{id})
public User selectById(int id);

查询: @Select

添加: @Insert

修改: @Update

删除: @Delete

P.S.

  1. 注解开发完成简单功能
  2. 配置文件开发完成复杂功能