MyBatis通俗的理解

Mybatis简介:


    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。本文将通过debug的方式来了解其工作原理。

为什么学Mybatis?

  1. 目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
  2. Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。

sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。

  1. Jdbc访问数据库的过程:

  2. //加载数据库驱动
  3. //创建数据库连接
  4. //创建statement
  5. //设置sql语句
  6. //设置查询参数
  7. //执行查询,得到ResultSet
  8. //解析结果集ResultSet
  9. //释放资源

MyBatis工作流程简述

1. MyBatis和数据库的交互有两种方式:

1.1 通过传统的MyBatis提供的API:这是传统的传递statement Id和查询参数给sqlsession对象,使用sqlsession对象完成和数据库的交互;

MyBatis提供了非常方便和简单的API,供用户实现对数据库的增删改查数据操作,以及对数据库连接信息和MyBatis自身配置信息的维护操作。

上述使用MyBatis的方法,是创建一个和数据库打交道的sqlsession对象,然后根据statement Id 和参数来操作数据库,这种方式固然很简单和实用,但是它不符合面向对象语言的概念和面向接口编程的编程习惯。由于面向接口的编程是面向对象的大趋势,MyBatis为了适应这一趋势,增加了第二种使用MyBatis支持接口调用方式。

1.2 MyBatis将配置文件中的每一个<mapper> 节点抽象为一个Mapper接口,而这个接口中声明的方法和跟<mapper> 节点中的<select|update|delete|insert> 节点项对应,即<select|update|delete|insert> 节点的id值为Mapper接口中的方法名称,parameterType 值表示Mapper对应方法的入参类型,而resultMap 值则对应了Mapper接口表示的返回值类型或者返回结果集的元素类型。

 

MyBatis的实现原理:

利用反射打通Java类与SQL语句之间的相互转换。

MyBatis访问数据库代码

@Test

public void testGetUserByid() throws IOException {

// 创建SqlSessionFactoryBuilder对象

SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();

// 查找配置文件创建输入流

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 加载配置文件,创建SqlSessionFactory对象

SqlSessionFactory sqlSessionFactory = sfb.build(inputStream);

// 创建SqlSession对象

SqlSession sqlSession = sqlSessionFactory.openSession();

// 执行查询,参数一:要查询的statementId ,参数二:sql语句入参

User user = sqlSession.selectOne("user.getUserById", 1);

 

Mybatis核心类:


    SqlSessionFactory:每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或通过Java的方式构建出 SqlSessionFactory 的实例。SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,建议使用单例模式或者静态单例模式。一个SqlSessionFactory对应配置文件中的一个环境(environment),如果你要使用多个数据库就配置多个环境分别对应一个SqlSessionFactory。

    SqlSession:SqlSession是一个接口,它有2个实现类,分别是DefaultSqlSession(默认使用)以及SqlSessionManager。SqlSession通过内部存放的执行器(Executor)来对数据进行CRUD。此外SqlSession不是线程安全的,因为每一次操作完数据库后都要调用close对其进行关闭,官方建议通过try-finally来保证总是关闭SqlSession。

    Executor:Executor(执行器)接口有两个实现类,其中BaseExecutor有三个继承类分别是BatchExecutor(重用语句并执行批量更新),ReuseExecutor(重用预处理语句prepared statement,跟Simple的唯一区别就是内部缓存statement),SimpleExecutor(默认,每次都会创建新的statement)。以上三个就是主要的Executor。通过下图可以看到Mybatis在Executor的设计上面使用了装饰器模式,我们可以用CachingExecutor来装饰前面的三个执行器目的就是用来实现缓存。

动态代理dao开发规则

namespace必需是接口的全路径名
接口的方法名必需与映射文件的sql id一致
接口的输入参数必需与映射文件的parameterType类型一致
接口的返回类型必须与映射文件的resultType类型一致

动态代理dao开发步骤


创建UserMapper.xml映射文件(把原来的user.xml复制按开发规则要求修改一下)
创建UserMapper接口(把原来的UserDao.java复制按开发规则要求修改一下)
加载UserMapper.xml

动态代理

我想了个很骚的比喻,希望能解释清楚:
接口Class对象是大内太监,里面的方法和字段比做他的一身武艺,但是他没有小DD(构造器),
所以不能new实例。一身武艺后继无人。
那怎么办呢?
正常途径(implements)
写一个类,实现该接口。这个就相当于大街上拉了一个人,认他做干爹。一身武艺传给他,只是比他干爹多了小DD,可以new实例。
非正常途径(动态代理):
通过妙手圣医Proxy的克隆大法(Proxy.getProxyClass())克隆一个Class,但是有小DD。所以这个克隆人Class可以创建实例,也就是代理对象。
代理Class其实就是附有构造器的接口Class,一样的类结构信息,却能创建实例。

Java实现动态代理的两种方式
Java领域中,常用的动态代理实现方式有两种,一种是利用JDK反射机制生成代理,另外一种是使用CGLIB代理。

 

MyBatis的一二级缓存:

1、一级缓存是默认自动开启的,一级缓存的作用域是sqlsession(一次sql的会话,会话结束,缓存失效)

2、二级缓存需要手动开启,在mybatis 的配置文件中 配置参数为turn

生命周期():二级缓存范围是按照每个namepace一个缓存来存贮和维护,同一个namespace放到一个缓存对象中,当这个namaspace中执行了!isselect语句的时候,整个namespace中的缓存全部清除掉。

    开启二级缓存是可以实现sqlsession共享一个 Mapper(Namespace)数据 

    也就是二级缓存被多个 SqlSession 共享,是一个全局的变量。当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

  1. 一级缓存,一级缓存是SqlSession级别的缓存,对于相同的查询,会从缓存中返回结果而不是查询数据库
  2. 二级缓存,二级缓存是Mapper级别的缓存,定义在Mapper文件的<cache>标签中并需要开启此缓存,多个Mapper文件可以共用一个缓存,依赖<cache-ref>标签配置

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值