首页 > 服务器 正文
SqlSession是如何创建的?

时间:2022-11-17 05:42:06 阅读: 评论: 作者:

  #头条创作挑战赛#

  前言

    上文学习了mybatis在启动的时候都做了什么操作,这里继续往下学习。

  SqlSession

    每一个会话就有一个SqlSession,SqlSession是和数据库沟通的桥梁,它提供了一些操作数据库的相关命令以及事务的相关处理,一些增删改查、获取连接配置信息、关闭会话、事务提交回滚等等,使用方法如 Person p = session.selectOne("cn.mybatis.mydemo.mapper.PersonMapper.selectPersonById", 1);不过官方不推荐这样的使用方式,推荐使用如下的调用方式:

  // 获得mapper接口的代理对象PersonMapper pm = session.getMapper(PersonMapper.class);// 直接调用接口的方法,查询id为1的Peson数据Person p = pm.selectPersonById(1);

  SqlSession如何创建的?

    前面学习到了,创建了SqlSessionFactory,默认创建的就是 DefaultSqlSessionFactory那么这里面都是些啥呢?可以看到提供了很多的openSession方法都是返回SqlSession对象的,也就是SqlSessionFactory的openSession创建了SqlSession对象。

  创建SqlSession的时候做了什么操作?

    通过上面的源码截图可以看到,openSession下面有两种实现:

  openSessionFromDataSourceopenSessionFromConnectionopenSessionFromDataSource

    通过上文说的初始化之后存储数据的configuration获取一下环境信息;然后利用环境信息获取一下事务工厂;使用事务工厂创建事务;然后就可以创建一个执行器;之后就可以创建一个SqlSession对象。

    这些都是啥,先思考下:如果我要去钓鱼,我会有那几个步骤呢?

  确认钓鱼地点,我要知道去哪里钓鱼。确认钓鱼管理规定,去钓鱼的地方,对钓鱼有没有啥管理啊,万一钓着钓着被人打了出来呢,做好准备。确认钓鱼工具,我至少也要有个鱼竿吧,再来点鱼饵。上述条件满足了,我 去 钓鱼。  假设:水塘,就是存放数据的数据库。鱼,就是要从数据库查询的数据。钓鱼管理规定应对方案,就是事务控制。钓鱼工具,就是可以实现具体交互逻辑的执行器。有了这些,就可以创建一个可以对数据库操作的对象SqlSession。

    这里的源码先不跟进去了,我大致看了下比较深,细节比较多,后面专门写,就简单对几个入参说明下吧

  ExecutorType:顾名思义,执行器类型。用这玩意儿选择要用哪种执行器SimpleExecutor是每次都会关闭statement,意味着下一次使用需要重新开启statement。ReuseExecutor不会关闭statement,而是把statement放到缓存中。缓存的key为sql语句,value即为对应的statement。也就是说不会每一次调用都去创建一个 Statement 对象,而是会重复利用以前创建好的(如果SQL相同的话),这也就是在很多数据连接池库中常见的 PSCache 概念 。BatchExecutor是批处理型执行器,doUpdate预处理存储过程或批处理操作,doQuery提交并执行过程。SimpleExecutor 比 ReuseExecutor 的性能要差 , 因为 SimpleExecutor 没有做 PSCache。为什么做了 PSCache 性能就会高呢 , 因为当SQL越复杂占位符越多的时候预编译的时间也就越长,创建一个PreparedStatement对象的时间也就越长。猜想中BatchExecutor比ReuseExecutor功能强大性能高,实际上并非如此,BatchExecutor是没有做PSCache的。BatchExecutor 与 SimpleExecutor 和 ReuseExecutor 还有一个区别就是 , BatchExecutor 的事务是没法自动提交的。因为 BatchExecutor 只有在调用了 SqlSession 的 commit 方法的时候,它才会去执行 executeBatch 方法。

  TransactionIsolationLevel:隔离级别,分别是无事务、读已提交、读未提交、可重复读、串行化。

  autoCommit:自动提交,bool值;就是是否自动提交的标记;true:自动提交false:不自动提交openSessionFromConnection

    乍一看,好似和前面的没啥区别,其实不太一样,看我选中的地方,创建事务用的是Connection对象。也就是说,这个是已经有的连接中创建SqlSession,而上面那个则是从数据库连接池中创建SqlSession。

    一样,源码先不跟进去了,说明下参数:

  ExecutorType:同上Connection:与特定数据库的连接(会话)。在连接的上下文中执行SQL语句并返回结果。Connection对象的数据库能够提供描述其表、其的SQL语法、其存储过程、此连接的功能等的信息。该信息是通过getMetaData方法获得的。注意:在配置连接时,JDBC应用程序应该使用适当的连接方法,如setAutocommit或setTransactionIsolation。当有JDBC方法可用时,应用程序不应该直接调用SQL命令来更改连接的配置。默认情况下,Connection对象处于自动提交模式,这意味着它在执行每个语句后自动提交更改。如果已禁用自动提交模式,则必须显式调用commit方法以提交更改;否则,数据库更改将不会被保存。使用JDBC 2.1核心API创建的新Connection对象具有与之关联的初始空类型映射。用户可以在此类型映射中为UDT输入自定义映射。当使用Resultset方法从数据源检索UDT时。getobject方法将检查连接的类型映射,以查看是否有针对该UDT的条目。如果是,getobject方法将把UDT映射到指定的类。如果没有条目,将使用标准映射映射UDT。用户可以创建一个新的类型映射,即java.util。映射对象,在其中创建一个条目,并将其传递给java。可以执行自定义映射的SQL方法。