Mybatis執行流程(一)

##搭建一個簡單的Mybatis+Maven項目 ###Maven依賴html

<!-- 添加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>

###代碼java

@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;
    }
}

###配置文件mysql

//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 ###執行流程圖 ###源碼走讀 ####獲取readersql

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());
}

#####解析配置返回configurationapache

//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()方法session

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

######獲取SqlSessionmybatis

//經過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();
    }
  }

######獲取Executorapp

//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

相關文章
相關標籤/搜索