Java EE轻量级框架应用实战:SSM框架(Spring MVC+Spring+MyBatis)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.1 MyBatis框架的核心接口和类

使用MyBatis框架对项目进行测试时,创建SqlSession对象的代码如下。

img

代码中涉及两个核心对象:SqlSessionFactory和SqlSession,它们在MyBatis框架中起着至关重要的作用。本节将对这两个对象进行详细讲解。首先介绍MyBatis框架的核心接口和类,如图2.1所示。

img

图2.1 MyBatis框架的核心接口和类

(1)每个MyBatis框架的应用程序都以一个SqlSessionFactory对象的实例为核心。

(2)获取SqlSessionFactoryBuilder对象,可根据XML配置文件或Configuration类的实例构建该对象。

(3)获取SqlSessionFactory对象,可以通过SqlSessionFactoryBuilder对象来获得。

(4)获取SqlSession实例,SqlSession对象包含以数据库为背景的所有执行SQL操作的方法,可以使用该实例直接执行已映射的SQL语句。

2.1.1 SqlSessionFactoryBuilder

1.SqlSessionFactoryBuilder的作用

SqlSessionFactoryBuilder负责构建SqlSessionFactory,并提供多个build()方法的重载,如图2.2所示。

img

图2.2 SqlSessionFactoryBuilder提供的build()方法

通过源码分析,可以发现它们都在调用同一签名方法:

img

由于方法参数environment和properties都可以为null,那么真正的重载方法只有如下3种。

(1)build(Reader reader,String environment,Properties properties)。

(2)build(InputStream inputStream,String environment,Properties properties)。

(3)build(Configuration config)。

通过上述分析发现,配置信息提供给SqlSessionFactoryBuilder的build()方法,包括InputStream(字节流)、Reader(字符流)和Configuration(类),由于字节流与字符流都属于读取配置文件的方式,所以从配置信息的来源就很容易想到构建一个SqlSessionFactory的两种方式:读取XML配置文件和编程。本章采用读取XML配置文件的方式。

2.SqlSessionFactoryBuilder的生命周期和作用域

SqlSessionFactoryBuilder的最大特点是用过即丢。一旦创建SqlSessionFactory后,这个类就不再需要了,因此SqlSessionFactoryBuilder的最佳范围就是存在于方法体内,也就是局部变量。

2.1.2 SqlSessionFactory

1.SqlSessionFactory的作用

SqlSessionFactory就是创建SqlSession实例的工厂,所有的MyBatis框架应用都以SqlSessionFactory实例为中心。SqlSessionFactory实例可以通过SqlSessionFactoryBuilder来获得,然后就可以使用openSession()方法来获取SqlSession实例,如图2.3所示。

img

图2.3 SqlSessionFactory提供的openSession()方法

img

当openSession()方法的参数为boolean值时,若传入true则表示关闭事务控制,自动提交;若传入false则表示开启事务控制。若不传入参数则默认为true。

img

2.SqlSessionFactory的生命周期和作用域

SqlSessionFactory一旦创建就会在整个应用运行过程中始终存在,没有理由销毁或再创建,并且在应用运行中也不建议多次创建SqlSessionFactory。因此SqlSessionFactory的最佳作用域就是Application,即随着应用的生命周期一同存在。那么这种“存在于整个应用运行期间,并且同时只存在一个对象实例”的模式就是单例模式(指在应用运行期间有且仅有一个实例)。

下面将对获取SqlSessionFactory的代码进行优化,最简单的实现方式就是放在静态代码块下,以保证SqlSessionFactory只被创建一次,其实现步骤如下。

(1)创建工具类MyBatisUtil.java,在静态代码块中创建SqlSessionFactory。

在前面的案例中,每个方法执行时都需要读取配置文件,并根据配置文件的信息构建SqlSessionFactory,然后再创建SqlSession,这就导致了大量的重复代码。为了简化开发,可以先将上述重复代码封装到一个工具类中,然后通过工具类来创建SqlSession,其代码见示例1。

