代码演示Mybatis-Generator 扩展自定义生成(下)

六、服务层代码自定义生成


重写Context,ConfigurationParser,MyBatisGeneratorConfigurationParser, 增加服务层生成逻辑。

先对Service基类进行介绍。

1)BaseService

<code>package cn.xxx.core.base.service;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import cn.xxx.core.base.model.BaseExample;
import cn.xxx.core.base.model.PageInfo;

public interface BaseService {

long countByExample(Example example);

int deleteByExample(Example example);

int deleteByPrimaryKey(ID id);

int insert(T record);

int insertSelective(T record);

List selectByExample(Example example);

/**
* return T object
* @author Marvis
* @date May 23, 2018 11:37:11 AM
* @param example
* @return
*/
T selectByCondition(Example example);
/**
* if pageInfo == null


* then return result of selectByExample(example)
* @author Marvis
* @date Jul 13, 2017 5:24:35 PM
* @param example
* @param pageInfo
* @return
*/
List selectByPageExmple(Example example, PageInfo pageInfo);

T selectByPrimaryKey(ID id);

int updateByExampleSelective(@Param("record") T record, @Param("example") Example example);

int updateByExample(@Param("record") T record, @Param("example") Example example);

int updateByPrimaryKeySelective(T record);

int updateByPrimaryKey(T record);
}
/<code>

2)BaseServiceImpl

<code>package cn.xxx.core.base.service.impl;

import java.util.List;

import cn.xxx.core.base.dao.BaseMapper;
import cn.xxx.core.base.model.BaseExample;
import cn.xxx.core.base.model.PageInfo;
import cn.xxx.core.base.service.BaseService;

public abstract class BaseServiceImpl implements BaseService {

private BaseMapper mapper;

public void setMapper(BaseMapper mapper) {
this.mapper = mapper;
}

public long countByExample(Example example) {

return mapper.countByExample(example);
}

@Override
public int deleteByExample(Example example) {
return mapper.deleteByExample(example);
}

@Override
public int deleteByPrimaryKey(ID id) {
return mapper.deleteByPrimaryKey(id);
}

@Override
public int insert(T record) {
return mapper.insert(record);
}

@Override
public int insertSelective(T record) {
return mapper.insertSelective(record);
}

@Override
public List selectByExample(Example example) {
return mapper.selectByExample(example);
}
@Override
public T selectByCondition(Example example) {

List datas = selectByExample(example);
return datas != null && datas.size() == 0 ? null : datas.get(0);
}

@Override
public List selectByPageExmple(Example example, PageInfo pageInfo) {

if(pageInfo != null){

example.setPageInfo(pageInfo);
pageInfo.setPageParams(Long.valueOf(this.countByExample(example)).intValue());
}
return this.selectByExample(example);
}

@Override
public T selectByPrimaryKey(ID id) {

return mapper.selectByPrimaryKey(id);
}

@Override
public int updateByExampleSelective(T record, Example example) {
return mapper.updateByExampleSelective(record, example);
}

@Override
public int updateByExample(T record, Example example) {
return mapper.updateByExample(record, example);
}

@Override
public int updateByPrimaryKeySelective(T record) {
return mapper.updateByPrimaryKeySelective(record);
}

@Override
public int updateByPrimaryKey(T record) {
return mapper.updateByPrimaryKey(record);
}
}
/<code>

3)ServiceLayerPlugin

<code>package run.override.service;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
import run.override.pagination.PaginationPlugin;

