Python 官方文档:入门教程 => 点击学习
目录前言jdbc传统JDBC弊端思考源码分析获取数据源总结前言 上文讲的mybatis部署运行且根据官网运行了一个demo:一步到位部署运行MyBatis3源码<保姆级>
上文讲的mybatis部署运行且根据官网运行了一个demo:一步到位部署运行MyBatis3源码<保姆级>
再贴一个JDBC运行的测试方法,流程为:
@Test
public void jdbcTest(){
String driver = "com.Mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/news?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true";
String user = "root";
String pwd = "root123456";
Connection connection=null;
ResultSet rs=null;
PreparedStatement stmt=null;
try {
Class.forName(driver);
//获取数据库连接
connection = DriverManager.getConnection(url,user,pwd);
String sql = "select * from t_level where name=?";
//创建Statement对象(每一个Statement为一次数据库执行请求)
stmt=connection.prepareStatement(sql);
//设置传入参数
stmt.setString(1,"zhangsan");
//执行SQL语句
rs = stmt.executeQuery(sql);
ResultSetMetaData metaData =rs.getMetaData();
//处理查询结果-----此处未做操作
int columnCount= metaData.getColumnCount();
System.out.println(columnCount);
} catch (Exception e) {
e.printStackTrace();
}finally {
try{
//关闭结果集
if(rs!=null){
rs.close();
rs=null;
}
//关闭执行
if(stmt!=null){
stmt.close();
stmt=null;
}
if(connection!=null){
connection.close();
connection=null;
}
}catch(SQLException e){
e.printStackTrace();
}
}
}
拿JDBC测试用例和上文mybatis的测试用例对比,可以发现哪些些共同点?
@Test
public void test() throws IOException {
InputStream input = Resources.getResourceAsStream("SqlSessionConfig.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(input);
SqlSession sqlSession = sessionFactory.openSession();
LevelDao dao = sqlSession.getMapper(LevelDao.class);
List<Level> all = dao.findAll();
}
首先他们都要有数据源,这是毋庸置疑的。其次还要有执行sql语句,再有就是执行操作。
接下来进入到源码分析阶段。
由于我们是根据官网 Building SqlSessionFactory from XML的方式来测试demo的,接下来我们的解析就按照XML文件配置形式来讲解。
数据源4大元素包括:驱动、 url、 用户名、 密码。
在看代码之前,先看一下我们的配置文件结构。
mybatis是什么时候获取到数据源的呢?要从测试方法生成SqlSessionFactory说起。
通过断点进入到SqlSessionFactoryBuilder
的build
方法中,方法体就两行关键代码,首先new了一个XML 配置生成器
,接着调用了其parse()生成一个Configuration
对象。
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
parse方法执行了下面这条语句:
parseConfiguration(parser.evalnode("/configuration"));
parser.evalNode
会生成一个mybatis封装的XNode
对象,copy后发现就是我们配置文件中<configuration>
标签中的内容。
进入到parseConfiguration
方法中,可以看出好多方法的字符串参数都和我们<configuration>
标签中的一些标签名称相同。没错,每一步都是去扫描到对应参数的标签内容从而进行一些配置处理。
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
loadCustomLogImpl(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
我们此处不研究其他处内容,直接看environmentsElement
方法的内容。root.evalNode("environments")
返回的XNode对象的value就是我们的environments
标签内容。
进入到environmentsElement
方法中,会循环遍历下一级的environment
,此处便是解析xml配置多数据源的地方。
private void environmentsElement(XNode context) throws Exception {
if (context != null) {
if (environment == null) {
environment = context.getStringAttribute("default");
}
//xml配置多数据源
for (XNode child : context.getChildren()) {
String id = child.getStringAttribute("id");
if (isSpecifiedEnvironment(id)) {
TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
//<dataSource></dataSource>
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
//获得到数据库源
DataSource dataSource = dsFactory.getDataSource();
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}
dataSourceElement
方法会拿到dataSource
标签的内容生成一个DataSourceFactory
,并根据我们的配置给其属性赋值。
通过getDataSource()
方法便可以拿到我们的数据源。
最后调用configuration.setEnvironment
给到全局配置中的。
执行流程图如下:
到此这篇关于MyBatis3源码解析之如何获取数据源的文章就介绍到这了,更多相关MyBatis3获取数据源内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: MyBatis3源码解析之如何获取数据源详解
本文链接: https://www.lsjlt.com/news/152629.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0