02-MyBatis

1、MyBatis中的工作原理

1、MyBatis框架的初始化操作。

        系统启动的时候会加载解析全局配置文件和对应映射文件。加载解析的相关信息存储在 Configuration 对象,Configuration是SqlSessionFactory类中的一个属性。
2、处理SQL请求的流程。

public void test1() throws  Exception{

        // 1.获取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

        // 2.加载解析配置文件并获取SqlSessionFactory对象
        // SqlSessionFactory 的实例我们没有通过 DefaultSqlSessionFactory直接来获取
        // 而是通过一个Builder对象来建造的
        // SqlSessionFactory 生产 SqlSession 对象的  SqlSessionFactory 应该是单例
        // 全局配置文件和映射文件 也只需要在 系统启动的时候完成加载操作

        // 通过建造者模式来 构建复杂的对象  1.完成配置文件的加载解析  2.完成SqlSessionFactory的创建(工厂模式)
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);

        // 3.根据SqlSessionFactory对象获取SqlSession对象
        SqlSession sqlSession = factory.openSession();

        // 4.通过SqlSession中提供的 API方法来操作数据库
        List<User> list = sqlSession.selectList("com.boge.mapper.UserMapper.selectUserList");
        // 获取接口的代码对象  得到的其实是 通过JDBC代理模式获取的一个代理对象(代理模式)
       // UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //List<User> list = mapper.selectUserList();
        System.out.println("list.size() = " + list.size());

        // 5.关闭会话
        sqlSession.close(); // 关闭session  清空一级缓存

    }

用图表示:

 SqlSessionFactory: new DefaultSqlSessionFactory  全局配置文件的加载解【Configuration】,映射文件的加载解析【Configuration,MappedStatement】

SqlSession:new DefaultSqlSession,创建相关的事务工厂,完成Executor的创建,已经二级缓存 CachingExecutor的装饰,同时完成了插件逻辑的植入。

selectOne();  二级缓存 -> 一级缓存 --> 数据库插入

2、MyBatis中的缓存设计

2.1、缓存的作用

减低数据源的访问频率。从而提高数据源的处理能力。或者提高服务器的响应速度

2.2、MyBatis中的缓存设计

1、MyBatis中的缓存的架构设计:用到了装饰器模式,对cache接口进行增强。
2、MyBatis中的一级缓存和二级缓存
        一级缓存:session级别(会话级别)
        二级缓存:SqlSessionFactory级别(进程级别)

3、缓存的设计
    通过装饰模式实现缓存功能扩展。

4、一级缓存和二级缓存的顺序问题:        先二级缓存再一级缓存

5、为什么会先走二级缓存再走一级缓存?

        二级缓存的作用域是SqlSessionFactory级别-90%找到

        一级缓存是SqlSession级别的-5%找到

        先走二级缓存再走一级缓存,为了提高效率。

6、一级缓存开关(默认是开启的) 在配置文件中设置成statement。

7、二级缓存开关(默认是关闭的) 在配置文件中将enableCache设置成true,在mapper映射文件中添加<cache/>标签。

3、MyBatis中如何实现缓存的扩展

1、考察你对MyBatis中缓存架构的理解

2、考察你对MyBatis缓存的扩展。实际动手能力

        > 创建Cache接口的实现。重新getObject和putObject方法
        > 怎么让我们自定义的实现:在mapper映射文件的 cache标签中通过type属性关联我们自定义的Cache接口的实现。

4、MyBatis中涉及到的设计模式

从MyBatis的整体架构设计来分析

缓存模块:装饰器模式

日志模块:适配器模式【策略模式】代理模式

反射模块:工厂模式,装饰器模式

Mapping:代理模式

SqlSessionFactory  :SqlSessionFactoryBuilder 建造者模式

模板方法模式:

5、谈谈你对SqlSessionFactory的理解

        SqlSessionFactory是MyBatis中非常核心的一个API。是一个SqlSessionFactory工厂。目的是创建SqlSession对象。SqlSessionFactory应该是单例。SqlSessionFactory对象的创建是通过SqlSessionFactoryBuilder来实现。在SqlSessionFactoryBuilder即完成了SqlSessionFactory对象的创建。也完成了全局配置文件和相关的映射文件的加载和解析操作。相关的加载解析的信息会被保存在Configuration对象中。

        而且涉及到了两种涉及模式:工厂模式,建造者模式

6、谈谈你对SqlSession的理解

        SqlSession是MyBatis中非常核心的一个API:作用是通过相关API来实现对应的数据库数据的操作。

SqlSession对象的获取需要通过SqlSessionFactory来实现。是一个会话级别的。当一个新的会话到来的时候。我们需要新建一个SqlSession对象来处理。当一个会话结束后我们需要关闭相关的会话资源。处理请求的方式:

1. 通过相关的增删改查的API直接处理
2. 可以通过getMapper(xxx.class) 来获取相关的mapper接口的代理对象来处理。(这个用的比较多)

7、谈谈你对MyBatis的理解

MyBatis应该是我们在工作中使用频率最高的一个ORM框架。持久层框架

1. 提供非常方便的API来实现增删改查操作
2. 支持灵活的缓存处理方案,一级缓存、二级缓存,三级缓存
3. 还支持相关的延迟数据加载的处理
4. 还提供了非常多的灵活标签来实现复杂的业务处理,if foreach where trim set bind ...
5. 相比于Hibernate会更加的灵活,Hibernate不用关注SQL语句的编写,非常重。

 8、谈谈MyBatis中的分页原理