import run.override.proxyFactory.FullyQualifiedJavaTypeProxyFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ServiceLayerPlugin extends PaginationPlugin {
/**
* 生成额外java文件
*/
@Override
public List<generatedjavafile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {

ContextOverride context = (ContextOverride) introspectedTable.getContext();

ServiceGeneratorConfiguration serviceGeneratorConfiguration;

if ((serviceGeneratorConfiguration = context.getServiceGeneratorConfiguration()) == null)
return null;

String targetPackage = serviceGeneratorConfiguration.getTargetPackage();
String targetProject = serviceGeneratorConfiguration.getTargetProject();
String implementationPackage = serviceGeneratorConfiguration.getImplementationPackage();

CompilationUnit addServiceInterface = addServiceInterface(introspectedTable, targetPackage);
CompilationUnit addServiceImplClazz = addServiceImplClazz(introspectedTable, targetPackage,
implementationPackage);

GeneratedJavaFile gjfServiceInterface = new GeneratedJavaFile(addServiceInterface, targetProject,
this.context.getProperty("javaFileEncoding"), this.context.getJavaFormatter());
GeneratedJavaFile gjfServiceImplClazz = new GeneratedJavaFile(addServiceImplClazz, targetProject,
this.context.getProperty("javaFileEncoding"), this.context.getJavaFormatter());

List<generatedjavafile> list = new ArrayList<>();
list.add(gjfServiceInterface);
list.add(gjfServiceImplClazz);
return list;
}

protected CompilationUnit addServiceInterface(IntrospectedTable introspectedTable, String targetPackage) {

String entityClazzType = introspectedTable.getBaseRecordType();
String serviceSuperPackage = targetPackage;

String entityExampleClazzType = introspectedTable.getExampleType();
String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();

JavaTypeResolver javaTypeResolver = new JavaTypeResolverDefaultImpl();

FullyQualifiedJavaType calculateJavaType = javaTypeResolver

.calculateJavaType(introspectedTable.getPrimaryKeyColumns().get(0));

StringBuilder builder = new StringBuilder();

FullyQualifiedJavaType superInterfaceType = new FullyQualifiedJavaType(

builder.append("BaseService .append(entityClazzType)
.append(",")
.append(entityExampleClazzType)
.append(",")
.append(calculateJavaType.getShortName()).append(">").toString());

Interface serviceInterface = new Interface(
builder.delete(0, builder.length())
.append(serviceSuperPackage)
.append(".")
.append(domainObjectName)
.append("Service")
.toString()
);

serviceInterface.addSuperInterface(superInterfaceType);
serviceInterface.setVisibility(JavaVisibility.PUBLIC);

FullyQualifiedJavaType baseServiceInstance = FullyQualifiedJavaTypeProxyFactory.getBaseServiceInstance();
FullyQualifiedJavaType modelJavaType = new FullyQualifiedJavaType(entityClazzType);
FullyQualifiedJavaType exampleJavaType = new FullyQualifiedJavaType(entityExampleClazzType);
serviceInterface.addImportedType(baseServiceInstance);
serviceInterface.addImportedType(modelJavaType);
serviceInterface.addImportedType(exampleJavaType);
serviceInterface.addFileCommentLine("/*** copyright (c) 2019 Marvis ***/");


this.additionalServiceMethods(introspectedTable, serviceInterface);
return serviceInterface;
}

protected CompilationUnit addServiceImplClazz(IntrospectedTable introspectedTable, String targetPackage,
String implementationPackage) {

String entityClazzType = introspectedTable.getBaseRecordType();
String serviceSuperPackage = targetPackage;
String serviceImplSuperPackage = implementationPackage;
String entityExampleClazzType = introspectedTable.getExampleType();

String javaMapperType = introspectedTable.getMyBatis3JavaMapperType();

String domainObjectName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();

JavaTypeResolver javaTypeResolver = new JavaTypeResolverDefaultImpl();

FullyQualifiedJavaType calculateJavaType = javaTypeResolver
.calculateJavaType(introspectedTable.getPrimaryKeyColumns().get(0));

StringBuilder builder = new StringBuilder();

FullyQualifiedJavaType superClazzType = new FullyQualifiedJavaType(

builder.append("BaseServiceImpl .append(entityClazzType)
.append(",")
.append(entityExampleClazzType)
.append(",")
.append(calculateJavaType.getShortName()).append(">")
.toString()
);

FullyQualifiedJavaType implInterfaceType = new FullyQualifiedJavaType(

builder.delete(0, builder.length())
.append(serviceSuperPackage)
.append(".")
.append(domainObjectName)
.append("Service")
.toString()
);

TopLevelClass serviceImplClazz = new TopLevelClass(

builder.delete(0, builder.length())
.append(serviceImplSuperPackage)
.append(".")
.append(domainObjectName)
.append("ServiceImpl")
.toString()
);

serviceImplClazz.addSuperInterface(implInterfaceType);
serviceImplClazz.setSuperClass(superClazzType);
serviceImplClazz.setVisibility(JavaVisibility.PUBLIC);
serviceImplClazz.addAnnotation("@Service");

FullyQualifiedJavaType baseServiceInstance = FullyQualifiedJavaTypeProxyFactory.getBaseServiceImplInstance();
FullyQualifiedJavaType modelJavaType = new FullyQualifiedJavaType(entityClazzType);
FullyQualifiedJavaType exampleJavaType = new FullyQualifiedJavaType(entityExampleClazzType);
serviceImplClazz
.addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));
serviceImplClazz.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Service"));
serviceImplClazz.addImportedType(baseServiceInstance);
serviceImplClazz.addImportedType(modelJavaType);
serviceImplClazz.addImportedType(exampleJavaType);
serviceImplClazz.addImportedType(implInterfaceType);


FullyQualifiedJavaType logType = new FullyQualifiedJavaType("org.slf4j.Logger");
FullyQualifiedJavaType logFactoryType = new FullyQualifiedJavaType("org.slf4j.LoggerFactory");
Field logField = new Field();
logField.setVisibility(JavaVisibility.PRIVATE);
logField.setStatic(true);
logField.setFinal(true);
logField.setType(logType);
logField.setName("logger");
logField.setInitializationString(
builder.delete(0, builder.length())
.append("LoggerFactory.getLogger(")
.append(domainObjectName)
.append("ServiceImpl.class)")
.toString()
);

logField.addAnnotation("");
logField.addAnnotation("@SuppressWarnings(\"unused\")");
serviceImplClazz.addField(logField);
serviceImplClazz.addImportedType(logType);
serviceImplClazz.addImportedType(logFactoryType);

String mapperName = builder.delete(0, builder.length())
.append(Character.toLowerCase(domainObjectName.charAt(0)))
.append(domainObjectName.substring(1))
.append("Mapper")
.toString();

FullyQualifiedJavaType JavaMapperType = new FullyQualifiedJavaType(javaMapperType);

Field mapperField = new Field();
mapperField.setVisibility(JavaVisibility.PUBLIC);
mapperField.setType(JavaMapperType);// Mapper.java
mapperField.setName(mapperName);
mapperField.addAnnotation("@Autowired");
serviceImplClazz.addField(mapperField);
serviceImplClazz.addImportedType(JavaMapperType);

Method mapperMethod = new Method();
mapperMethod.setVisibility(JavaVisibility.PUBLIC);
mapperMethod.setName("setMapper");
mapperMethod.addBodyLine("super.setMapper(" + mapperName + ");");
mapperMethod.addAnnotation("@Autowired");

serviceImplClazz.addMethod(mapperMethod);
serviceImplClazz.addFileCommentLine("/*** copyright (c) 2019 Marvis ***/");

serviceImplClazz
.addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));


