流程分析
1.解析流程
- 1).指定全局配置文件
String resource = "mybatis-config.xml";
- 2)将配置文件转化成流对象,这里用新建一个Resouces类
public class Resources {
public static InputStream read(String resource) {
return Resources.class.getClassLoader().getResourceAsStream(resource);
}
}
InputStream inputStram = Resources.read(resource)
- 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);
}
- 解析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);
}
- 解析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);
}
}
}