1.谈谈分页的理解:数据太多。用户并不需要这么多。我们的内存也放不下这么多的数据
SQL:
    MySQL:limit
    Oracle:rowid

2.谈谈MyBatis中的分页如何使用

        > 先查出来总数,在执行分页,两条SQL语句

        > 使用插件pageHelper

        > 使用mybatisPlus

3,谈谈MyBatis中的分页实现

在MyBatis中实现分页有两种实现

        > 逻辑分页:RowBounds,这个没啥可说的。
        > 物理分页:拦截器实现

9、Spring中是如何解决DefaultSqlSession的数据安全问题的

        DefaultSqlSession是线程非安全的。也就意味着我们不能够把DefaultSqlSession声明在成员变量中。

        每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

        在Spring中提供了一个SqlSessionTemplate来实现SqlSession的相关的定义。然后在SqlSessionTemplate中的每个方法都通过SqlSessionProxy来操作。这个是一个动态代理对象。然后在动态代理对象中通过方法级别的DefaultSqlSession来实现相关的数据库的操作。

10、谈谈你对MyBatis中的延迟加载的理解

延迟加载:等一会加载。在多表关联查询操作的时候可以使用到的一种方案。如果是单表操作就完全没有延迟加载的概念。比如。查询用户和部门信息。如果我们仅仅只是需要用户的信息。而不需要用户对应的部门信息。这时就可以使用延迟加载机制来处理。

1。需要开启延迟加载 

<settings>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
</settings>

2。需要配置多表关联

* association 一对一的关联配置
* collection 一对多的关联配置

延迟加载的原理:代理对象

11、谈谈对MyBatis中插件的原理理解

MyBatis中的插件设计的目的是什么:方便我们开发人员实现对MyBatis功能的增强

设计中允许我们对:

        * Executor
        * ParameterHandler
        * ResultSetHandler
        * StatementHandler

        这四个对象的相关方法实现增强。

要实现自定义的拦截器:

1. 创建自定义的Java类。通过@Interceptors注解来定义相关的方法签名
2. 我们需要在对应的配置文件中通过plugins来注册自定义的拦截器

我们可以通过拦截器做哪些操作?

1. 检查执行的SQL。比如 sql 中有select * . delete from 。。。
2. 对执行的SQL的参数做处理
3. 对查询的结果做装饰处理
4. 对查询SQL的分表处理

12、使用MyBatis的mapper接口 调用时有哪些要求?也就是mapper接口文件和mapper映射文件的使用规范。

MyBatis中的Mapper接口实现的本质是代理模式

1. Mapper映射文件的namespace的值必须是Mapper接口对应的全类路径的名称
2. Mapper接口中的方法名必须在mapper的映射文件中有对应的sql的id
3. Mapper接口中的入参类型必须和mapper映射文件中的每个sql 的parameterType类型相同
4. Mapper接口中的出参类型必须和mapper映射文件中的么个sql的resultType类型相同
5. 接口名称和Mapper映射文件同名

13、如何获取MyBatis中自增的主键

需要获取自增的主键:在同一个事务中操作多表。我们需要关联的id信息。

userMapper映射文件:

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    
</insert>

java文件:

User user = new User();
userMapper.insertUser(user);
System.out.println("自增的主键:id" + user.getId());

14、不同Mapper(映射文件)中的id是否可以相同?

可以相同:每一个映射文件的namespace都会设置为对应的mapper接口的全类路径名称。也就是保证了每一个Mapper映射文件的namespace是唯一的。那么我们只需要满足在同一个映射文件中的id是不同的就可以了。

eg:

UserMapper.xml: com.boge.mapper.UserMapper  #selectList

RoleMapper.xml com.boge.mapper.RoleMapper   #selectList

15、谈谈你对MyBatis的架构设计的理解

1. 接口层:面向开发者。提供相关的API
2. 核心层:MyBatis的核心功能的实现:增删改查操作
3. 基础模块:由很多相互之间没有关联的模块组成。作用是支持核心层来完成核心的功能。

16、传统JDBC的不足和MyBatis的解决方案

1. 我们需要频繁的创建和释放数据库库的连接对象。会造成系统资源的浪费。从而影响系统的性能,针对这种情况我们的解决方案是数据库连接池,例如DBCP数据库连接池。然后在MyBatis中的全局配置文件中我们可以设置相关的数据库连接池。当然和Spring整合后我们也可以配置相关的数据库连接。
2. SQL语句我们是直接添加到了代码中了,造成维护的成本增加。所以对应SQL的动态性要求比较高。这时我们可以考虑把SQL和我们的代码分离,在MyBatis中专门提供了映射文件。我们在映射文件中通过标签来写相关的SQL。
3. 向SQL中传递参数也很麻烦,因为SQL语句的where条件不一定。可能有很多值也可能很少。占位符和参数需要一一对应。在MyBatis中自动完成java对象和sql中参数的映射。
4. 对于结果集的映射也很麻烦,主要是SQL本身的变化会导致解析的难度。我们的解决方案。在MyBatis中通过ResultSetHandler来自动把结果集映射到对应的Java对象中。
5. 传统的JDBC操作不支持事务。缓存。延迟加载等功能。在MyBatis中都提供了相关的实现。

17、谈谈你对MyBatis中的Executor的理解

Executor的类型有三类:

* SIMPLE:默认  SimpleExecutor:每次操作都是一个新的Statement对象
* REUSE: ReuseExecutor,会根据SQL缓存Statement对象。实现Statement对象的复用
* BATCH: BatchExecutor 批处理

我们可以通过SalSessionFactory这个类的openSession(Executor executor)的重载方法,查看ExecutorType。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值