源码-mybatis-01-SqlSessionFactory创建_weixin_30849591的博客-程序员秘密

技术标签: java  数据库  

0.总概

 

 
1.SqlSessionFactory在mybatis只要创建一次;
import com.suntek.vdm.gw.util.AESEncipher;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.*;
import java.util.Properties;
 
/**
* @author Binglong
*/
public class MybatisUtils {
 
    private static SqlSessionFactory factory=null;
    /**
     * 获取SqlSessionFactory,只创建一次
     * @return SqlSessionFactory
     */
    private static SqlSessionFactory getSqlSessionFactory() {
        if (null != factory){
            return factory;
        }
        synchronized (SqlSessionFactory.class){
            factory = getFactory();
        }
        return factory;
    }
 
    private static SqlSessionFactory getFactory() {
        try {
            //读取配置文件
            Reader reader= Resources.getResourceAsReader("mybatis.xml");
            //创建SQLSessionFactory
            return new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

classpath路径下的mybatis.xml配置文件(以后详解配置文件)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入配置-->
    <properties resource="conf/db.properties"/>
    <!--sql打印 -->
    <!--<settings>-->
    <!--<setting name="logImpl" value="STDOUT_LOGGING"/>-->
    <!--</settings>-->
 
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="net.sourceforge.jtds.jdbc.Driver"/>
                <!--<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>-->
                <property name="url" value="${url}"/>
                <!--<property name="username" value="${username}"/>-->
                <!--<property name="password" value="${password}"/>-->
                <!--poolMaximumIdleConnections是空闲连接数,就是没有处理请求的连接,默认是5-->
                <property name="poolMaximumIdleConnections" value="5"/>
                <!--poolMaximumActiveConnections是最大的活动连接数,活动连接,就是正在与数据库交互的连接,默认是10-->
                <property name="poolMaximumActiveConnections" value="50"/>
                <!--<property name="poolPingQuery" value="SELECT 1 FROM VDM_VR_NODE" />-->
                <!--<property name="poolPingEnabled" value="true" />-->
            </dataSource>
        </environment>
    </environments>
 
    <mappers>
        <mapper resource="com/ned/gw/mapping/UserMapper.xml"></mapper>
    </mappers>
</configuration>
2.SqlSessionFactoryBuilder构建
从上面可以看到,SqlSessionFactory主要是由SqlSessionFactoryBuilder创建,而SqlSessionFactoryBuilder提供了两种方法创建,一种基于Reader,另一种基于InputStream;两种方式都是把配置封装成 XMLConfigBuilder,然后通过 new DefaultSqlSessionFactory(config)创建;
有构造方法可以看,也要传入Properties 配置;
package org.apache.ibatis.session;
 
import java.io.*;
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, 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, 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);
    }
}

 

3.XMLConfigBuilder解析
a.而XMLConfigBuilder最终把Reader和InputStream都封装成一个 XPathParser(从字面上看估计是一个路径解析器);
b.获取到XMLConfigBuilder,还调用了其parse()方法,也就是解析配置文件(解析详情以后分析);
c.最终把所有配置封装在 Configuration中,而这个Configuration正是SqlSessioFactory实现类DefaultSqlSessioFactory的重要属性;
值得关注的是这里XMLConfigBuilder创建时Properties props参数
public class XMLConfigBuilder extends BaseBuilder {
    private boolean parsed;
    private XPathParser parser;
    private String environment;
 
 
    private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
        super(new Configuration());
        ErrorContext.instance().resource("SQL Mapper Configuration");
        this.configuration.setVariables(props);
        this.parsed = false;
        this.environment = environment;
        this.parser = parser;
    }
 
    //解析
    public Configuration parse() {
        if (this.parsed) {
            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        } else {
            this.parsed = true;
            //从配置文件configuration节点作为根节点开始
            this.parseConfiguration(this.parser.evalNode("/configuration"));
            return this.configuration;
        }
    }
 
    //从这里可以看到,解析是按顺序解析,也就是平时配置文件的标签顺序
    private void parseConfiguration(XNode root) {
        try {
            this.propertiesElement(root.evalNode("properties"));
            this.typeAliasesElement(root.evalNode("typeAliases"));
            this.pluginElement(root.evalNode("plugins"));
            this.objectFactoryElement(root.evalNode("objectFactory"));
            this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
            this.settingsElement(root.evalNode("settings"));
            this.environmentsElement(root.evalNode("environments"));
            this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
            this.typeHandlerElement(root.evalNode("typeHandlers"));
            this.mapperElement(root.evalNode("mappers"));
        } catch (Exception var3) {
            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
        }
    }

}
public class XPathParser {
    private Document document ;
    private boolean validation; //是否开启验证
    private EntityResolver entityResolver ; //用于加载本地D T D 文件
    private Properties variables ; // mybatis.xml 中<propteries> 标签定义的键位对集合
    private XPath xpath ; // XPath 对象
}
public class DefaultSqlSessionFactory implements SqlSessionFactory {
    private final Configuration configuration;
    …………
}

 

 

