Java面试——MyBatis 相关
MyBatis原理
1,MyBatis 是一个被广泛应用的持久化框架。先创建会话工厂,然后从会话工厂中打开会话
2,通过 class 类型和配置生成 Mapper 接口的代理实现,最后使用 Mapper 进行持久化操作。
3,SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession 和 Mapper 几个方面入手简单分析 MyBatis 的实现原理。
4,SqlSessionFactoryBuilder使用builder模式生成SqlSessionFactory,提供了多个builder方法,接受XML配置文件的Reader或者InputStream输入流。
5,在builder方法实现中,首先根据输入流构建xmlConfigBuilder对象,调用其parse方法解析XML文件得到Configuration对象,最后创建SqlSession返回。
2,SqlSessionFactory相关
SqlSessionFactory是个接口,默认实现DefaultSqlSessionFactory,SqlSessionFactory作用是获取SqlSession,提供了多个OpenSession方法,支持从DataSource数据源和一个给定的连接connection中创建SqlSession。
3,OpenSession方法的实现
openSession 方法的底层实现可以分为 5 步:
①从 Configuration 对象中获取环境配置 Environment;
②根据环境配置得到事务工厂 TransactionFactory;
③从事务工厂得到事务 Transaction,Transaction 包装了数据库连接,处理数据库连接的创建、准备、提交、回滚和关闭;
④创建执行器 Executor;
⑤创建 SqlSession,返回 DefaultSqlSession 的实例。
4,SqlSession相关
SqlSession 是一个接口,默认实现是 DefaultSqlSession,提供了多种数据库操作方式。如 select、selectOne、selectList、insert、update、delete、commit、rollback 和 getMapper 等方法。getMapper 方法用于获取 Mapper 接口的代理实现。
5,Executor相关
- 数据库的增删改查和事务的提交回滚都是通过 Executor 执行的。Executor 有 3 种类型 SIMPLE、REUSE、BATCH
- 默认使用简易执行器 SIMPLE,REUSE 类型执行器重用预处理语句,BATCH 类型执行器重用预处理语句和批量更新。
- Executor 对象的创建在 Configuration 类型的 newExecutor 方法中进行。
- Executor 在执行过程中,会用到 StatementHandler、ParameterHandler 和 ResultHandler
其中 StatementHandler 封装了 java.sql.Statement 的相关操作,ParameterHandler 封装了 SQL 对参数的处理
6,Mapper相关
Mapper 是通过 JDK 动态代理实现的,在 MapperProxyFactory 中创建 MapperProxy 并进行接口代理封装。
对 Mapper 接口的调用实际上是由 MapperProxy 实现的。
7,JDK 动态代理
- 在 MapperProxy 中,实现了 InvocationHandler 的 invoke 方法。
- methodCache 是一个 ConcurrentHashMap,其中存储了方法与 MapperMethod 的对应关系。
- 从 methodCache 缓存中获取或创建 MapperMethod 对象,然后调用 MapperMethod 对象的 execute 方法执行数据库操作。
8,MapperProxy
1,创建 MapperMethod 对象时,会在构造函数中初始化 SqlCommand 和MethodSignature。
2,SqlCommand 包含了数据库操作的名称,格式为 “接口名.操作名称”,以及 XML 中配置的操作类型,如 select、update等
3,把一个 Mapper 接口与 XML中的一个配置结合起来。
4,MethodSignature 是方法的签名,标记了方法的返回值类型,对于使用 RowBounds(offset 和 limit 配置)、ResultHandler(结果处理回调)作为参数的方法记录参数位置并初始化参数处理器。5,在 MapperMethod 的 execute 方法中,根据 SqlCommand 中的配置选择 SqlSession 的方法,根据 MethodSignature 的配置处理传入的参数,调用 SqlSession 的方法进行数据库操作,最后根据 MethodSignature 的返回值类型返回操作结果。
9,如何防止sql注入
- 在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。
- 这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。
简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。- 如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你得手动处理过滤一下输入的内容。
- 如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。
网友评论