0
点赞
收藏
分享

微信扫一扫

(面经总结)一篇文章带你整理面试过程中关于 Mybatis 底层的相关知识

霸姨 2022-05-02 阅读 26

文章目录

一、什么是 Mybatis ?

Mybatis是一个orm类型的半自动框架,执行了对JDBC的封装,是一个持久层框架,它可以通过XML文件或者注解来配置原生信息,不在需要去做更多繁琐重复的过程,如创建连接,加载驱动!

ORM 思想:
	Object Relational Mappging 对象关系映射
	简单的说:
			就是把数据库表和实体类及实体类的属性对应起来
			让我们可以操作实体类就实现操作数据库表。

二、Mybatis 优缺点及使用场合

优点

  • 基于SQL语句编译,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
  • 与JDBC相比,减少了50%的代码,消除了JDBC大量冗余的代码,不需要手动开关连接;
  • 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)
  • 能够与Spring很好的集成
  • 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护

缺点

  • SQL语句的编写工作量较大,尤其字段多,关联表多时,对开发人员编写SQL语句的功底有一定要求!
  • SQL语句依赖于数据库,导致数据库的移植性差,不能随意更换数据库。

适用场合:MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案,对性能要求很高,或者需求变化较多的项目,如互联网项目

三、#{}和${}的区别是什么?

(1)${}表示拼接 sql 串,通过${}可以将语句传入的内容拼接在 sql 中

<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="mybatis.domain.User">
select * from user where username like '%${value}%'
</select>

(2)Mybatis在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为?号,调用PreparedStatementset方法来赋值;

四、mappers 映射器对应的Dao接口的工作原理?

在这里插入图片描述
我们的 Dao 接口并没有实现类,调用它的时候,具体是怎么执行到我们的 SQL 语句的?

配置文件配置package 标签,会将对应包路径下的所有dao 类注册到 Spring 容器中,当我们通过注解注入这个 dao 接口时,返回的是一个 Dao 接口的代理对象,这个代理对象的处理器是 MapperProxy对象,所以通过@Autowired注入Dao接口的时候,注入的就是这个代理对象,我们调用到Dao接口的方法时,则会调用到MapperProxy对象的invoke()方法。

代理对象会拦截接口方法,根据类的全限定名+方法名,唯一定位到一个 MapperStatement 并调用执行器执行所代表的sql,然后将sql执行结果返回。

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">
<!--namespace确定该方法是在哪个dao接口-->
<mapper namespace="mybatis.dao.UserDao">
    <!--查询所有用户-->
    <!--id 表示方法名称,resultType 表示要封装到哪里去-->
    <select id="findAll" resultType="mybatis.domain.User">
        select * from user
    </select>
    <!--保存用户-->
    <insert id="saveUser" parameterType="mybatis.domain.User">
        insert into user(username,birthday,sex,address)
        values (#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>

五、Mybatis 的一级和二级缓存

缓存:

(1)一级缓存:SqlSession 级别的缓存

(2)二级缓存:mapper 级别的缓存

(3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。

六、Mybatis 的 Mapper 接口调用要求

(1)Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同

(2) Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同

(3)Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同

(4) Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径

<!--namespace确定该方法是在哪个dao接口-->
<mapper namespace="mybatis.dao.UserDao">
    <!--根据id查询-->
    <select id="findById" parameterType="int" resultType="mybatis.domain.User">
        select * from where id = #{uid};
    </select>
</mapper>

七、resultMap 和 resultType

(1)resultType

在这里插入图片描述
(2)resultMap

<resultMap id="userMap" type="mybatis.domain.UserTest">
        <!--主键字段的对应-->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="name"></result>
        <result property="userAddress" column="address"></result>
        <result property="userSex" column="sex"></result>
        <result property="userBirthday" column="birthday"></result>
</resultMap>

在这里插入图片描述

八、Mybatis 实现批量插入

配置useGeneratedKeyskeyProperty就可以批量插入并返回主键了

<insert id="batchInsertCameras" useGeneratedKeys="true" keyProperty="cameraNo">
    insert into camera (chanIndex,cameraName)
    values
    <foreach collection="list" item="c" separator=",">
        (#{c.chanIndex},#{c.cameraName})
    </foreach>
</insert>

具体可参考:mybatis批量插入并返回主键

举报

相关推荐

0 条评论