侧边栏壁纸
博主头像
Mr.D的小破站博主等级

身如柳絮随风扬,无论云泥意贯一

  • 累计撰写 21 篇文章
  • 累计创建 9 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

MyBatis

Mr.D
2024-10-29 / 0 评论 / 0 点赞 / 8 阅读 / 14431 字

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

#{}就是SQL中的?号,调用preparedStatement的set方法来复制,防止sql注入,提高系统安全。

${}替换成变量的值

2、Mybatis和ORM、hibernate(jpa)有什么区别?(Object Relation Mapping)

mybatis和hibernate都同处于持久层的框架。

mybatis是粗粒度封装,hibernate是细粒度封装。

mybatis是一个半ORM(对象关系映射)框架,内部封装了JDBC,开发是只关注sql语句,不需要加载驱动,创建连接等繁杂操作

hibernate对象关系映射能力强,直接面向对象编程,不用关心sql

3、Mybatis怎么封装动态SQL?(常见的动态sql的标签)

where,if,set,foreach,trim,choose,when,otherwise

4、Mybatis怎么实现分页?

利用分页插件pageHelper,基本原理是,使用mybatis提供的插件接口,实现自定义插件,在插件的方法内拦截要执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

5、Mybatis使用了哪些设计模式?

MyBatis中用到的设计模式_mybatis用到哪些设计模式-CSDN博客

  1. Builder模式

    1. 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。例如:SqlSessionFactoryBuilderXMLConfigBuilder

    2. 一般来说,如果一个对象的构建比较复杂,超出了构造函数的包含范围,就可以使用工厂模式和Builder模式。相对于工厂模式会产出一个完整的产品,Builder应用于更加复杂的对象创建。在规范中遇到多个构造器参数时,就可以考虑构建者模式。

  2. 单例模式

    1. 单例模式确保某个类只能有一个实例,而且自行实例化并向整个系统提供这个实例。这个类为单例类,提供全局访问的方法。

  3. 工厂模式

    1. 比如SqlSessionFactory使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单的工厂模式

    2. 简单工厂模式(Simple Factory Pattern)可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类

  4. 代理模式

    1. 代理模式是Mybatis的核心使用的模式。

    2. 代理模式(Proxy Pattern)定义:它是一个对象结构型模式,给某个对象提供一个代理,并由代理对象控制对原对象的引用。

  5. 模板方法模式

    1. 定义:一个设计师给出一个算法的轮廓和骨架,另一个设计师给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法叫做基本方法。把这些基本方法汇总起来就是模板方法。例如:BaseExcutorSimpleExecutor

6、Mybatis如何实现主键回填?

可以联动业务场景

在购物交易的时候,付完钱之后一般都会返回一个订单编号,其实这个订单编号在数据库中就是主键,但是在插入时id的值为null,所以订单编号应该为null。

如果插入数据的时候写id,数据量庞大起来就是很科学

还有个方法就是插入后再查寻这条数据,但是非常麻烦。

所以诞生了主键回填

什么是主键回填?

|——把插入数据时,把插入为null的主键id数据填回去。实现添加+查询一步到位。

  1. 主键自增

    1. 这种方式比较简单,就是在插入节点上添加useGeneratedKeys属性,同时设置接收回传主键的属性。(配置完成后,我们执行一个插入操作,插入时传入一个对象,插入完成后,这个对象的 id 就会被自动赋值,值就是刚刚插入成功的id。)

    <insert id="insertBook" userGeneraterKeys="true" keyProperty="id">
        insert into t_book(b_name,author) values (#{name},#{author});
    </insert>
  2. 自定义主键自增

    1. 利用MySQL自带的last_insert_id()函数查询刚刚插入的id,这种方式是在 insert 节点中添加 selectKey 来实现主键回填,可以再插入前执行,也可以再插入后执行

    <insert id="insertBook">
        <selectKey order="BEFORE" keyProperty="id" resultType="java.lang.Interger">
            SELECT LAST_INSERT_ID();
        </selectKey>
        insert into t_book(b_name,author) values (#{name},#{author}); 
    </insert>
    ​
    //order:sql语句再插入语句中的执行顺序

7、Mybatis一级缓存和二级缓存有什么区别?

  • 一级缓存SqlSession级别的缓存,作用域SqlSession内,底层使用map集合实现,当Session flush或close之后,Session中的Cache将会清空,默认打开一级缓存

  • 二级缓存时SqlSessionFactory级别的缓存,作用域是针对mapper进行缓存,不同的sqlSession可以共享。默认不打开二级缓存,要开启二级缓存,要实现Serializable序列化接口,可以映射文件中的配置。

8、mybatis的实现原理?

  1. 读取mybatis的全局配置文件

  2. 加载映射文件,该文件配置了操作数据库的sql语句

  3. 构造会话工厂SqlSessionFactory

  4. 构建会话对象SqlSession,对象包含执行sql语句的所有方法

  5. Executor执行器操作数据库,根据SqlSession传递的参数动态的生成要执行的sql语句,负责查询缓存的维护

  6. MappedStatement对象是映射信息的封装,用于存储要映射的sql语句的id、参数等信息,

  7. 输入参数映射。参数类型可以是map、list、基本数据类型,pojo类型

  8. 输出结果映射。

源码:

  1. 根据配置文件初始出Configuration对象

  2. 创建一个DefaultSqlSession对象,它里面包括Configuration和Exucutor

  3. 执行DefaultSqlSession.getMapper(),拿到Mapper接口对的MapperProxy

  4. MapperProxy就有DefaultSqlSession

  5. 执行增删改查方法:

    1. 调用DefaultSqlSession的crud

    2. 创建一个StatementHandler对象

    3. 调用StatementHandler预编译参数以及设置参数值;使用ParameterHandler的crud方法

    4. 调用StatementHandler的crud方法

    5. ResultSetHandler封装结果

9、插件原理?

在MyBatis中插件是通过拦截器来实现的,拦截的对象为Executor、StatementHandler、ParameterHandler、ResultSetHandler。

将四大对象都放到pluginAll做一个处理,有返回一个对象。对原对象进行动态代理,代理的时候加入拦截器执行。注意并不是四大对象的所有方法都会拦截。

10、通常一个Xml映射文件,都会写一个Dao接口与之对应, 请问,这个Dao接口的工作原理是什么?

Dao接口里的方法, 参数不同时,方法能重载吗?

Dao接口,也叫mapper接口。接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement。

Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

11、如何执行批量插入?

  1. foreach,通过拼接sql语句的方式完成批量操作的。拼接的sql语句过多,导致sql大小超过了mysql服务器中max_allowed_packet变量的值,抛出PacketTooBigException异常,在mysql上调大该值,默认为4M

  2. 批量插入,打开sqlSession的时候指定:ExecutorType.BATCH

12、MyBatis实现一对一映射,一对多映射

  1. association

  2. collection

13、Mybatis是否支持延迟加载?

如果支持,它的实现原理是什么?

mybatis仅支持association关联对象和collection关联集合对象的延迟加载。在mybatis配置文件中,可以配置是否启用延迟加载(lazyLoadingEnabled),默认是关闭的,使用的时候在发送sql去进行查询。

原理是使用cglib(code generation library)创建目标对象的代理对象。当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。


0
博主关闭了当前页面的评论