this.additionalServiceImplMethods(introspectedTable, serviceImplClazz, mapperName);

return serviceImplClazz;
}

protected void additionalServiceMethods(IntrospectedTable introspectedTable, Interface serviceInterface) {

if (this.notHasBLOBColumns(introspectedTable))
return;

introspectedTable.getGeneratedJavaFiles().stream().filter(file -> file.getCompilationUnit().isJavaInterface()
&& file.getCompilationUnit().getType().getShortName().endsWith("Mapper")).map(GeneratedJavaFile::getCompilationUnit).forEach(
compilationUnit -> ((Interface) compilationUnit).getMethods().forEach(

m -> serviceInterface.addMethod(this.additionalServiceLayerMethod(serviceInterface, m))));
}

protected void additionalServiceImplMethods(IntrospectedTable introspectedTable, TopLevelClass clazz,
String mapperName) {

if (this.notHasBLOBColumns(introspectedTable))
return;

introspectedTable.getGeneratedJavaFiles().stream().filter(file -> file.getCompilationUnit().isJavaInterface()
&& file.getCompilationUnit().getType().getShortName().endsWith("Mapper")).map(GeneratedJavaFile::getCompilationUnit).forEach(
compilationUnit -> ((Interface) compilationUnit).getMethods().forEach(m -> {

Method serviceImplMethod = this.additionalServiceLayerMethod(clazz, m);
serviceImplMethod.addAnnotation("@Override");
serviceImplMethod.addBodyLine(this.generateBodyForServiceImplMethod(mapperName, m));

clazz.addMethod(serviceImplMethod);
}));
}


