在第一次篇文章中,我们简单的编写运行了一个查询数据库中某一数据的大致流程,现在我们研究一下MyBatis的运行流程,他到底是以怎么样的运行方式进行运行呢?
运行流程
1、测试类中代码详细流程
我们都知道在Java中一个程序的入口是main函数,在这里也不例外。所以我们先观察main函数,而main函数在我们的Test类中编写。代码如下:
package com.rjxy.mybatis.shiyan1;
import java.io.IOException;
import java.io.Reader;
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 com.rjxy.mybatis.shiyan1.User;
public class UserTest {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
String resource = "config.xml";
//加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession();
//映射sql的标识字符串
String statement = "com.rjxy.mybatis.shiyan1.userMapper.getUser";
//执行查询返回一个唯一user对象的sql
User user = session.selectOne(statement, 1);
System.out.println(user);
}
}
第一步:
我们发现在main函数中,首先是将config.xml放到一个字符串变量中。我们知道config.xml配置文件是存放数据库信息以及Mapper文件的位置。
第二步:
是使用Resources加载配置好的配置文件,Resources是ibatis.io包下面的类,也就是一个io流,用于读写文件,通过getResourceAsStream把xml文件加载进来,把配置文件解析为一个流。存放到一个reader对象中,我们要知道Reader类是Java IO中所有Reader的基类。这里不理解没有关系,就可以理解为将配置文件信息解析出来放到了Reader的对象中。
第三步:
我们看到new了一个SqlSessionFactoryBuilder对象吗,他是SqlSessionFactory的构建者。我们调用了他的build()方法。
我们看看build方法的源码:
我们发现里面有一个XMLconfigBuilder对象,他是用来解析XML文件的一个构建者,通过他的parse()方法解析mybatis配置文件
然后我们发现parse()解析完成后,他返回了一个configuration对象,它是用来存放mybatis核心配置文件解析完成后的结果。这个configuration又返回给谁了呢?继续看源码:
又返回了一个build方法,把刚才的返回值configuration作为参数传入这个方法中,并返回了一个DefaultSqlSessionFactory对象,这是SqlSessionFactory的实现类,用来生产defaultSqlSession对象。这样上面的第三步才算真正的结束了。。
以上听不懂没有关系。我们先学习整体流程,知道new这个SqlSessionFactoryBuilder对象,是用来构建SqlSessionFactory的就好。
第四步:
我们通过sessionFactory下的openSession()方法生成了能执行映射文件中sql的sqlSession。
第五步:
我们将要执行的Mapper文件下的sql语句,那么我们怎么确定是在哪个Mapper文件下的哪个sql语句呢?回看第一步,引进了config.xml文件,在该文件中写明的所有的Mapper文件,我们只需要找到某个文件中的mapper的namespace属性和select中的id为依据找到要执行的sql语句。所以我们将要查找的namespace和id拼接成一个字符串,作为seleceOne方法中的参数,去找对应的sql语句。
<mapper namespace="com.rjxy.mybatis.shiyan1.userMapper">
<select id="getUser" parameterType="int" resultType="com.rjxy.mybatis.shiyan1.User">
select * from users where id=#{id}
</select>
</mapper>
在Mapper文件中需要知道的是查询标签中的各个属性的含义:
- id:在命名空间中唯一的标识符,可以被用来引用这条语句。
- parameterType:将会传入这条语句的参数的类全限定名或别名。(这里我们是依靠id查询的所以,传入参数的类型为int)
- resultType:期望从这条语句中返回结果的类全限定名或别名。(这里我们将查询的结果向存放到实体类中,所以值为实体类的地址)
还有些标签和上方提到的别名,我们之后使用到再介绍。
第六步:
由于我们这里目的为查询,所以我们调用session中的selectOne方法,该方法有两个参数。第一个参数表示sql语句对应的地方,第二个为查询需要的参数。将结果返回到一个实体类对象。
补充:
MyBatis 是基于 sql 映射配置的框架,sql 语句都写在 Mapper 配置文件中,在用户需要的时候,就需要去读取 Mapper 配置文件中的 sql 配置。而 mappers 标签就是用来配置需要加载的 sql 映射配置文件路径的。用户在需要时通过该标签下的内容去寻找到对应的sql语句的地址。(config.xml文件内容如下)
在接下来的两行代码中我们要知道:
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
SqlSession通过SqlSessionFactory创建。
SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
我们要进行数据库的操作,就必须要使用SqlSession中的对应方法。
<?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="db.properties"></properties>
<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="${name}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/rjxy/mybatis/shiyan1/userMapper.xml"/>
</mappers>
</configuration>
第七步
打印输出实体类,因为这个实体中覆写了toString方法,所以会自己默认调用toString方法,输出查询到的数据。