Mybatis

MyBatis基本概念

什么是mybatis

2001年,Clinton Begin发起了一个名为iBATIS的开源项目,最初侧重于密码软件的研发,后来发展成为一款基于Java的持久层框架。

​ 2004年,Clinton将iBATIS的名字和源码捐赠给了Apache软件基金会。
​ 2010年,核心开发团队决定离开Apache软件基金会,并且将iBATIS改名为MyBatis。
​ MyBatis是一款优秀的支持自定义SQL查询、存储过程和高级映射的持久层框架,消除了几乎所有的JDBC代码和参数的手动设置以及结果集的检索。MyBatis可以使用XML或注解进行配置和映射,MyBatis通过将参数映射到配置的SQL形成最终执行的SQL语句,最后将执行SQL的结果映射成Java对象返回。
​ 与其他的ORM(对象关系映射)框架不同,MyBatis并没有将Java对象与数据库表关联起来,而是将Java方法与SQL语句关联。

官方文档: http://www.mybatis.org/mybatis-3/getting-started.html

工作原理

使用MyBatis之前,我们要先理解下MyBatis的工作原理。
在这里插入图片描述

工作原理

mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件(也可以用Java文件配置的方式,需要添加@Configuration)中构建出SqlSessionFactory(SqlSessionFactory是线程安全的);

然后,SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。

说明:SqlSession是单线程对象,因为它是非线程安全的,是持久化操作的独享对象,类似jdbc中的Connection,底层就封装了jdbc连接。

详细流程如下

  1. 加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。

  2. SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。

  3. SqlSession对象完成和数据库的交互:

  • 用户程序调用mybatis接口层api(即Mapper接口中的方法)

  • SqlSession通过调用api的Statement ID找到对应的MappedStatement对象

  • 通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象

  • JDBC执行sql。

  • 借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。

配置文件

mybatis-config.xml

下面根据源码分析下:
程序加载mybatis-config.xml,由SqlSessionFactoryBuilder到SqlSessionFactory的过程。

源码部分解读 SqlSessionFactoryBuilder

  1. SqlSessionFactoryBuilder加载 XMLConfigBuilder
1.public class SqlSessionFactoryBuilder {  
2.  
3.  //Reader读取mybatis配置文件,传入构造方法  
4.  //除了Reader外,其实还有对应的inputStream作为参数的构造方法,  
5.  //这也体现了mybatis配置的灵活性  
6.  public SqlSessionFactory build(Reader reader) {  
7.    return build(reader, null, null);  
8.  }  
9.  
10.  public SqlSessionFactory build(Reader reader, String environment) {  
11.    return build(reader, environment, null);  
12.  }  
13.    
14.  //mybatis配置文件 + properties, 此时mybatis配置文件中可以不配置properties,也能使用${}形式  
15.  public SqlSessionFactory build(Reader reader, Properties properties) {  
16.    return build(reader, null, properties);  
17.  }  
18.    
19.  //通过XMLConfigBuilder解析mybatis配置,然后创建SqlSessionFactory对象  
20.  public SqlSessionFactory build(Reader reader, String environment, Properties properties) {  
21.    try {  
22.      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);  
23.      //下面看看这个方法的源码  
24.      return build(parser.parse());  
25.    } catch (Exception e) {  
26.      throw ExceptionFactory.wrapException("Error building SqlSession.", e);  
27.    } finally {  
28.      ErrorContext.instance().reset();  
29.      try {  
30.        reader.close();  
31.      } catch (IOException e) {  
32.        // Intentionally ignore. Prefer previous error.  
33.      }  
34.    }  
35.  }  
36.  
37.  public SqlSessionFactory build(Configuration config) {  
38.    return new DefaultSqlSessionFactory(config);  
39.  }  
40.  
41.}  

XMLConfigBuilder

1./** 
2. * mybatis 配置文件解析 
3. */  
4.public class XMLConfigBuilder extends BaseBuilder {  
5.  public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {  
6.    this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);  
7.  }  
8.  
9.  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {  
10.    super(new Configuration());  
11.    ErrorContext.instance().resource("SQL Mapper Configuration");  
12.    this.configuration.setVariables(props);  
13.    this.parsed = false;  
14.    this.environment = environment;  
15.    this.parser = parser;  
16.  }  
17.    
18.  //外部调用此方法对mybatis配置文件进行解析  
19.  public Configuration parse() {  
20.    if (parsed) {  
21.      throw new BuilderException("Each XMLConfigBuilder can only be used once.");  
22.    }  
23.    parsed = true;  
24.    //从根节点configuration  
25.    parseConfiguration(parser.evalNode("/configuration"));  
26.    return configuration;  
27.  }  
28.  
29.  //此方法就是解析configuration节点下的子节点  
30.  //由此也可看出,我们在configuration下面能配置的节点为以下10个节点  
31.  private void parseConfiguration(XNode root) {  
32.    try {  
33.      propertiesElement(root.evalNode("properties")); //issue #117 read properties first  
34.      typeAliasesElement(root.evalNode("typeAliases"));  
35.      pluginElement(root.evalNode("plugins"));  
36.      objectFactoryElement(root.evalNode("objectFactory"));  
37.      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));  
38.      settingsElement(root.evalNode("settings"));  
39.      environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631  
40.      databaseIdProviderElement(root.evalNode("databaseIdProvider"));  
41.      typeHandlerElement(root.evalNode("typeHandlers"));  
42.      mapperElement(root.evalNode("mappers"));  
43.    } catch (Exception e) {  
44.      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);  
45.    }  
46.  }  
}  

通过以上源码,我们就能看出,在mybatis的配置文件中:

  1. configuration节点为根节点。
  2. 在configuration节点之下,我们可以配置10个子节点, 分别为:
  • properties
  • typeAliases
  • plugins
  • objectFactory
  • objectWrapperFactory
  • settings
  • environments
  • databaseIdProvider
  • typeHandlers
  • Mappers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值