Mybatis 原理分析

时间:2019-12-18 00:02:38   收藏:0   阅读:87

对于入门程序的流程分析

使用过程

  1. 读配置文件

    读取配置文件时绝对路径和相对路径(web工程部署后没有src路径)都有一定问题,实际开发中一般有两种方法

    • 使用类加载器,它只能读取类路径的配置文件
    • 使用SerbletContext对象的getRealPath()
  2. 创建SqlSessionFactory工厂,使用了建造者模式(Builder Pattern)

  3. 使用工厂生产SqlSession对象,使用了工厂模式(Factory Pattern)

  4. 使用SqlSession创建Dao接口的代理对象,使用了代理模式(Proxy Pattern)

  5. 使用代理对象执行方法

  6. 释放资源

底层调用jdbc的流程,即自定义dao中selectList()方法的执行流程,也是代理对象增强的逻辑

  1. 注册驱动,获取Connection对象(需要数据库信息)
    • 通过SqlMapConfig.xml的数据库信息,解析xml文件用到的是dom4j技术
  2. 获取预处理对象PreparedStatement(需要sql语句)
    • 通过SqlMapConfig.xml中的mapper标签定位UserDao.xml,映射配置文件中有sql语句
  3. 执行查询,得到结果集ResultSet
  4. 遍历结果集用于封装
    • 根据UserDao.xml中的resultType反射获得User对象,User对象的属性名和表中列名一致,可以一一封装进user对象中,再把user对象封装进list中

创建代理对象流程

原理分析:模拟Mybatis各组件实现入门程序

session.selectList()源码分析

//UserDaoImpl.java
public List<User> findAll(){
    session.selectList("com.whteway.dao.UserDao.findAll");
}
//DefaultSqlSession.java
public <E> List<E> selectList(String statement){
    this.selectList(statement, null);
}
public <E> List<E> selectList(String statement, Object parameter){
    this.selectList(statement, parameter, RowBounds.DEFAULT);
}
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds){
    try{
        MappedStatement ms = configuration.getMappedStatement(statement);
        return executor.query(ms, wrapColeection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
    } catch (Exception e){
        
    } finally {
        ErrorContext.instance().reset();
    }
}
//CachingExecutor.java
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException{
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException{
    ...
    return delegate.<E> query(ms, parameterObect, rowBounds, resultHandler, key, boundSql);
}
//BaseExecutor.java...
//经过一系列的调用,会走到PreparedStatementHandler类中的一个query方法
//PreparedStatementHandler.java
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException{
    //出现JDBC代码
    PreparedStatement ps = (PreparedStatement)statement;
    ps.execute();
    return resultSetHandler.<E> handleResultSets(ps);
}
//DefaultResultSetHandler.java
public List<Object> handleResultSets(Statement stmt) throws SQLException{
    //封装结果集的代码
}
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!