计算机系统应用教程网站

网站首页 > 技术文章 正文

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

btikc 2024-09-29 09:59:20 技术文章 18 ℃ 0 评论

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


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

先对Service基类进行介绍。

1)BaseService

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<T, Example extends BaseExample, ID> {

    long countByExample(Example example);

    int deleteByExample(Example example);

    int deleteByPrimaryKey(ID id);

    int insert(T record);

    int insertSelective(T record);

    List<T> 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<p/>
     * then return result of selectByExample(example)
     * @author Marvis
     * @date Jul 13, 2017 5:24:35 PM
     * @param example
     * @param pageInfo
     * @return
     */
    List<T> 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);
}

2)BaseServiceImpl

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<T, Example extends BaseExample, ID> implements BaseService<T, Example, ID> {

    private BaseMapper<T, Example, ID> mapper;

    public void setMapper(BaseMapper<T, Example, ID> 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<T> selectByExample(Example example) {
        return mapper.selectByExample(example);
    }
    @Override
    public T selectByCondition(Example example) {
        
        List<T> datas = selectByExample(example);
        return datas != null && datas.size() == 0 ? null : datas.get(0);
    }

    @Override
    public List<T> 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);
    }
}

3)ServiceLayerPlugin

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();
    }

}

4)ContextOverride

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;
    }
}

5)MyBatisGeneratorConfigurationParserOverride

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);
        }

    }
}

6)ServiceGeneratorConfiguration

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));
    }

}

7)ConfigurationParserOverride

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);
    }

}


七、PluginChain



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

package run.override;

import run.override.service.ServiceLayerPlugin;
public class PluginChain extends ServiceLayerPlugin {
}


八、generatorConfig.xml


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