private boolean notHasBLOBColumns(IntrospectedTable introspectedTable) {
return !introspectedTable.hasBLOBColumns();
}

private Method additionalServiceLayerMethod(CompilationUnit compilation, Method m) {

Method method = new Method();
method.setVisibility(JavaVisibility.PUBLIC);
method.setName(m.getName());

List<parameter> parameters = m.getParameters();

method.getParameters().addAll(parameters.stream().peek(param -> param.getAnnotations().clear()).collect(Collectors.toList()));

method.setReturnType(m.getReturnType());
compilation.addImportedType(
new FullyQualifiedJavaType(m.getReturnType().getFullyQualifiedNameWithoutTypeParameters()));
return method;
}

private String generateBodyForServiceImplMethod(String mapperName, Method m) {
StringBuilder sbf = new StringBuilder("return ");
sbf.append(mapperName).append(".").append(m.getName()).append("(");

boolean singleParam = true;
for (Parameter parameter : m.getParameters()) {

if (singleParam)
singleParam = !singleParam;
else
sbf.append(", ");
sbf.append(parameter.getName());

}

sbf.append(");");
return sbf.toString();
}

}/<parameter>/<generatedjavafile>/<generatedjavafile>/<code>

4)ContextOverride

<code>package run.override.service;

import java.util.List;

import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.ModelType;

public class ContextOverride extends Context{
//添加ServiceGeneratorConfiguration
private ServiceGeneratorConfiguration serviceGeneratorConfiguration;

public ContextOverride(ModelType defaultModelType) {
super(defaultModelType);
}

public ServiceGeneratorConfiguration getServiceGeneratorConfiguration() {
return serviceGeneratorConfiguration;
}


public void setServiceGeneratorConfiguration(ServiceGeneratorConfiguration serviceGeneratorConfiguration) {
this.serviceGeneratorConfiguration = serviceGeneratorConfiguration;
}

@Override
public void validate(List<string> errors) {
if(serviceGeneratorConfiguration != null)
serviceGeneratorConfiguration.validate(errors, this.getId());

super.validate(errors);
}

public XmlElement toXmlElement() {

XmlElement xmlElement = super.toXmlElement();
if (serviceGeneratorConfiguration != null)
xmlElement.addElement(serviceGeneratorConfiguration.toXmlElement());
return xmlElement;
}
}/<string>/<code>

5)MyBatisGeneratorConfigurationParserOverride

<code>package run.override.service;

import java.util.Properties;

import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.JavaClientGeneratorConfiguration;
import org.mybatis.generator.config.ModelType;
import org.mybatis.generator.config.PluginConfiguration;
import org.mybatis.generator.config.xml.MyBatisGeneratorConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.util.StringUtility;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class MyBatisGeneratorConfigurationParserOverride extends MyBatisGeneratorConfigurationParser {

public MyBatisGeneratorConfigurationParserOverride(Properties extraProperties) {
super(extraProperties);
}

private void parseJavaServiceGenerator(Context context, Node node) {

ContextOverride contextOverride = ContextOverride.class.cast(context); ////替换Context

ServiceGeneratorConfiguration serviceGeneratorConfiguration = new ServiceGeneratorConfiguration();

contextOverride.setServiceGeneratorConfiguration(serviceGeneratorConfiguration);
Properties attributes = parseAttributes(node);

String targetPackage = attributes.getProperty("targetPackage");
String targetProject = attributes.getProperty("targetProject");
String implementationPackage = attributes.getProperty("implementationPackage");

serviceGeneratorConfiguration.setTargetPackage(targetPackage);
serviceGeneratorConfiguration.setTargetProject(targetProject);
serviceGeneratorConfiguration.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 && "property".equals(childNode.getNodeName()))
parseProperty(serviceGeneratorConfiguration, childNode);
}

}

@Override
public Configuration parseConfiguration(Element rootNode) throws XMLParserException {
Configuration configuration = new Configuration();

NodeList nodeList = rootNode.getChildNodes();
for (int i = 0; i < nodeList.getLength(); ++i) {
Node childNode = nodeList.item(i);

if (childNode.getNodeType() != 1) {
continue;
}

if ("properties".equals(childNode.getNodeName()))
parseProperties(configuration, childNode);
else if ("classPathEntry".equals(childNode.getNodeName()))
parseClassPathEntry(configuration, childNode);
else if ("context".equals(childNode.getNodeName())) {
parseContext(configuration, childNode);
}
}

return configuration;
}

