2.3 生命周期
我们在 2.2 节讨论了 MyBatis 的主要组件和它们的基本用法,而现实中要想写出高效的程序只掌握 Mybatis 的基本用法是远远不够的。我们还要掌握它们的生命周期,这是十分重要的,尤其是在 Web 应用,Socket 连接池等多线程场景中,如果我们不了解 MyBatis 组件的生命周期可能带来很严重的并发问题。这节的任务是正确理解 SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession 和 Mapper 的生命周期,并且重构上面的代码,使 MyBatis 能够高效的工作。这对于 MyBatis 应用的正确性和高性能是极其重要的,我们必须掌握它们。
2.3.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 是利用 XML 或者 Java 编码获得资源来构建 SqlSessionFactory 的,通过它可以构建多个 SessionFactory。它的作用就是一个构建器,一旦我们构建了 SqlSessionFactory,它的作用就已经完结,失去了存在的意义,这时我们就应该毫不犹豫的废弃它,将它回收。所以它的生命周期只存在于方法的局部,它的作用就是生成 SqlSessionFactory 对象。
2.3.2 SqlSessionFactory
SqlSessionFactory 的作用是创建 SqlSession,而 SqlSession 就是一个会话,相当于 JDBC 中的 Connection 对象。每次应用程序需要访问数据库,我们就要通过 SqlSessionFactory 创建 SqlSession,所以 SqlSessionFactory 应该在 MyBatis 应用的整个生命周期中。而如果我们多次创建同一个数据库的 SqlSessionFactory,则每次创建 SqlSessionFactory 会打开更多的数据库连接(Connection)资源,那么连接资源就很快会被耗尽。因此 SqlSessionFactory 的责任是唯一的,它的责任就是创建 SqlSession,所以我们果断采用单例模式。如果我们采用多例,那么它对数据库连接的消耗是很大的,不利于我们统一的管理,这样便嗅到了代码的坏味道。所以正确的做法应该是使得每一个数据库只对应一个 SqlSessionFactory,管理好数据库资源的分配,避免过多的 Connection 被消耗。
2.3.3 SqlSession
SqlSession 是一个会话,相当于 JDBC 的一个 Connection 对象,它的生命周期应该是在请求数据库处理事务的过程中。它是一个线程不安全的对象,在涉及多线程的时候我们需要特别的当心,操作数据库需要注意其隔离级别,数据库锁等高级特性。此外,每次创建的 SqlSession 都必须及时关闭它,它长期存在就会使数据库连接池的活动资源减少,对系统性能的影响很大。正如前面的代码一样,我们往往通过 finally 语句块保证我们正确的关闭 SqlSession。它存活于一个应用的请求和操作,可以执行多条 SQL,保证事务的一致性。
2.3.4 Mapper
Mapper 是一个接口,而没有任何实现类,它的作用是发送 SQL,然后返回我们需要的结果,或者执行 SQL 从而修改数据库的数据,因此它应该在一个 SqlSession 事务方法之内,是一个方法级别的东西。它就如同 JDBC 中的一条 SQL 语句的执行,它最大的范围和 SqlSession 是相同的。尽管我们想一直保存着 Mapper,但是你会发现它很难控制,所以尽量在一个 SqlSession 事务的方法中使用它们,然后废弃掉。
有了上面的叙述,我们已经清楚了 MyBatis 组件的生命周期,如图 2-6 所示。
图 2-6 MyBatis 组件的生命周期
到这里我们比较完整地描述了 MyBatis 框架和它所涉及的组件及其生命周期,接下来我们来构建一个简单的实例,以加深对 MyBatis 基础框架的理解。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论