- 什么是mybatis?
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
这段话告诉我们mybatis是就是对数据库进行增删查改的工具,方便我们对数据库进行操作。
mybatis的工作流程
// 第一步,创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 第二步,加载配置文件
InputStream inputStream = Resources.getResourceAsStream("spring-mybatis.xml");
// 第三步,创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 第四步,创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 第五步,使用SqlSession对象执行查询
List<TUser> list = sqlSession.getMapper(TUserMapper.class).queryAll();
// 第七步,释放资源
sqlSession.close();
源代码://
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.apache.ibatis.session;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
public class SqlSessionFactoryBuilder {
public SqlSessionFactoryBuilder() {
}
public SqlSessionFactory build(Reader reader) {
return this.build((Reader)reader, (String)null, (Properties)null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return this.build((Reader)reader, environment, (Properties)null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return this.build((Reader)reader, (String)null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return this.build((InputStream)inputStream, environment, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return this.build((InputStream)inputStream, (String)null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
从源码可以看出,归根到底还是只执行了一下两个方法之一:两者区别在于输入的方式不一样(字节流和字符流)。
public SqlSessionFactory build(Reader reader, String environment, Properties properties)
和 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
至于这个方法,是调用DefaultSqlSessionFactory,这个方法是SqlSessionFactory的实现类。
完整的一次创建sqlsession过程如下:
代码:
InputStream inputStream = Resources.getResourceAsStream("spring-mybatis.xml");
源代码:
- 读取配置文件输入流:
public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
if (in == null) {
throw new IOException("Could not find resource " + resource);
} else {
return in;
}
}
该方法将配置文件转换成字节流。
代码:
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
使用SqlSessionFactoryBuilder创建sqlSessionFactory 对象
源代码:SqlSessionFactoryBuilder.build
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
}
}
XMLConfigBuilder方法(将由配置文件转换来的字节流转变成Configuration 对象)
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
传入configuration对象,调用SqlSessionFactory 的实现类DefaultSqlSessionFactory。
以上是SqlSessionFactory 创建的过程。
值得注意的是在DefaultSqlSessionFactory源代码里
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
Configuration 为final修饰的,这说明mybatis应该是单例的。
接下来是创建sqlsession对象。
在DefaultSqlSessionFactory对SqlSessionFactory 里的8个构造方法均进行了实现。
在DefaultSqlSessionFactory源码里可以看出,8个构造方法可以分为两种。
最终调用
openSessionFromDataSource
或者
openSessionFromConnection
这两种方法。
public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
return this.openSessionFromDataSource(execType, (TransactionIsolationLevel)null, autoCommit);
}
openSessionFromDataSource方法
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;//定义事务对象
DefaultSqlSession var8;
try {
//读取 之前输入的 configuration形成 Environment对象
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
//通过环境environment作为入参,获取到事务工厂
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
Executor executor = this.configuration.newExecutor(tx, execType);
//Mtbayis执行器 Executor 执行器
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
//对DefaultSqlSession进行赋值
} catch (Exception var12) {
this.closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
到此,一个sqlsession对象就实例化好了,实际上openSession 就是对DefaultSqlSession类中的成员变量赋值。
接下来是用sqlsession对象对数据库进行操作。
如果使用sqlsession.getMapper( )进行接口绑定。
getMapper()方法会返回一个map对象
MyBatis是一款持久层框架,简化了数据库操作。其工作流程包括:创建SqlSessionFactoryBuilder,加载配置文件,创建SqlSessionFactory,打开SqlSession,执行查询,最后关闭资源。源码中通过XMLConfigBuilder解析配置,构建SqlSessionFactory,再创建SqlSession,执行数据库操作。
389

被折叠的 条评论
为什么被折叠?