private void parseContext(Configuration configuration, Node node) {
Properties attributes = parseAttributes(node);

String defaultModelType = attributes.getProperty("defaultModelType");
String targetRuntime = attributes.getProperty("targetRuntime");
String introspectedColumnImpl = attributes.getProperty("introspectedColumnImpl");
String id = attributes.getProperty("id");
ModelType mt = defaultModelType != null ? ModelType.getModelType(defaultModelType) : null;
Context context = new ContextOverride(mt);
context.setId(id);
if (StringUtility.stringHasValue(introspectedColumnImpl))
context.setIntrospectedColumnImpl(introspectedColumnImpl);
if (StringUtility.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() != 1)
continue;

if ("property".equals(childNode.getNodeName())) {
parseProperty(context, childNode);
continue;
}
if ("plugin".equals(childNode.getNodeName())) {
parsePlugin(context, childNode);
continue;
}
if ("commentGenerator".equals(childNode.getNodeName())) {
parseCommentGenerator(context, childNode);
continue;
}
if ("jdbcConnection".equals(childNode.getNodeName())) {
parseJdbcConnection(context, childNode);
continue;
}
if ("connectionFactory".equals(childNode.getNodeName())) {
parseConnectionFactory(context, childNode);
continue;
}
if ("javaModelGenerator".equals(childNode.getNodeName())) {
parseJavaModelGenerator(context, childNode);
continue;
}
if ("javaTypeResolver".equals(childNode.getNodeName())) {
parseJavaTypeResolver(context, childNode);
continue;
}
if ("sqlMapGenerator".equals(childNode.getNodeName())) {
parseSqlMapGenerator(context, childNode);
continue;
}

if ("javaClientGenerator".equals(childNode.getNodeName())) {
parseJavaClientGenerator(context, childNode);
continue;
}
if ("javaServiceGenerator".equals(childNode.getNodeName())) {
parseJavaServiceGenerator(context, childNode);
continue;
}
if ("table".equals(childNode.getNodeName()))
parseTable(context, childNode);
}
}

private void parsePlugin(Context context, Node node) {
PluginConfiguration pluginConfiguration = new PluginConfiguration();
context.addPluginConfiguration(pluginConfiguration);
Properties attributes = parseAttributes(node);
String type = attributes.getProperty("type");
pluginConfiguration.setConfigurationType(type);
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
if (childNode.getNodeType() == 1 && "property".equals(childNode.getNodeName()))
parseProperty(pluginConfiguration, childNode);
}

}

private void parseJavaClientGenerator(Context context, Node node) {
JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
Properties attributes = parseAttributes(node);
String type = attributes.getProperty("type");
String targetPackage = attributes.getProperty("targetPackage");
String targetProject = attributes.getProperty("targetProject");
String implementationPackage = attributes.getProperty("implementationPackage");
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() == 1 && "property".equals(childNode.getNodeName()))
parseProperty(javaClientGeneratorConfiguration, childNode);
}

}
}/<code>

6)ServiceGeneratorConfiguration

<code>package run.override.service;

import java.util.List;

import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.PropertyHolder;
import org.mybatis.generator.internal.util.StringUtility;
import org.mybatis.generator.internal.util.messages.Messages;

public class ServiceGeneratorConfiguration extends PropertyHolder {

private String targetPackage;
private String implementationPackage;
private String targetProject;
/**
*
*/
public ServiceGeneratorConfiguration() {
super();
}
public String getTargetPackage() {
return targetPackage;
}
public void setTargetPackage(String targetPackage) {
this.targetPackage = targetPackage;
}
public String getImplementationPackage() {
return implementationPackage;
}
public void setImplementationPackage(String implementationPackage) {
this.implementationPackage = implementationPackage;
}
public String getTargetProject() {
return targetProject;
}
public void setTargetProject(String targetProject) {
this.targetProject = targetProject;
}
public XmlElement toXmlElement() {
XmlElement answer = new XmlElement("javaServiceGenerator");

if (targetPackage != null) {
answer.addAttribute(new Attribute("targetPackage", targetPackage));
}

if (implementationPackage != null) {
answer.addAttribute(new Attribute("implementationPackage", targetPackage));
}
if (targetProject != null) {
answer.addAttribute(new Attribute("targetProject", targetProject));
}


addPropertyXmlElements(answer);

return answer;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public void validate(List errors, String contextId) {
if (!StringUtility.stringHasValue(getTargetProject()))
errors.add(Messages.getString("ValidationError.102", contextId));
if (!StringUtility.stringHasValue(getTargetPackage()))
errors.add(Messages.getString("ValidationError.112", "ServiceGenerator", contextId));
if (!StringUtility.stringHasValue(getImplementationPackage()))
errors.add(Messages.getString("ValidationError.120", contextId));
}

}/<code>

7)ConfigurationParserOverride

