现在企业级开发中ssm是很常见的技术标配,mybatis比hibernate轻量了很多,而且学习成本相对较低,简单易上手。
那么,问题来了,简单好用的mybatis底层到底是如何实现的呢?都使用了什么原理呢?
为了深入的了解底层原理呢,写了几段简单的代码结合debug,开始学习底层咯,直接先上代码。
public class XmlReaderTest { @Test public void mybatisXmlReaderTest() { String resourceXml = "mybatis-test-config.xml"; SqlSessionFactory factory = null; SqlSession sqlSession = null; try { Reader reader = Resources.getResourceAsReader(resourceXml); factory = new SqlSessionFactoryBuilder().build(reader); sqlSession = factory.openSession(); List<Student> list = sqlSession.selectList("getStudentInfo","lily"); System.out.println(list.size()+">>>"+list.get(0).getAddress()); } catch (IOException e) { e.printStackTrace(); } finally { sqlSession.close(); } } }
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/logistics?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/springapp/mybatis/StudentMapper.xml"/> <mapper resource="com/springapp/mybatis/TeacherMapper.xml"/> </mappers> </configuration>
首先是读取mybatis的配置文件,创建工程类,获得session,调用SqlSession里面的方法进行数据库的相关操作。
factory = new SqlSessionFactoryBuilder().build(reader);主要看后面的build()方法,返回DefaultSqlSessionFactory对象:其实通过build()方法最终调的是这个方法:
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) { // Intentionally ignore. Prefer previous error. } }}在这个方法中使用了配置文件的解析类xmlconfigbuilder,重点看这一句:
return build(parser.parse()); 进入xmlconfigbuilder的parse()方法进一步查看:
public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; parseConfiguration(parser.evalNode("/configuration")); return configuration;}返回的是一个Configuration对象,其中
parser.evalNode("/configuration"),解析配置文件,返回指定节点的内容。内容如下:
<configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/logistics?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/springapp/mybatis/StudentMapper.xml"/> <mapper resource="com/springapp/mybatis/TeacherMapper.xml"/> </mappers> </configuration>
它的外层方法parseConfiguration(),进行具体的解析configuration下的子节点,并给configuration的对应变量赋值。
重点关注其中的:
environmentsElement(root.evalNode("environments")); //相当于jdbc配置数据源,以及事务的配置mapperElement(root.evalNode("mappers"));//解析sql映射文件 最后附上流程图:
时间: 2024-10-11 05:15:33