mybatis架构设计及实例分析

使用Mapper接口和数据库交互

Mybatis将配置文件中的每一个<mapper>节点抽象为一个Mapper接口,而这个接口中声明的方法和mapper节点的<select|update|delete|insert>节点项对应。

2.数据处理层

数据处理层可以说是MyBatis 的核心,从大的方面上讲,它要完成三个功能:

a. 通过传入参数构建动态SQL语句;

b. SQL语句的执行以及封装查询结果集成List<E>

2.1.参数映射和动态SQL语句生成

动态语句生成可以说是MyBatis框架非常优雅的一个设计,MyBatis 通过传入的参数值,使用 Ognl 来动态地构造SQL语句,使得MyBatis 有很强的灵活性和扩展性。

参数映射指的是对于java 数据类型和jdbc数据类型之间的转换:这里有包括两个过程:查询阶段,我们要将java类型的数据,转换成jdbc类型的数据,通过 preparedStatement.setXXX() 来设值;另一个就是对resultset查询结果集的jdbcType 数据转换成java 数据类型。

2.2. SQL语句的执行以及封装查询结果集成List<E>

动态SQL语句生成之后,MyBatis 将执行SQL语句,并将可能返回的结果集转换成List<E> 列表。MyBatis 在对结果集的处理中,支持结果集关系一对多和多对一的转换,并且有两种支持方式,一种为嵌套查询语句的查询,还有一种是嵌套结果集的查询。

3. 框架支撑层

3.1. 事务管理机制

事务管理机制对于ORM框架而言是不可缺少的一部分

3.2. 连接池管理机制

由于创建一个数据库连接所占用的资源比较大, 对于数据吞吐量大和访问量非常大的应用而言,连接池的设计就显得非常重要

3.3. 缓存机制

为了提高数据利用率和减小服务器和数据库的压力,MyBatis 会对于一些查询提供会话级别的数据缓存,会将对某一次查询,放置到SqlSession 中,在允许的时间间隔内,对于完全相同的查询,MyBatis 会直接将缓存结果返回给用户,而不用再到数据库中查找。

3. 4. SQL语句的配置方式

传统的MyBatis 配置SQL 语句方式就是使用XML文件进行配置的,但是这种方式不能很好地支持面向接口编程的理念,为了支持面向接口的编程,MyBatis 引入了Mapper接口的概念,面向接口的引入,对使用注解来配置SQL 语句成为可能,用户只需要在接口上添加必要的注解即可,不用再去配置XML文件了,但是,目前的MyBatis 只是对注解配置SQL 语句提供了有限的支持,某些高级功能还是要依赖XML配置文件配置SQL 语句。

mysql的主要构件

  • SqlSession            作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
  • Executor              MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
  • StatementHandler   封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
  • ParameterHandler   负责对用户传递的参数转换成JDBC Statement 所需要的参数,
  • ResultSetHandler    负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
  • TypeHandler          负责java数据类型和jdbc数据类型之间的映射和转换
  • MappedStatement   MappedStatement维护了一条<select|update|delete|insert>节点的封装,
  • SqlSource            负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
  • BoundSql             表示动态生成的SQL语句以及相应的参数信息
  • Configuration        MyBatis所有的配置信息都维持在Configuration对象之中。

MyBatis把数据源分为三种:

  • unpooled 不使用连接池的数据源
  • pooled 使用连接池的数据源
  • jndi 使用jndi实现的数据源

PooledDataSource需要创建java.sql.Connection实例对象时,还是通过UnpooledDataSource来创建。PooledDataSource只是提供一种缓存机制。

DataSource什么时候创建Connection对象

当我们需要创建SqlSession对象并需要执行SQL语句时,这时候Mybatis才会去调用dataSource对象来创建java.sql.Connection对象,也就是说,java.sql.Connection对象的创建一直延迟到执行SQL语句的时候。

UnpooledDataSource如何实现getConnection方法

使用UnpooledDataSource的getConnection(),每调用一次就会产生一个新的Connection实例对象

  1. 初始化驱动:
  2. 创建Connection对象
  3. 配置Connection对象:是否自动提交和隔离级别
  4. 返回Connection对象

每调用一次getConnection()方法,都会通过DriverManager.getConnection()返回新的java.sql.Connection实例

为什么要使用连接池?

创建一个Connection对象的代价是250ms,而sql执行时间为170ms,代价很高。

使用了连接池的PooledDataSource

PooledDataSource将Connection对象包裹成PooledConnection对象放到了PoolState类型的容器中维护,MyBatis将连接池中的PooledConnection分为两种状态:空闲状态和活动状态,这两种状态的PooledConnection对象分别存储到PoolState容器内的idleConnections和activeConnections两个List集合:

  • idleConnections:调用getConnection()方法时,优先从此集合取PooledConnection对象
  • activeConnections:如果从idleConnections集合中取PooledConnection对象时,没有取到,则看此集合是否已满,如果未满,PooledDataSource会创建出一个PooledConnection,添加到此集合中,并返回。

当程序中使用完Connection对象时,如果不使用数据库连接池,一般会用connetion.close()方法,关闭connection连接,释放资源。那么使用连接池之后如何处理呢?

怎样实现Connection对象调用了close()方法,而实际是将其添加到连接池中呢

这里要使用代理模式,为真正的Connection对象创建一个代理对象,代理对象所有的方法都是调用相应的真正Connection对象的方法实现,当代理对象执行close()时,要做特殊处理,不调用真正Connection对象的close()方法,而是将Connection对象添加到连接池中。

PooledConnection对象内持有一个真正的数据库连接java.sql.Connection实例对象和一个java.sql.Connection的代理。

mybatis事务管理机制

对数据库的事务而言,应该具有以下几点:创建(create)、提交(commit)、回滚(rollback)、关闭(close),对应地,mybatis将事务抽象成了Transaction接口。

myBatis事务管理机制分两种:

  • 使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交、回滚、关闭
  • 使用MANAGED的事务管理机制:这种机制mybatis自身不会去实现事务管理,而是让程序的容器来实现对事务的管理

可看代码:JdbcTransaction和ManagedTransaction

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值