手写mybatis框架

这篇博客详细解析了MyBatis配置文件的处理过程,从读取全局配置文件到解析数据源、MapperStatement对象的创建,再到XMLConfigBuilder和XMLMapperStatement的角色。文章深入探讨了如何从environments标签到mappers标签的解析,以及如何处理CRUD标签,展示了MyBatis框架底层的工作原理。
摘要由CSDN通过智能技术生成

流程分析

1.解析流程

  1. 1).指定全局配置文件
String resource = "mybatis-config.xml";
  1. 2)将配置文件转化成流对象,这里用新建一个Resouces类
public class Resources {
    public static InputStream read(String resource) {
   		 return Resources.class.getClassLoader().getResourceAsStream(resource);
    }
}
InputStream  inputStram = Resources.read(resource)
  1. 3)创建XMLConfigBuilder类,专门解析全局配置文件,返回一个Configuration对象
    Configrution对象中包含数据源信息
    Datasource对象和封装处理CRUD标签的mapperedStatement对象的map集合,map集合中封装了mapperedStatement对象和mapperedStatementId
public class Configuration {
    private DataSource dataSource;
    private Map<String , MapperedStatement> mapperedStatementMap  = new HashMap<String,MapperedStatement>();

    public Configuration(DataSource dataSource, Map<String, MapperedStatement> mapperedStatementMap) {
        this.dataSource = dataSource;
        this.mapperedStatementMap = mapperedStatementMap;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    public void addMapperedStatement(String mapperedStatementId,MapperedStatement mapperedStatement){
        mapperedStatementMap.put(mapperedStatementId,mapperedStatement);
    }
    public MapperedStatement getMapperedStatement(String statementId){
        return mapperedStatementMap.get(statementId);
    }
}

mapperedStatement对象中封装了处理CRUD标签的信息

public class MapperedStatement {
    private String statementId;
    private Class<?> parameterTypeClass;
    private Class<?> resultTypeClass;
    private String statementType;
    private SqlSource sqlSource;

    public MapperedStatement(String statementId, Class<?> parameterTypeClass, Class<?> resultTypeClass, String statementType, SqlSource sqlSource) {
        this.statementId = statementId;
        this.parameterTypeClass = parameterTypeClass;
        this.resultTypeClass = resultTypeClass;
        this.statementType = statementType;
        this.sqlSource = sqlSource;
    }

    public String getStatementId() {
        return statementId;
    }

    public void setStatementId(String statementId) {
        this.statementId = statementId;
    }

    public Class<?> getParameterTypeClass() {
        return parameterTypeClass;
    }

    public void setParameterTypeClass(Class<?> parameterTypeClass) {
        this.parameterTypeClass = parameterTypeClass;
    }

    public Class<?> getResultTypeClass() {
        return resultTypeClass;
    }

    public void setResultTypeClass(Class<?> resultTypeClass) {
        this.resultTypeClass = resultTypeClass;
    }

    public String getStatementType() {
        return statementType;
    }

    public void setStatementType(String statementType) {
        this.statementType = statementType;
    }

    public SqlSource getSqlSource() {
        return sqlSource;
    }

    public void setSqlSource(SqlSource sqlSource) {
        this.sqlSource = sqlSource;
    }
}

XMLConfigBuilder解析了全局配置文件中的environments标签和mappers标签

 public Configuration parse(InputStream inputStream) {
        Document document = DocumentUtils.read(inputStream);
        Element rootElement = document.getRootElement();
        parseRootElement(rootElement);
        return configuration;
    }

    private void parseRootElement(Element rootElement) {
        Element environments = rootElement.element("environments");
        parseElementEnvironment(environments);
        Element mappers = rootElement.element("mappers");
        parseMappers(mappers);
    }
  1. 解析environments标签
 private void parseElementEnvironment(Element elementEnvironment) {
        String defaultId = elementEnvironment.attributeValue("default");
        List<Element> environments = elementEnvironment.elements();
        for (Element environment:environments) {
            String id = environment.attributeValue("id");
            if(defaultId.equals(id)){
                parseEnvironment(environment);
            }
        }
    }

    private void parseEnvironment(Element environment) {
        Element datasourceElement = environment.element("dataSource");
        String type = datasourceElement.attributeValue("type");
        if(type.equals("DBCP")){
            parseDatasource(datasourceElement);
        }
    }

    private void parseDatasource(Element datasourceElement) {
        List<Element> propertyElements = datasourceElement.elements("property");
        BasicDataSource dataSource = new BasicDataSource();
        Properties properties = new Properties();
        for (Element propertyElement:propertyElements) {
            String name = propertyElement.attributeValue("name");
            String value = propertyElement.attributeValue("value");
            properties.put(name,value);
            dataSource.setUrl(properties.getProperty("url"));
            dataSource.setDriverClassName(properties.getProperty("driver"));
            dataSource.setUsername(properties.getProperty("username"));
            dataSource.setPassword(properties.getProperty("password"));
        }
        configuration.setDataSource(dataSource);
    }
  1. 解析mapper标签
private void parseMappers(Element mappers) {
        List<Element> mapperElements = mappers.elements();
        for (Element mapperElement : mapperElements) {
            String resource = mapperElement.attributeValue("resource");
            InputStream inputStram = Resources.read(resource);
            Document document = DocumentUtils.read(inputStram);
            parseDocument(document);
        }
    }

    private void parseDocument(Document document) {
        XMLMapperStatement xmlMapperStatement = new XMLMapperStatement(configuration);
        xmlMapperStatement.parse(document.getRootElement());
    }

mapper标签中有sql映射文件,交给专门的XMLMapperStatement类去处理,XMLMapperStatement负责解析除了CRUD之外的标签,之后将CRUD标签交给XMLStatementBuilder类去处理

public class XMLMapperStatement {
    private Configuration configuration;

    public XMLMapperStatement(Configuration configuration) {
        this.configuration = configuration;
    }

    public void parse(Element rootElement) {
        String namespace = rootElement.attributeValue("namespace");
        List<Element> selectElements = rootElement.elements("select");
        for (Element selectElement:selectElements) {
            XMLStatementBuilder xmlStatementBuilder = new XMLStatementBuilder(configuration);
            xmlStatementBuilder.parse(selectElement,namespace);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值