<code>package run.override.service;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.config.xml.MyBatisGeneratorConfigurationParser;
import org.mybatis.generator.config.xml.ParserEntityResolver;
import org.mybatis.generator.config.xml.ParserErrorHandler;
import org.mybatis.generator.exception.XMLParserException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class ConfigurationParserOverride extends ConfigurationParser {

private List<string> warnings;
private List<string> parseErrors;
private Properties extraProperties;

public ConfigurationParserOverride(List<string> warnings) {
this(null, warnings);
}

public ConfigurationParserOverride(Properties extraProperties, List<string> warnings) {
super(extraProperties, warnings);
this.extraProperties = extraProperties;

if (warnings == null)
this.warnings = new ArrayList<>();
else {
this.warnings = warnings;
}

this.parseErrors = new ArrayList<>();
}

@Override
public Configuration parseConfiguration(File inputFile) throws IOException, XMLParserException {
FileReader fr = new FileReader(inputFile);

return parseConfiguration(fr);
}

@Override
public Configuration parseConfiguration(InputStream inputStream) throws IOException, XMLParserException {
InputSource is = new InputSource(inputStream);

return parseConfiguration(is);
}

@Override
public Configuration parseConfiguration(Reader reader) throws IOException, XMLParserException {
InputSource is = new InputSource(reader);

return parseConfiguration(is);
}

private Configuration parseConfiguration(InputSource inputSource) throws IOException, XMLParserException {
this.parseErrors.clear();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new ParserEntityResolver());

ParserErrorHandler handler = new ParserErrorHandler(this.warnings, this.parseErrors);

builder.setErrorHandler(handler);

Document document = null;
try {
document = builder.parse(inputSource);
} catch (SAXParseException e) {
throw new XMLParserException(this.parseErrors);
} catch (SAXException e) {
if (e.getException() == null)
this.parseErrors.add(e.getMessage());
else {
this.parseErrors.add(e.getException().getMessage());
}
}

if (this.parseErrors.size() > 0) {
throw new XMLParserException(this.parseErrors);
}

Element rootNode = document.getDocumentElement();
Configuration config = parseMyBatisGeneratorConfiguration(rootNode);

if (this.parseErrors.size() > 0) {
throw new XMLParserException(this.parseErrors);
}

return config;
} catch (ParserConfigurationException e) {
this.parseErrors.add(e.getMessage());
throw new XMLParserException(this.parseErrors);
}
}

private Configuration parseMyBatisGeneratorConfiguration(Element rootNode) throws XMLParserException {

//替换MyBatisGeneratorConfigurationParser
MyBatisGeneratorConfigurationParser parser = new MyBatisGeneratorConfigurationParserOverride(
this.extraProperties);

return parser.parseConfiguration(rootNode);

}

}/<string>/<string>/<string>/<string>/<code>


七、PluginChain



通过继承,把以上扩展Plugin串起来(SerializablePlugin一些项目中可能不需要,故不加入Chain。同时,其他也可以根据需要对Chain进行更改)。

<code>package run.override;

import run.override.service.ServiceLayerPlugin;
public class PluginChain extends ServiceLayerPlugin {
}/<code>


八、generatorConfig.xml


增加javaServiceGenerator相关配置标签。本文使用内部DTD做示例,亦可通过外部DTD或xsd来实现。

1)generatorConfig.xml

<code> 


br>
[



resource CDATA #IMPLIED
url CDATA #IMPLIED>

javaModelGenerator, sqlMapGenerator, javaClientGenerator, javaServiceGenerator,table+)>
defaultModelType CDATA #IMPLIED
targetRuntime CDATA #IMPLIED
introspectedColumnImpl CDATA #IMPLIED>


