概述:
配置读取是代码生成的基础工作,主要就是把xml中的元数据读取到内存中,供后面的代码生成逻辑使用
相关类
1、ConfigurationParser
功能
主要用来将xml配置文件读取到内存,获取根节点,根据根节点的属性值,选择对应的子节点的配置解析器
代码解读:
1)读取xml
// dcoument 组装器
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new ParserEntityResolver());
// 实例化一个错误处理类,处理的错误和警告信息会以list形式保存
ParserErrorHandler handler = new ParserErrorHandler(warnings,
parseErrors);
builder.setErrorHandler(handler);
// 使用w3c 文档解析
Document document = null;
try {
// 将内存文件转换为w3c文档对象
document = builder.parse(inputSource);
} catch (SAXParseException e) {
// 抛除自定义xml转换错误异常
throw new XMLParserException(parseErrors);
} catch (SAXException e) {
// 其他异常处理
if (e.getException() == null) {
parseErrors.add(e.getMessage());
} else {
parseErrors.add(e.getException().getMessage());
}
}
// 有错的情况下,抛出异常终止运行
if (parseErrors.size() > 0) {
throw new XMLParserException(parseErrors);
}
2、解析根节点,根据元数据值获取子节点解析器
// 返回的配置文件对象
Configuration config;
// 获取根节点
Element rootNode = document.getDocumentElement();
// 获取文档类型
DocumentType docType = document.getDoctype();
if (rootNode.getNodeType() == Node.ELEMENT_NODE
&& docType.getPublicId().equals(
XmlConstants.IBATOR_CONFIG_PUBLIC_ID)) {
config = parseIbatorConfiguration(rootNode);
} else if (rootNode.getNodeType() == Node.ELEMENT_NODE
&& docType.getPublicId().equals(
XmlConstants.MYBATIS_GENERATOR_CONFIG_PUBLIC_ID)) {
// -//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN
// 该DTD运行此分支,也就是mybatis处理分支
config = parseMyBatisGeneratorConfiguration(rootNode);
} else {
throw new XMLParserException(getString("RuntimeError.5")); //$NON-NLS-1$
}
if (parseErrors.size() > 0) {
throw new XMLParserException(parseErrors);
}
2、MyBatisGeneratorConfigurationParser
功能:
主要实现子节点解析工作,同时把所有的元数据加载到内存,供后续解析使用
代码解读:
1)属性、数据库类驱动以及上下解析
if ("properties".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseProperties(configuration, childNode);
} else if ("classPathEntry".equals(childNode.getNodeName())) { //$NON-NLS-1$
// 转换类路径节点,转换的元素赋值给配置对象
parseClassPathEntry(configuration, childNode);
} else if ("context".equals(childNode.getNodeName())) { //$NON-NLS-1$
// 转换上下文节点,转换的元素赋值给配置对象
parseContext(configuration, childNode);
}
2)解析上下文,将所有的元数据加载到内存上下文,生成代码时使用这些数据(如:生成哪些类、报名、类名等)
// 获取context的所有属性以及值
Properties attributes = parseAttributes(node);
String defaultModelType = attributes.getProperty("defaultModelType"); //$NON-NLS-1$
String targetRuntime = attributes.getProperty("targetRuntime"); //$NON-NLS-1$
String introspectedColumnImpl = attributes
.getProperty("introspectedColumnImpl"); //$NON-NLS-1$
String id = attributes.getProperty("id"); //$NON-NLS-1$
ModelType mt = defaultModelType == null ? null : ModelType
.getModelType(defaultModelType);
System.err.println("parseContext | 获取缺省的模型类型:" + mt);
// 实例化一个上下文,并将模型类型传入构造方法,如果为null则是适用condition
Context context = new Context(mt);
context.setId(id);
if (stringHasValue(introspectedColumnImpl)) {
context.setIntrospectedColumnImpl(introspectedColumnImpl);
}
if (stringHasValue(targetRuntime)) {
context.setTargetRuntime(targetRuntime);
}
// 将上下文放到配置对象中
configuration.addContext(context);
// 获取上下问的子节点,遍历转换
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
if (childNode.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseProperty(context, childNode);
} else if ("plugin".equals(childNode.getNodeName())) { //$NON-NLS-1$
parsePlugin(context, childNode);
} else if ("commentGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
// 注释转换
parseCommentGenerator(context, childNode);
} else if ("jdbcConnection".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseJdbcConnection(context, childNode);
} else if ("connectionFactory".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseConnectionFactory(context, childNode);
} else if ("javaModelGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseJavaModelGenerator(context, childNode);
} else if ("javaTypeResolver".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseJavaTypeResolver(context, childNode);
} else if ("sqlMapGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseSqlMapGenerator(context, childNode);
} else if ("javaClientGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseJavaClientGenerator(context, childNode);
} else if ("table".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseTable(context, childNode);
}
3)解读每个具体属性到各自内存配置对象中
JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
Properties attributes = parseAttributes(node);
String type = attributes.getProperty("type"); //$NON-NLS-1$
String targetPackage = attributes.getProperty("targetPackage"); //$NON-NLS-1$
String targetProject = attributes.getProperty("targetProject"); //$NON-NLS-1$
String implementationPackage = attributes
.getProperty("implementationPackage"); //$NON-NLS-1$
javaClientGeneratorConfiguration.setConfigurationType(type);
javaClientGeneratorConfiguration.setTargetPackage(targetPackage);
javaClientGeneratorConfiguration.setTargetProject(targetProject);
javaClientGeneratorConfiguration
.setImplementationPackage(implementationPackage);
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
if (childNode.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
parseProperty(javaClientGeneratorConfiguration, childNode);
}
}
※ 上面解读具体解读的代码都雷同,首先需要各自节点的一个配置类(
JavaClientGeneratorConfiguration ),然后将数据读取到该类的实例对象中,同时将该对象注入到内存上下文中(Context)。