一、mybatis的使用
// 1. 读取配置文件,读成字节输入流,注意:现在还没解析
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2. 解析配置文件,封装Configuration对象 创建DefaultSqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 3. 生产了DefaultSqlsession实例对象 设置了事务不自动提交 完成了executor对象的创建
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.(1)根据statementid来从Configuration中map集合中获取到了指定的MappedStatement对象
//(2)将查询任务委派了executor执行器
User user = sqlSession.selectOne("com.lagou.mapper.IUserMapper.findById",1);
System.out.println(user);
User user2 = sqlSession.selectOne("com.lagou.mapper.IUserMapper.findById",1);
System.out.println(user2);
// 5.释放资源
sqlSession.close();
1)通过Resource读取mybatis的配置文件,将文件读取为流的形式
<?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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
1.1 configuration标签内容,最主要的是dataSource标签中配置了数据库信息,用来配置数据源,type=POOLED 表示从数据源连接池中获取连接
1.2 mappers标签:存放了所有mapper.xml的全路径,读取该配置解析mapper.xml文件中的sql语句,参数类型,查询结果类型
2、通过建造者模式创建SqlSessionFactory
2.1 进入SalSessionFactory#build()方法
创建专门解析mybatis的配置文件的类XMLConfigBuilder,具体看一下XMLConfigBuilder#parse方法,看它是怎么解析mybatis的配置xml文件的。
先检查是否有解析过该配置文件,如果没有解析则将解析的表示设置为true,解析配置文件。解析xml中configuration标签下的所有内容,包括数据源信息以及mapper.xml信息。并且将解析出来的信息存入到Configuration中,Configuration中包括很多配置信息,每一条sql语句会被解析成MapperStatement对象,然后放入Configuration#mappedStatements的map中,其中map的key值为KEY:`${namespace}.${id}`。
进入parseConfiguration方法查看解析配置文件详情。
这里面解析了xml文件中的所有标签,进入解析properties标签的方法。
xml文件可以通过properties标签引入外部配置文件,可以将数据库信息配置到外部文件中,然后通过properties标签的resource或者url属性引入。这里是通过resource或者url属性读取外部文件,并且将key-value的配置放入到配置文件Properties对象中。
这里具体看一下解析mappers标签的细节:mapperElement(root.evalNode("mappers")); 遍历mappers标签中的子标签并创建MappedStatement对象,MappedStatement对象中封装了mapper标签中的sql语句,请求参数类型和响应参数类型等,一个mapper标签对应一个MappedStatement。mybatis在执行mapper中具体的sql的时候,是通过key值获取到具体的MappedStatement对象,然后进行解析执行。
这里主要看最后一条解析每条sql语句
通过XMLStatementBuilder.parseStatementNode()方法解析每一条<mapper>标签中的各个属性,这是只看解析创建sql的方法以及创建mapperstatment对象的方法
创建SqlSource对象并生成BoundSql主要是解析sql中的占位符
将占位符解析成ParameterMapping集合,最后执行的时候填入具体的参数。创建MapperStatment对象,会将对象放入到configration对象中。到此在sqlsession执行具体的查询方法的时候就可以通过key获取具体的MapperStatment对象,并解析其中的SqlSource,填充参数生成具体需要执行的sql,并执行。
3、回到第二步SqlSessionFactoryBuilder的build方法解析完mybaties的配置xml文件,解析外部配置生成数据源,并且解析配置中的所有mapper标签生成具体MapperStatment对象并且存入到Configration类中,最后生成了SqlSessionFactory对象,SqlSessionFactory对象调用openSession生成了SqlSession对象。
方法里面主要是创建了事物管理器和创建了Executor对象,Executor对象是执行sql操作的。mybatis使用了装饰者模式,如果没有开启二级缓存则创建的是SimpleExecutor对象,如果开始了缓存则创建 CachingExecutor 对象,对Executor对象进行包装。
4、创建完SqlSession对象完成之后就调用sqlSession中的方法进行查询,传入查询的ID,ID就是创建MapperStatment对象,并且将对象放入Configuration对象的Map中的key值,也就是`${namespace}.${id}`。前面说过,具体执行sql的操作是在Executor对象中完成的,查看BaseExecutor的Query方法
mybatis默认开启了一级缓存,所以这里会先从一级缓存中查询,查询不到之后再去数据库查,下面是具体的查询方法