Web框架-Mybatis-核心组件
核心组件
MyBatis
的核心组件:
-
SqlSessionFactoryBuilder
(构造器):它会根据配置信息或者代码来生成SqlSessionFactory
(工厂接口)。 -
SqlSessionFactory
:依靠工厂来生成SqlSession
(会话)。 -
SqlSession
:是一个既可以发送SQL
去执行并返回结果,也可以获取Mapper
的接口。 -
SQLMapper
:它是MyBaits
新设计的组件,它是由一个Java接口和XML
文件(或 注解)构成的,需要给出对应的SQL
和映射规则。它负责发送SQL
去执行,并返 回结果。
SqlSessionFactory创建
MyBatis提供了两种模式去创建SqlSessionFactory: 一种是XML配置的方式;另一种是代码的方式。
- XML配置的方式
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--环境配置,连接的数据库,这里使用的是MySQL-->
<environments default="mysql">
<environment id="mysql">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"> </property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</dataSource>
</environment>
</environments>
<mappers>
<!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,
如果在某包下,则要写明路径,如:com/mybatistest/config/UserMapper.xml-->
<mapper resource="UserMapper.xml"></mapper>
</mappers>
</configuration>
SqlSessionFactory sqlSessionFactory = null;
String resource = "mybatis-config.xml";
InptStream inputStream;
try{
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch(IOException e){
e.printStackTrace();
}
- 代码的方式
PooledDataSource dataSource = new PooledDataSource ();//构建数据库连接池
dataSource.setDriver ("com.mysql.jdbc.Driver");
dataSource.setUrl ("jdbc:mysql://localhost:3306/mybatis");
dataSource.setUsername("root");
dataSource.setPassword("root");
//构建数据库事务方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
//创建了数据库运行环境
Environment environment = new Environment ("developmentn, transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);//构建 Configuration 对象
configuration.getTypeAliasRegistry().registerAlias(nroleH, Role.class);//注册一个MyBatis上下文别名
configuration.addMapper(RoleMapper.class);//加入一个映射器
//使用 SqlSessionFactoryBuiIder 构建 SqlSessionFactory
return new SqlSessionFactoryBuiIder().build (configuration);
SqlSession
SqlSession
接口类似于一个JDBC
中的Connection
接口对象,我们需要保证每次用完正常关闭它,所以正确的做法是把关闭SqlSession
接口的代码写在finally
语句中保证每次都会 关闭SqlSession
,让连接资源归还给数据库。
SqlSession
是MyBatis的核心接口,类似于JDBC中的Connection对象,代表着一个链接资源的启用。具体作用有三个:
- 获取Mapper接口
- 发送SQL给数据库
- 控制数据库事务
创建一个SqlSession:
SqlSession sqlSession = SqlSessionFactory.openSession();
注意:SqlSession是个门面接口,但实际上底层工作的是Executor
SqlSession事务:
sqlSession.commit();//提交事务
sqlSession.rollback();//回滚事务
sqlSession.close();
Mapper
映射器是由Java接口和XML文件(或注解)共同组成的,它的作用如下。
- 提供SQL语句,并可以配置SQL参数类型、返回类型、缓存刷新等信息
- 描述缓存与配置缓存
- 提供动态SQL
- 描述映射规则,定义查询结果和POJO的映射关系。
实现方式:
- 1.XML文件配置方式实现Mapper

xml
与pojo
是自动映射的(如:role_name <==> roleName
),只要列名一一对应即可。
- 2.Java注解方式实现Mapper

XML文件配置与注解映射比较:
- XML和注解同时使用,XML会覆盖到注解的映射
- XML可读性高,动态SQL更容易使用
- XML可以相互引入,而注解不可以
SqlSession发送SQL与用Mapper接口发送SQL
SqlSession
直接发送:
User user = (User)sqlSession.selectOne("com.example.mybatis.mapper.UserMapper.getUserById","123");
用Mapper
接口发送SQL:
UserMapper usrMapper = sqlSession.getMapper(RoleMapper.class);
User user = roleMapper.getUserById("123");
对比:
- Mapper接口可读性高
- 使用Mapper.getUserById("123"),IDE会校验和提示错误。而sqlSession.selectOne("getUserById","123");运行时才能知道是否错误产生。
为什么需要Mapper呢
Mapper
是一个接口,相对而言它可以进一步屏蔽SqlSession
这个对象,使得它具有更强的业务可读性。因此强烈建议釆用映射器方式编写代码,其好处主要有两点。
-
sqlSession.selectOne
是功能性代码,长长的字符串比较晦涩难懂,不包含业务逻辑 的含义,不符合面向对象的规范,而对于roleMapper.getRole
这样的才是符合面向对象规范的编程,也更符合业务的逻辑。 - 使用
Mapper
方式,IDE
可以检查Java语法,避免不必要的错误。
Mapper
是MyBatis
特有的接口编程模式,而iBatis
只能通过SqlSession
用SQL
的id
过滤SQL
去执行。
核心组件的生命周期
-
SqlSessionFactoryBuiler
创建了SqlSessionFactory
就是失去了作用,只存在于创建SqlSessionFactory
的方法中 -
SqlSessionFactory
可以被认为是数据库连接池,需要它来创建SqlSession
。因此它的声明周期等同于MyBatis
应用的周期。但是相应的它一般是单例的,避免大量创建占用太多资源。 -
SqlSession
相当于一个Connection
连接对象,一个事务执行完就应该关闭了。 -
Mapper
由SqlSession
创建,生命周期最多等同于SqlSession
。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder
是利用 XML
或者 Java 编码获得资源来构建 SqlSessionFactory
的,通过它可以构建多个SessionFactory
它的作用就是一个构建器,一旦我们构建了 SqlSessionFactory
,它的作用就已经完结,失去了存在的意义,这时我们就应该毫不犹豫的废弃它,将它回收。所以它的生命周期只存在于方法的局部,它的作用就是生成 SqlSessionFactory
对象。
SqlSessionFactory
SqlSessionFactory
的作用是创建SqlSession
,而SqlSession
就是一个会话,相当于JDBC
中的Connection
对象。每次应用程序需要访问数据库,我们就要通过SqlSessionFactory
创建SqlSession
,所以SqlSessionFactory
应该在MyBatis
应用的整个生命周期中。
而如果我们 多次创建同一个数据库的SqlSessionFactory
,则每次创建SqlSessionFactory
会打开更多的数 据库连接(Connection
)资源,那么连接资源就很快会被耗尽。因此SqlSessionFactory
的责任是唯一的,它的责任就是创建SqlSession
,所以我们果断釆用单例模式。
如果我们采用多例,那么它对数据库连接的消耗是很大的,不利于我们统一的管理,这样便嗅到了代码的坏味道。所以正确的做法应该是使得每一个数据库只对应一个SqlSessionFactory
,管理好数据库资源的分配,避免过多的Connection
被消耗。
SqlSession
SqlSession
是一个会话,相当于JDBC
的一个Connection
对象,它的生命周期应该是在请求数据库处理事务的过程中。它是一个线程不安全的对象,在涉及多线程的时候我们需要特别的当心,操作数据库需要注意其隔离级别,数据库锁等高级特性。此外,每次创 建的SqlSession
都必须及时关闭它,它长期存在就会使数据库连接池的活动资源减少,对 系统性能的影响很大。正如前面的代码一样,我们往往通过finally
语句块保证我们正确的关闭SqlSession
。它存活于一个应用的请求和操作,可以执行多条SQL
,保证事务的一 致性。
Mapper
Mapper
是一个接口,而没有任何实现类,它的作用是发送SQL
,然后返回我们需要的 结果,或者执行SQL
从而修改数据库的数据,因此它应该在一个SqlSession
事务方法之内, 是一个方法级别的东西。它就如同JDBC
中的一条SQL
语句的执行,它最大的范围与SqlSession
是相同的。尽管我们想一直保存着Mapper
,但是你会发现它很难控制,所以尽量在一个SqlSession
事务的方法中使用它们,然后废弃掉。
重要结论:1.SqlSessionFactory使用单例模式;2.SqlSession使用后必须关闭