img【示例1】 工具类MyBatisUtil.java

img

(2)创建 SqlSession和关闭SqlSession,其代码见示例2。

img【示例2】 创建SqlSession和关闭SqlSession

img

通过以上静态类的方式来保证SqlSessionFactory实例只能被创建一次。当然,最佳的解决方案是使用依赖注入容器—Spring框架来管理SqlSessionFactory的单例生命周期。

img

设计模式中的单例模式将在后续的Spring MVC中具体展开讲解,此处了解即可。

2.1.3 SqlSession

1.SqlSession的作用

SqlSession是用于执行持久化操作的对象,类似于JDBC的Connection。它提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句,SqlSession提供的方法如图2.4所示。

img

图2.4 SqlSession提供的方法

2.SqlSession的生命周期和作用域

SqlSession对应着一次数据库会话,由于数据库会话不是永久的,因此SqlSession的生命周期也不是永久的。相反,在每次访问数据库时都需要创建它(并不是在SqlSession里只能执行一次SQL,是完全可以执行多次的,但若关闭SqlSession则需要重新创建)。创建SqlSession的地方只有一个,就是SqlSessionFactory对象的openSession()方法。

img

每个线程都有自己的SqlSession实例,SqlSession实例不能被共享,也不是线程安全的。因此最佳的范围是在request作用域或方法体作用域内。

关闭SqlSession是非常重要的,必须确保SqlSession在finally语句块中正常关闭。关闭的标准方式如下。

img

3.SqlSession的常用方法

SqlSession中包含了很多方法,其常用方法及其说明如表2-1所示。

表2-1 SqlSession的常用方法及其说明

img

续表

img

4.SqlSession的两种使用方式

(1)通过SqlSession实例直接执行已映射的SQL语句。

如通过调用selectList方法执行用户表的查询操作,其步骤如下。

修改UserMapper.xml文件,增加查询用户列表的select节点,见示例3。

img【示例3】 增加查询用户列表的select节点

img

修改测试类UserMapperTest.java,并调用selectList方法执行查询操作,见示例4。

img【示例4】 调用selectList方法执行查询操作

img

(2)基于Mapper接口方式操作数据。

修改上一个演示示例,其步骤如下。

创建绑定映射语句的UserMapper.java接口,并提供getUserList()接口方法,该接口称为映射器,见示例5。

img

接口的方法必须与SQL映射文件中SQL语句的id相对应。

img【示例5】 UserMapper.java

img

修改测试类UserMapperTest.java,并调用getMapper(Mapper.class)执行Mapper接口方法实现对数据的查询操作,其代码见示例6。

img【示例6】 UserMapperTest.java

img

img

第1种方式是MyBatis旧版本提供的操作方式,虽然现在也可以正常工作,但第2种方式是MyBatis官方推荐使用的,其表达方式的代码更清晰且类型安全,不用担心易错的字符串字面值和强制类型转换。

2.1.4 技能训练

上机练习1 实现供应商表的查询

需求说明

在第1章练习搭建的环境中,完成以下操作。

(1)使用MyBatis框架实现对供应商表的查询操作(查询出全部数据)。

(2)编写工具类MyBatisUtil.java,获取SqlSessionFactory实例。

(3)分别使用两种方式(①通过SqlSession实例直接运行已映射的SQL语句;②基于Mapper接口方式操作数据)实现对数据的操作,并对比其区别。

img

(1)修改SQL映射文件ProviderMapper.xml,增加select元素节点,编写查询语句。

(2)编写MyBatisUtil.java,在静态代码块中实现SqlSessionFactory的创建,并在该类中增加创建SqlSession和关闭SqlSession的静态方法。

(3)创建绑定映射语句的Mapper接口:ProviderMapper.java。

(4)修改测试类ProviderMapperTest.java,按照两种方式分别实现对数据的操作,并在后台运行输出结果。