Mybatis执行流程(一)
Mybatis执行流程(一)
wjk_snail 发表于1年前
Mybatis执行流程(一)
  • 发表于 1年前
  • 阅读 55
  • 收藏 0
  • 点赞 0
  • 评论 0

##搭建一个简单的Mybatis+Maven项目 ###Maven依赖

  <!-- 添加log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <!-- 添加mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.6</version>
        </dependency>
        <!-- 添加mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.12</version>
        </dependency>
        <!-- 添加junit驱动 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.14.8</version>
        </dependency>

###代码


@Data
public class Student {
    private Long id;
    private String name;
}

public interface StudentDao {
        public void insert(Student student);
        public Student findUserById (int id);
        public List<Student> findAllUsers();
}

public class StudentDaoTest {
    @Test
    public void findUserById() {
        SqlSession sqlSession = getSessionFactory().openSession();
        StudentDao userMapper = sqlSession.getMapper(StudentDao.class);
        Student user = userMapper.findUserById(1);
        System.out.println(user.toString());
    }

    //Mybatis 通过SqlSessionFactory获取SqlSession, 然后才能通过SqlSession与数据库进行交互
    private static SqlSessionFactory getSessionFactory() {
        SqlSessionFactory sessionFactory = null;
        String resource = "configuration.xml";
        try {
            sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }
}

###配置文件

//configuration.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配置文件, 我这里面配置的是数据库相关 -->
    <properties resource="dbConfig.properties"></properties>
    <!-- 指定Mybatis使用log4j -->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <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://localhost:3306/student"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 映射文件,mybatis精髓, 后面才会细讲 -->
    <mappers>
        <mapper resource="userDao-mapping.xml"/>
    </mappers>
</configuration>
//userDao-mapping.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
        "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.mybatis.StudentDao">
    <select id="findUserById" resultType="com.mybatis.Student" >
        select * from student where id = #{id}
    </select>
</mapper>	

##通过SqlSessionFactory获取SqlSession ###执行流程图 ###源码走读 ####获取reader

sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
Resources.getResourceAsReader(resource)

####获取SqlSessionFactory #####build()方法

//调用SqlSessionFactoryBuilder.build()方法获取SqlSessionFactory
public SqlSessionFactory build(Reader reader, String environment, Properties properties) { 
		//获取解析器
 		XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
 		//解析配置文件
      return build(parser.parse());
}

#####解析配置返回configuration

	//XMLConfigBuilder.parse()解析配置返回configuration
	public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    //configuration为根节点
    parseConfiguration(parser.evalNode("/configuration"));
    //解析完成后返回configration
    return configuration;
  }

  private void parseConfiguration(XNode root) {
  	//接下来有10个子节点,注意在configuration.xml中配置子节点的时候得按照解析的顺序
  	//这些节点的解析后面的博客再走读
    try {
      propertiesElement(root.evalNode("properties")); //issue #117 read properties first
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      settingsElement(root.evalNode("settings"));
      environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
      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);
    }
  }

#####获得SqlSessionFactory

  //通过configuration获得SqlSessionFactory
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

####获取sqlSession #####调用openSession()方法

//调用SqlSessionFactory的openSession()方法
public SqlSession openSession() {
	//主要看看这个方法
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}

######获取SqlSession

//通过DefaultSqlSessionFactoryz获取SqlSession
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      //Environment子节点获得数据连接的配置还有事务的配置
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      //获取执行器
      final Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

######获取Executor

  //Configurationz中获取执行器(Executor)
  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    //缓存配置,如下
    /* 
    	<select id="findUserById"  useCache="true" resultType="com.mybatis.Student">
        select * from student where id = #{id}
    	</select>
	 /*
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    //执行拦截器 其实就是plugins子节的配置
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

通过上面的操作变获得有含有confingration,Executor,transaction,数据库连接等的sqlsession。

参考:http://www.cnblogs.com/dongying/p/4142476.html

共有 人打赏支持
粉丝 8
博文 68
码字总数 50704
×
wjk_snail
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: