手写MyBatis

Mybatis中的关键类

  • 入口: SqlSessionFactoryBuild().build().openSqlSession().getMapper(BlogMapper.class);
package com.hbatis.v2.session;

public class SqlSessionFactoryBuild {

  private Configuration configuration;
  
  public SqlSessionFactoryBuild build() {
    configuration=new Configuration();
    return this;
  }
  public DefaultSqlSession openSqlSession(){
    return new DefaultSqlSession(configuration);
  }
}
  • 定义DefaultSqlSession
package com.hbatis.v2.session;

import com.hbatis.v2.executor.Executor;
import com.hbatis.v2.mapper.BlogMapper;

public class DefaultSqlSession {

  private Configuration configuration;

  private Executor executor;

  public DefaultSqlSession(Configuration configuration) {

    this.configuration = configuration;
    this.executor=configuration.newExecutor();

  }
  public <T> T getMapper(Class clazz) {
    return configuration.getMapper(clazz,this);
  }

}
  • 配置config,这个扫描指定路径,加载XML文件,这里用key–value的properties来代替处理。
package com.hbatis.v2.session;

import com.hbatis.v2.binding.MapperRegistry;
import com.hbatis.v2.executor.Executor;
import com.hbatis.v2.executor.SimpleExecutor;

import java.io.File;
import java.util.*;

public class Configuration {

  public static final ResourceBundle sqlMappings; // SQL映射关系配置,使用注解时不用重复配置

  public static final ResourceBundle properties; // 全局配置

  public static final MapperRegistry MAPPER_REGISTRY = new MapperRegistry(); // 维护接口与工厂类关系
  public static final Map<String, String> mappedStatements = new HashMap<>();
  private List<Class<?>> mapperList = new ArrayList<>(); // 所有Mapper接口
  private List<String> classPaths = new ArrayList<>(); // 类所有文件

  static {
    sqlMappings=ResourceBundle.getBundle("sql");
    properties=ResourceBundle.getBundle("mybatis");

  }


  public Configuration(){
    // 1.解析sql.properties
    for (String key:sqlMappings.keySet()) {
      Class mapper=null;
      Class pojo=null;
      String statement= sqlMappings.getString(key).split("--")[0];
      String pojoStr = sqlMappings.getString(key).split("--")[1];

      try {

        Class.forName(key.substring(0, key.lastIndexOf(".")));
        pojo=Class.forName(pojoStr);

      }catch (Exception e){
        e.printStackTrace();
      }

      MAPPER_REGISTRY.addMapper(mapper,pojo);
      mappedStatements.put(key,statement);

    }
    String mapperPath = properties.getString("mapper.path");
    scanPackage(mapperPath);
  }

  private void scanPackage(String mapperPath) {
    String classPath = this.getClass().getResource("/").getPath();
    mapperPath = mapperPath.replace(".", File.separator);
    String mainPath = classPath + mapperPath;
    doPath(new File(mainPath));
    for (String className : classPaths) {
      className = className.replace(classPath.replace("/","\\").replaceFirst("\\\\",""),"").replace("\\",".").replace(".class","");
      Class<?> clazz = null;
      try {
        clazz = Class.forName(className);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
      if(clazz.isInterface()){
        mapperList.add(clazz);
      }

    }

  }

  private void doPath(File file) {
    if(file.isDirectory()){
      File[] files = file.listFiles();
      for (File f1:files) {
        doPath(f1);
      }
    }else{
      if(file.getName().endsWith(".class")){
        classPaths.add(file.getPath());
      }
    }
  }


  public Executor newExecutor() {
    Executor executor=null;
    //    if(properties.getString("cache.enabled").equals("true")){

    //    }else{
    executor=new SimpleExecutor();
    //    }
    return executor;
  }


  public <T> T getMapper(Class clazz, DefaultSqlSession sqlSession) {
    return null;
  }

}
  • 所有的代理类存储的器,Map的形式
package com.hbatis.v2.binding;

import com.hbatis.v2.session.DefaultSqlSession;

import java.util.HashMap;
import java.util.Map;

public class MapperRegistry {
  private final Map<Class<?>,MapperProxyFactory> knownMappers =new HashMap<>();


  public <T> void addMapper(Class<T> clazz,Class pojo){
    knownMappers.put(clazz,new MapperProxyFactory());
  }

  public <T> T getMapper(Class<T> clazz, DefaultSqlSession sqlSession){
    MapperProxyFactory mapperProxyFactory = knownMappers.get(clazz);
    return (T)mapperProxyFactory.newInstance(sqlSession);
  }

}
  • 测试类

package com.hbatis.v2;

import com.hbatis.v2.mapper.Blog;
import com.hbatis.v2.mapper.BlogMapper;
import com.hbatis.v2.session.SqlSessionFactoryBuild;

public class TestHbatis {

  public static void main(String[] args) {
    BlogMapper mapper = new SqlSessionFactoryBuild().build().openSqlSession().getMapper(BlogMapper.class);
    Blog blog = mapper.selectBlogById(1);
    System.out.println(blog);
  }

}

github地址:https://github.com/alfredhua/test/tree/master/mybatis


文章作者: 凌云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 凌云 !
  目录