type CDATA #IMPLIED>


driverClass CDATA #REQUIRED
connectionURL CDATA #REQUIRED
userId CDATA #IMPLIED
password CDATA #IMPLIED>


location CDATA #REQUIRED>


name CDATA #REQUIRED
value CDATA #REQUIRED>


type CDATA #REQUIRED>


targetPackage CDATA #REQUIRED
targetProject CDATA #REQUIRED>


type CDATA #IMPLIED>


targetPackage CDATA #REQUIRED
targetProject CDATA #REQUIRED>


type CDATA #REQUIRED
targetPackage CDATA #REQUIRED
targetProject CDATA #REQUIRED
implementationPackage CDATA #IMPLIED>


targetPackage CDATA #REQUIRED
implementationPackage CDATA #REQUIRED
targetProject CDATA #REQUIRED>


catalog CDATA #IMPLIED
schema CDATA #IMPLIED
tableName CDATA #REQUIRED
alias CDATA #IMPLIED
domainObjectName CDATA #IMPLIED
mapperName CDATA #IMPLIED
sqlProviderName CDATA #IMPLIED
enableInsert CDATA #IMPLIED
enableSelectByPrimaryKey CDATA #IMPLIED
enableSelectByExample CDATA #IMPLIED
enableUpdateByPrimaryKey CDATA #IMPLIED
enableDeleteByPrimaryKey CDATA #IMPLIED
enableDeleteByExample CDATA #IMPLIED
enableCountByExample CDATA #IMPLIED
enableUpdateByExample CDATA #IMPLIED
selectByPrimaryKeyQueryId CDATA #IMPLIED
selectByExampleQueryId CDATA #IMPLIED
modelType CDATA #IMPLIED
escapeWildcards CDATA #IMPLIED
delimitIdentifiers CDATA #IMPLIED
delimitAllColumns CDATA #IMPLIED>


column CDATA #REQUIRED
property CDATA #IMPLIED
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
typeHandler CDATA #IMPLIED

isGeneratedAlways CDATA #IMPLIED
delimitedColumnName CDATA #IMPLIED>


column CDATA #REQUIRED
delimitedColumnName CDATA #IMPLIED>



pattern CDATA #REQUIRED>


column CDATA #REQUIRED
delimitedColumnName CDATA #IMPLIED>


column CDATA #REQUIRED
sqlStatement CDATA #REQUIRED
identity CDATA #IMPLIED
type CDATA #IMPLIED>


searchString CDATA #REQUIRED
replaceString CDATA #IMPLIED>


searchString CDATA #REQUIRED
replaceString CDATA #IMPLIED>


type CDATA #IMPLIED>
]
>

<generatorconfiguration>
<context>

<plugin>
<plugin>
<plugin>
<commentgenerator>

<jdbcconnection> connectionURL="jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxx?characterEncoding=utf8"
userId="xxx" password="xxx">
/<jdbcconnection>
<javatyperesolver>
<property>

/<javatyperesolver>
<javamodelgenerator>
<property>
<property>
/<javamodelgenerator>

<sqlmapgenerator>
<property>
/<sqlmapgenerator>

<javaclientgenerator>
<property>
/<javaclientgenerator>

<javaservicegenerator> implementationPackage = "cn.xxx.elecsign.dly.service.impl" targetProject=".\\src">
<property>
/<javaservicegenerator>


<table> alias="table">
<generatedkey>
/<table>
/<context>
/<generatorconfiguration>/<code>


九、main启动


<code> package run.generator;


import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.internal.DefaultShellCallback;

import run.override.service.ConfigurationParserOverride;


public class Generator {

public void generator() throws Exception{

List<string> warnings = new ArrayList<string>();
boolean overwrite = true;
File configFile = new File("generatorConfig.xml");
//替换ConfigurationParser
ConfigurationParserOverride cp = new ConfigurationParserOverride(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);

myBatisGenerator.generate(null);

}
public static void main(String[] args) throws Exception {
try {
Generator generator = new Generator();
generator.generator();
} catch (Exception e) {
e.printStackTrace();
}

}

}/<string>/<string>/<code>

至此,对Mybatis-generator的扩展生成代码完成。


分享到:


相關文章: