名字简记
> SqlSessionFactoryBuilder => 工厂构造者
> SqlSessionFactory => 工厂
> sqlsession => 产品
> Mapper => 接口
一丶工厂构造者创建工厂
源码部分:
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
--进入build方法
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
--实际调用的build方法
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
...
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
...
}
--调用build,返回默认工厂
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
--进入parse()
public Configuration parse() {
if (this.parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
} else {
this.parsed = true;
this.parseConfiguration(this.parser.evalNode("/configuration"));
return this.configuration;
}
}
--DefaultSqlSessionFactory.class 实现 SqlSessionFactory接口
--主要方法
--构造器
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
---获取刚才构建工厂中,保存的configuration
public Configuration getConfiguration() {
return this.configuration;
}
--生成产品方法
public SqlSession openSession() {
return this.openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit);
}
--openSessionFromDataSource() 方法
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
DefaultSqlSession var8;
try {
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
Executor executor = this.configuration.newExecutor(tx, execType);
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var12) {
this.closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
--执行sql
public <T> T selectOne(String statement) {
return this.selectOne(statement, (Object)null);
}
思路:
调用SqlSessionFactoryBuilder.class 中的build方法,从XMLConfigBuilder可以看出将xml配置类转换为java类 通过parser.parse()方法下的this.parseConfiguration(this.parser.evalNode("/configuration")); 解析xml文件。所以在xml下的配置顺序为properties 属性,settings 设置,typeAliases 类型别名,typeHandlers 类型处理器,objectFactory 对象工厂,plugins 插件 ,environments 环境,environment 环境变量,transactionManager 事务管理器,dataSource 数据源,databaseIdProvider 数据库厂商标识,mappers 映射器。
进入parse()将解析的数据保存到一个configuration类中。 最后build方法,放回一个默认的工厂(DefaultSqlSessionFactory.class),将刚才的configuration类传入默认工厂中,生成产品方法,调用最后返回一个默认的产品DefaultSqlSession.class,在这个类中,发现有很多类似生成产品的方法 例:selectOne.
总体思路:
1.构建者通过xml文件,读取配置,生成java配置类,在建造工厂的时候已经生成好了MapperProxyFactory代理工厂,put的key就是 接口类 的类名 2.通过build,返回默认工厂 DefaultSqlSessionFactory 和 默认产品DefaultSqlSession 3.默认产品下多个默认执行sql的方法 。
设计模式
简单工厂模式 DefaultSqlSessionFactory,SqlSessionFactory 简单工厂模式的好处:解耦,我们只需要知道使用而不需要具体的创建,减少重复的代码,统一管理创建对象的逻辑。
为什么要用这个设计模式?
如果每次都要读取配置文件,再去创建工厂,而后再取得产品,代码存在太多的重复,那么需要一个工厂类来封装此操作,同时添加关闭的操作;