1)generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 内部DTD 亦可通过外部DTD来实现-->
<!DOCTYPE generatorConfiguration
  
  [
<!ELEMENT generatorConfiguration (properties?, classPathEntry*, context+)>
                        
<!ELEMENT properties EMPTY>
<!ATTLIST properties
  resource CDATA #IMPLIED
  url CDATA #IMPLIED>
<!--
    括号里是声明出现的次序:
    *: 出现任意次,包括0次
    ?: 出现最多一次
    |:选择之一
    +: 出现最少1次
    如果没有上述符号:必须且只能出现一次
 -->
<!ELEMENT context (property*, plugin*, commentGenerator?, (connectionFactory | jdbcConnection), javaTypeResolver?,
                         javaModelGenerator, sqlMapGenerator, javaClientGenerator, javaServiceGenerator,table+)>
<!ATTLIST context id ID #REQUIRED
  defaultModelType CDATA #IMPLIED
  targetRuntime CDATA #IMPLIED
  introspectedColumnImpl CDATA #IMPLIED>

<!ELEMENT connectionFactory (property*)>
<!ATTLIST connectionFactory
  type CDATA #IMPLIED>

<!ELEMENT jdbcConnection (property*)>
<!ATTLIST jdbcConnection
  driverClass CDATA #REQUIRED
  connectionURL CDATA #REQUIRED
  userId CDATA #IMPLIED
  password CDATA #IMPLIED>

<!ELEMENT classPathEntry EMPTY>
<!ATTLIST classPathEntry
  location CDATA #REQUIRED>

<!ELEMENT property EMPTY>
<!ATTLIST property
  name CDATA #REQUIRED
  value CDATA #REQUIRED>

<!ELEMENT plugin (property*)>
<!ATTLIST plugin
  type CDATA #REQUIRED>

<!ELEMENT javaModelGenerator (property*)>
<!ATTLIST javaModelGenerator
  targetPackage CDATA #REQUIRED
  targetProject CDATA #REQUIRED>

<!ELEMENT javaTypeResolver (property*)>
<!ATTLIST javaTypeResolver
  type CDATA #IMPLIED>

<!ELEMENT sqlMapGenerator (property*)>
<!ATTLIST sqlMapGenerator
  targetPackage CDATA #REQUIRED
  targetProject CDATA #REQUIRED>

<!ELEMENT javaClientGenerator (property*)>
<!ATTLIST javaClientGenerator
  type CDATA #REQUIRED
  targetPackage CDATA #REQUIRED
  targetProject CDATA #REQUIRED
  implementationPackage CDATA #IMPLIED>
  
<!ELEMENT javaServiceGenerator (property*)>
<!ATTLIST javaServiceGenerator
        targetPackage CDATA #REQUIRED
        implementationPackage CDATA #REQUIRED
        targetProject CDATA #REQUIRED>
        
<!ELEMENT table (property*, generatedKey?, domainObjectRenamingRule?, columnRenamingRule?, (columnOverride | ignoreColumn | ignoreColumnsByRegex)*) >
<!ATTLIST table
  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>

<!ELEMENT columnOverride (property*)>
<!ATTLIST columnOverride
  column CDATA #REQUIRED
  property CDATA #IMPLIED
  javaType CDATA #IMPLIED
  jdbcType CDATA #IMPLIED
  typeHandler CDATA #IMPLIED
  isGeneratedAlways CDATA #IMPLIED
  delimitedColumnName CDATA #IMPLIED>

<!ELEMENT ignoreColumn EMPTY>
<!ATTLIST ignoreColumn
  column CDATA #REQUIRED
  delimitedColumnName CDATA #IMPLIED>


<!ELEMENT ignoreColumnsByRegex (except*)>
<!ATTLIST ignoreColumnsByRegex
  pattern CDATA #REQUIRED>

<!ELEMENT except EMPTY>
<!ATTLIST except
  column CDATA #REQUIRED
  delimitedColumnName CDATA #IMPLIED>

<!ELEMENT generatedKey EMPTY>
<!ATTLIST generatedKey
  column CDATA #REQUIRED
  sqlStatement CDATA #REQUIRED
  identity CDATA #IMPLIED
  type CDATA #IMPLIED>

<!ELEMENT domainObjectRenamingRule EMPTY>
<!ATTLIST domainObjectRenamingRule
  searchString CDATA #REQUIRED
  replaceString CDATA #IMPLIED>

<!ELEMENT columnRenamingRule EMPTY>
<!ATTLIST columnRenamingRule
  searchString CDATA #REQUIRED
  replaceString CDATA #IMPLIED>

<!ELEMENT commentGenerator (property*)>
<!ATTLIST commentGenerator
  type CDATA #IMPLIED>
 ]
  >
   
<generatorConfiguration>
    <context id="ables" targetRuntime="MyBatis3">
                <!--
                    添加Plugin
               -->
        <plugin type="run.override.PluginChain" />
        <plugin type="run.override.SerializablePlugin" />
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
        <commentGenerator type="run.override.CommentGenerator"/>

        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxx?characterEncoding=utf8"
            userId="xxx" password="xxx">
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <javaModelGenerator targetPackage="cn.xxx.elecsign.model" targetProject=".\src">
            <property name="enableSubPackages" value="false" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <sqlMapGenerator targetPackage="mapper.cn.xxx.elecsign.dao" targetProject=".\src">
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>

        <javaClientGenerator type="XMLMAPPER" targetPackage="cn.xxx.elecsign.dao" targetProject=".\src">
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
              <!-- javaServiceGenerator  -->
        <javaServiceGenerator  targetPackage="cn.xxx.elecsign.dly.service"
                implementationPackage = "cn.xxx.elecsign.dly.service.impl" targetProject=".\src">
            <property name="enableSubPackages" value="false" />
        </javaServiceGenerator>

        <!-- 批次表,针对批量的异步操作 -->
        <table tableName="table" domainObjectName="Table"
            alias="table">
            <generatedKey column="id" sqlStatement="MySql" identity="true" />
        </table>
    </context>
</generatorConfiguration>


九、main启动


 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();
        }
        
    }

}

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

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表