浅谈:MyBatis框架的学习(面试收藏!!!)

前言

本篇文章我主要分享几个我认为MyBtis比较重要的点,亦或是MyBatis在面试中高频的几个问题的分析,好~
废话不多说,我们直接开始干货!!!

一、基础概述

1.概述:

学过MyBatis的人都知道,MyBatis可以说是一种增强版的JDBC,既然和JDBC有关,那么MyBatis的作用想必大家也能够知道,自然而然离不开数据库

MyBatis是一种主流的ORM框架,之前叫做iBatis,后来更名为MyBatis,实现数据持久化的框架。

2.优点:

既然是JDBC的增强版,我们在学习JDBC的时候,可以知道JDBC的代码量是相对较多的,而MyBatis则对JDBC进行了封装,大大减少了代码量

  • 极大简化了JDBC代码的开发
  • 简单好用、容易上手、具有更好的灵活性
  • 通过将SQL定义在XML中的方式降低程序的耦合性
  • 支持动态SQL,可以根据具体业务需求灵活实现功能

3.缺点:

MyBatis是最好的嘛?任何事物都会有其的优越点,即使是优化了的JDBC也不例外

  • 相比于Hibernate,开发者需要完成更多的工作,eg:定义SQL,设置POJO与数据的映射关系等
  • 要求开发者具备一定的SQL编写能力,在一些特定场景下工作量较大
  • 数据库的移植性差,SQL依赖于底层数据库,如果进行数据库的迁移,部分SQL需要重编写

二、环境搭建问题

对于一些刚开始学习MyBatis的小伙伴来说,搭建环境可谓是令人头疼的一项操作,接下来我总结一下大家在初次搭建环境及测试时可能会出现的错误

1.配置文件没用注册

2.绑定接口错误

3.方法名不对

4.返回值类型不对

5.Maven导出资源错误

6.mysql是5.7之前在注册驱动时应该是com.mysql.jdbc.Driver
而mysql5.7之后则是com.mysql.cj.jdbc.Driver

三、CRUD注意事项

在进行数据库操作的时候:增删改要提交事务!!!

方式有两种:
手动提交: sqlSession.commit();方法提交事务
自动提交:
我们可以在编写工具类的时候,手动设置为true

//既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
// SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
    public static SqlSession getSqlSession(){
         return sqlSessionFactory.openSession(true);
    }

四、配置解析

1.环境和属性

①environments:
MyBatis 可以配置成适应多种环境,不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

Mybatis默认的事务管理器就是JDBC

连接池:POOLED

②properties:
我们可以通过properties属性来实现引用配置文件

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置【db.properties】

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

2.常见配置

接下来给大家说一下:类型别名
类型别名可为 Java 类型设置一个缩写名字。
它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:

<typeAliases>
        <typeAlias type="com.zjd.pojo.User" alias="User"/>
    </typeAliases>

或者用包名:

扫描实体类的包,它的默认别名就为这个类的 类名小写

<typeAliases>
  <package name="com.zjd.pojo"/>
</typeAliases>

总结:

实体类比较少,使用第一种方式

如果实体类过多,可以使用第二种

但是第一种可以diy起别名

第二种可以通过加注解起别名@Alias()

3.映射器

大家在第一次跑mybatis的程序时,想必都见过这个错误吧:MapperRegistry
翻译过来也就是说:未注册绑定我们的mapper文件
我们在运行时,如果不在核心配置文件中绑定我们对应接口的Mapper.xml,程序怎么能够识别呢?

方式一:

<mappers>
    <mapper resource="com/wdit/dao/userMapper.xml"/>
</mappers>

方式二:

使用class文件绑定注册

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mappers> 

注意点:

  • 接口和它的mapper配置文件必须同名
  • 接口和它的mapper配置文件必须在同一个包下

方式三:

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

注意点:

  • 接口和它的mapper配置文件必须同名
  • 接口和它的mapper配置文件必须在同一个包下

4.生命周期和作用域

SqlSessionFactoryBuilder:

  • 一旦创建了 SqlSessionFactory,就不再需要它了
  • 局部变量

SqlSessionFactory:

  • 说白了就是可以理解成:数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域
  • 最简单的就是使用单例模式或者静态单例模式。

SqlSession:

  • 连接到连接池的一个请求!
  • 用完之后需要赶紧关闭,否则资源被占用
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
    在这里插入图片描述

五、解决属性名和字段名不一致问题

有时候,我们会发现比如数据库表中写到是pwd,然而我们创建实体类的时候却写成了password,结果我们在测试时,就会报错,这种情况怎么办呢?

1.方法一:

起别名

  select id,name,pwd as password from user where id= #{id}

2.方法二:

使用ResultMap结果集映射

<!--    结果集映射-->
    <resultMap id="UserMap" type="User">
<!-- column数据库中的字段,property实体类中的属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
    
    <select id="getUserByID" resultMap="UserMap">
        select * from mybatis.user where id= #{id}
    </select>
    

六、多对一和一对多问题

多对一和一对多问题是MyBatis里常见的问题,也是面试官比较爱问的问题
在这里插入图片描述
在这里,我简单的说一下实现的两种方法:
①按照结果嵌套查询---------------------->sql语句完整
②按照查询嵌套查询---------------------->类似于子查询,sql语句嵌套sql语句
两种方法都是解决问题的方法,也没什么优略之分,但是要注意

  • 保证sql的可读性【通俗易懂】
  • 注意一对多和多对一,属性名和字段的问题
  • 问题不好排除,可以用日志

七、动态SQL

所谓动态sql,我们就可以理解成根据不同条件动态的生成sql
动态sql还是相对好理解的,在这里,我就主要说一下sql片段

<sql id="if-title-author">
    <if test="title != null">
        and title=#{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</sql>

当我们去写动态sql时发现,频繁的出现相同的代码,此时我们可以采取sql片段的方法,将重复的提取出来

<include refid="if-title-author"></include>

在后续的sql语句中,插入include标签即可使用,减少了代码的复杂量

八、缓存

这里我主要说一下MyBatis的缓存原理:
用户查询的顺序:
其实是从右往左,也就是从二级缓存----一级缓存----再去数据库
在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页