4.总结
SqlSessionFactory创建过程是把配置文件通过InputStream或Reader两种方式传到SqlSessionFactoryBuilder,然后SqlSessionFactoryBuilder创建一个XMLConfigBuilder,把配置信息放到XMLConfigBuilder中然后调用parse方法进行一系列解析,最终生成一个Configuration,而这个Configuration正式DefaultSqlSessionFactory的唯一属性,也就是把Configuration传入new一个DefaultSqlSessionFactory;
 
 
遗留问题
mybaitis.xml解析解析细节;
Configuration类;
 
 
 

转载于:https://www.cnblogs.com/nedhome/p/10413239.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30849591/article/details/96589122

智能推荐

【转载】从我一年编程生涯中得到的经验教训_weixin_34245082的博客-程序员秘密

一年前,我还是一个新鲜出炉刚毕业的学生,刚开始我在Rocketrip的工作。经过一年的时间,我学到了很多东西。我常常在想,要是我能早点知道这些针对应届毕业生的技巧,那么我从学生到员工的转变道路将会顺畅得多。ps:顺序先后没有特定含义1.对工作的激情能大大提升你的工作质量。2.家庭归家庭,工作归工作,不混为一谈。3.95%的电子邮件没必要立即回应。这个比例可能有待商榷,但我想说明...

这是一个关于搜索展示的流失布局,里面有详细的代码以及展示_宠歆的小王子的博客-程序员秘密

和另外一个mvp三层是同一个这是搜索页面的展示以及搜索过后展示的搜索内容 这是activity里面需要的 @BindView(R.id.sou) ImageView sou; @BindView(R.id.sou_edit_sou) EditText sou_edit_sou; /*@BindView(R.id.liuShi) Liu...

sqlalchemy ORM reflection反射学习笔记_sqlalchemy 2.0 自动反射_LQ_2021的博客-程序员秘密

把数据库模式反射到ORM风格的类中,可以使用SQLAlchemy扩展模块中的automap(自动映射)为了反射数据库,需要使用automap_base。from sqlalchemy import create_engine, selectfrom sqlalchemy.ext.automap import automap_basefrom sqlalchemy.orm import Session# 使用automap_base()创建一个Base对象Base = automap_b

python 获取硬件信息_Python实现读取机器硬件信息的方法示例_weixin_39664456的博客-程序员秘密

本文实例讲述了Python实现读取机器硬件信息的方法。分享给大家供大家参考,具体如下:本人最近新学python ,用到关于机器的相关信息,经过一番研究,从网上查找资料,经过测试,总结了一下相关的方法.# -*- coding: UTF8 -*-import osimport win32apiimport datetimeimport platformimport getpassimport soc...

网络协议和管理_weixin_30699463的博客-程序员秘密

阅读内容:  网络概念  OSI模型  网络设备  TCP/IP  IP地址  配置网络  网络工具网络协议和管理: vpn:虚拟的专有网络 感觉像一条专线,但是虚拟的 网络:网络识别通过有形或无形的媒介连接通信 网络应用程序: Web 浏览器 即时消息:QQ,微信...

随便推点

k8s 1. 先跑起来_Neil_001的博客-程序员秘密

参考:每天5分钟玩转Kubernetes, Coldman著,第一章,先把kubernetes跑起来1. 在线练习:https://kubernetes.io/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive/2.Kubernetes Bootcamp Terminal$$ miniku...

白夜行_威士忌燕麦拿铁的博客-程序员秘密

“我的愿望是在白天走路,我的人生就像是在白夜里走路。”(桐原亮司)“ 我的天空里没有太阳,总是黑夜,但并不暗,因为有东西代替了太阳。虽然没有太阳那么明亮,但对我来说已经足够。凭借着这份光,我便能把黑夜当成白天。你明白吗?我从来就没有太阳,所以不怕失去。”(唐泽雪穗) ...

linux下DHCP中继代理设置_linux 开启dhcp中继服务_回魔儒生的博客-程序员秘密

实验平台:两台LINUX服务器,一台做DHCP服务器,一台做dhcprelay中继代理服务器,三台用于测试的PC,网线若干;实验要求:分配三个网段:            192.168.5.0/24                       192.168.6.0/24                       192.168.7.0/24其中DHCP中继代理服务器的三个网卡分别为:eth0

java.lang.NoClassDefFoundError: org/apache/commons/el/Logger_启动时没有正确初始化应用程序,无法找到工厂_ziyouniao719672119的博客-程序员秘密

五月 31, 2016 7:59:34 上午 org.apache.catalina.core.StandardContext listenerStart严重: Exception sending context initialized event to listener instance of class org.apache.myfaces.webapp.StartupServletCon

C语言 JAVA处理速度,编程语言的C语言程序牺牲了什么换来了速度_编程语言_Java_Javascript_课课家..._weixin_39849894的博客-程序员秘密

网络上似乎一直有种说法:C语言程序运行时要比其他语言编写的程序快得多,因为它“离底层机器很近”,这个说法正确吗?如果正确,那究竟是什么阻止了其他语言编写的程序和C语言程序一样快呢?C语言程序快是因为它简单编程语言其实就是程序员与机器沟通的一门“外语”,可以认为编程语言是为程序员和机器服务的。事实上,在设计编程语言时,常常需要在一些问题上取舍以寻求平衡,天平的两端则分别是程序员和机器。人类和计算机的...

推荐文章

热门文章

相关标签