MyBatis Generator 代码自动生成器

一、什么是逆向工程

Mybatis的逆向工程就是由代码生成器生成我们需要的代码和映射文件。我们在编写Mybatis程序时,基本都是围绕着pojo类,Mapper接口,Mapper.xml文件等文件来进行的。如果实际开发中数据库的表特别多,那么我们需要手动去写每一张表的pojo类,Mapper接口,Mapper.xml文件,这显然需要花费巨大的精力,而且可能由于表字段太多,哪里写错了都难以排除。所以我们在实际开发中,一般使用逆向工程方式来自动生成所需的文件,这也是企业中一种非常常见的方法。

注意:在使用逆向工程生成代码文件的时候,最好额外创建一个项目,不要在原来的项目中使用,因为如果你在原项目中有相同名字的文件,那么就会被新生成的文件所覆盖,导致之前写的代码没了,有一定的风险。所以实际开发中,我们一般新建一个项目,然后将生成的文件复制到自己的所需的工程中。

在这里插入图片描述

1、MGB简介

官方文档 : http://mybatis.org/generator/
逆向工程包的下载地址: https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.3.2

(1)MyBatis Generator:即MBG

(2)MBG是一个专门为MyBatis框架使用者定制的代码生成器

(3)MBG可以快速的根据表生成对应的映射文件、接口、以及bean类

(4)只可以生成单表CRUD,但是表连接、存储过程等这些复杂sql的定义需要我们手工编写

2、编写MBG的配置文件mbg.xml(重要几处配置)

相应的配置文件在官方文档中,可以找到

在这里插入图片描述

向下滑动

在这里插入图片描述在这里插入图片描述
上述配置文件是官方给出的示例配置文件,之后将其中相关部分改为和自己模块匹配的内容

3、运行程序(代码生成器)

在这里插入图片描述

二、逆向工程生成代码

①、首先创建maven项目

1、项目整体目录:

在这里插入图片描述

2、导入maven依赖:


<!-- Mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>
<!-- 日志处理 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<!-- 逆向工程 -->
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.4.0</version>
</dependency>

②、创建日志文件log4j.properties


# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE
 
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

③、创建generatorConfig.xml配置文件


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 
<generatorConfiguration>

    <!--targetRuntime="MyBatis3Simple"表示生成简易版本,这里创建原始版本,参数为MyBatis3-->
    <context id="testTables" targetRuntime="MyBatis3">
    
        <commentGenerator>
            <!-- 是否去除自动生成的注释。true:是;false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8"
                        userId="root"
                        password="root">
        </jdbcConnection>
 
        <!-- 默认false,把JDBC DECIMAL和NUMERIC类型解析为Integer,为true时把JDBC DECIMAL 和
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
 
        <!-- targetProject:POJO类生成的位置 -->
        <javaModelGenerator targetPackage="com.example.pojo"
                            targetProject="./src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.example.mapper"
                         targetProject="./src/main/resources">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.example.mapper"
                             targetProject="./src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>

        
<!--生成全部表tableName设为%-->
<!--        可选:-->
<!--        1,schema:数据库的schema;-->
<!--        2,catalog:数据库的catalog;-->
<!--        3,alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName-->
<!--        4,domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;-->
<!--        5,enableInsert(默认true):指定是否生成insert语句;-->
<!--        6,enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);-->
<!--        7,enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句;-->
<!--        8,enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);-->
<!--        9,enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);-->
<!--        10,enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句;-->
<!--        11,enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询);-->
<!--        12,enableUpdateByExample(默认true):MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);-->
<!--        13,modelType:参考context元素的defaultModelType,相当于覆盖;-->
<!--        14,delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性)-->
<!--        15,delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来。默认为false,delimitIdentifiers参考context的属性-->


         <!-- 指定生成哪些数据库表,要和数据库中对应,不能写错了,这里以t_user表为例,可以写多个;domainObjectName是要生成的实体类名称-->
        <!-- 指定数据库表 [SQLServer] schema=""必须为空 -->
        <table schema="mybatis" tableName="t_user"/>
        <!-- 有些表的字段需要指定java类型  -->
        <!-- <table schema="" tableName="">
            <columnOverride column="" javaType="" />
        </table> -->
        
    </context>
</generatorConfiguration>

注意:serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8中的 & 要改成转义字符 &amp; 这里传上来页面自动给转成了 &。

在这里插入图片描述
还有就是不同的数据库中不能含有相同的表,例如数据库A有t_user表,数据库B也有t_user表,那么到时候代码不知道生成哪个,而我恰好生成的是我们不需要的那个。啊?你说上面不是指定了数据库吗,怎么会到读取到其它数据库的表,不好意思,我试了不下十遍,最后我把其它数据库同名的表删除才成功的。如果你没有这种情况那更好咯。

④、创建逆向工程核心生成代码GeneratorSql.java


package com.thr.generator;
 
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
 
import java.io.File;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 逆向工程核心生成代码
 */
public class GeneratorSql {
   
   
    public void generator() throws Exception {
   
   
        List<String> warnings = new ArrayList<>();
        boolean overwrite = true;
        // 指定逆向工程配置文件
        String file = GeneratorSql.class.getResource("/generatorConfig.xml").getFile();
        File configFile = new File(file);
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
    // 执行main方法以生成代码
    public static void main(String[] args) {
   
   
        try {
   
   
            GeneratorSql generatorSql = new GeneratorSql();
            generatorSql.generator();
        } catch (Exception e) {
   
   
            e.printStackTrace();
        }
    }
 
}

⑤、运行逆向工程核心生成代码

运行上面的程序,如果控制台打印了如下日志,说明生成代码成功了。

在这里插入图片描述
然后我们再看项目就会发现生成了如下文件:

在这里插入图片描述

三、逆向工程举例

首先我们将上面生成的文件复制到目标项目中。在使用逆向工程举例之前,先来介绍生成的文件有哪些东西:

(1)、TUserMapper接口生成的方法介绍:

在这里插入图片描述在这里插入图片描述

  1. long countByExample(TUserExample example):按条件计数
  2. int deleteByExample(TUserExample example):按条件删除
  3. int deleteByPrimaryKey(Integer id):按主键删除
  4. int insert(TUser record):插入数据(返回值为ID)
  5. int insertSelective(TUser record):插入数据,只插入值不为null的字段,内部动态sql判断
  6. List selectByExample(TUserExample example):按条件查询,传入null表示查询所有
  7. TUser selectByPrimaryKey(Integer id):按主键查询
  8. int updateByExampleSelective(@Param(“record”) TUser record, @Param(“example”) TUserExample example):按条件更新值不为null的字段
  9. int updateByExample(@Param(“record”) TUser record, @Param(“example”) TUserExample example):按条件更新
  10. int updateByPrimaryKeySelective(TUser record):按主键更新值不为null的字段
  11. int updateByPrimaryKey(TUser record):按主键更新

测试不带条件的方法:


//Mybatis的测试
public class MybatisTest {
   
   
    //定义 SqlSession
    private SqlSession sqlSession = null;
    //定义 TUserMapper对象
    private TUserMapper mapper = null;
 
    @Before//在测试方法执行之前执行
    public void getSqlSession(){
   
   
        //1、加载 mybatis 全局配置文件
        InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //2、创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3、根据 sqlSessionFactory 产生session
        sqlSession = sqlSessionFactory.openSession();
        //4、创建Mapper接口的的代理对象,getMapper方法底层会通过动态代理生成TUserMapper的代理实现类
        mapper = sqlSession.getMapper(TUserMapper.class);
    }
 
    @After//在测试方法执行完成之后执行
    public void destroy() throws IOException {
   
   
        sqlSession.commit();
        sqlSession.close();
    }
    //查询所有用户信息
    @Test
    public void selectAllUser(){
   
   
        List<TUser> tUsers = mapper.selectByExample(null);//传入null表示查询所有
        for (TUser tUser : tUsers) {
   
   
            System.out.println(tUser);
        }
    }
    //根据用户id查询用户
    @Test
    public void selectByUserId(){
   
   
        TUser tUser = mapper.selectByPrimaryKey(1);
        System.out.println(tUser);
    }
    //添加用户信息
    @Test
    public void insertUser(){
   
   
        TUser tUser = new TUser();
        tUser.setUsername("凡尔赛");
        tUser.setAge(18);
        tUser.setBirthday(new Date());
        tUser.setSex("0");
        tUser.setAddress("漂亮国");
        int i = mapper.insertSelective(tUser);
        System.out.println(i>0?"添加成功":"添加失败");
    }
    //更新用户信息
    @Test
    public void updateUser(){
   
   
        TUser tUser = new TUser();
        tUser.setId(8);//这里要设置id才能修改成功,否则不知道修改哪一条数据
        tUser.setUsername("川建国");
        tUser.setAge(50);
        tUser.setBirthday(new Date());
        tUser.setSex("1");
        tUser.setAddress("漂亮国");
        int i = mapper.updateByPrimaryKeySelective(tUser);
        System.out.println(i>0?"修改成功":"修改失败");
    }
    //删除用户信息
    @Test
    public void deleteUser(){
   
   
        int i = mapper.deleteByPrimaryKey(8);
        System.out.println(i>0?"删除成功":"删除失败");
    }
}

(2)、TUserExample条件扩展类介绍:

上面的测试方法是不带条件的操作,那么接下来学习一下按条件如何进行增删改查操作,我们在逆向工程中已经生成了这个类TUserExample,这个类就是一个条件扩展类,里面定义了一系列方法用来做条件,比如:排序、去重、大于、小于、等于、模糊查询、数据在某某之间等等。

我们在TUserExample类中可以看到定义了一个内部类GeneratedCriteria,这个内部类就定义了一系列条件的方法,这些条件最后都会拼接在SQL中,但是我们一般不用它,都用它的子类Criteria来进行操作,Criteria继承了内部类GeneratedCriteria。

在这里插入图片描述
简单举例:


//Mybatis的测试
public class MybatisTest1 {
   
   
    //定义 SqlSession
    private SqlSession sqlSession = null;
    //定义 UserMapper对象
    private TUserMapper mapper = null;
 
    @Before//在测试方法执行之前执行
    public void getSqlSession(){
   
   
        //1、加载 mybatis 全局配置文件
        InputStream is = MybatisTest1.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //2、创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3、根据 sqlSessionFactory 产生session
        sqlSession = sqlSessionFactory.openSession();
        //4、创建Mapper接口的的代理对象,getMapper方法底层会通过动态代理生成UserMapper的代理实现类
        mapper = sqlSession.getMapper(TUserMapper.class);
    }
 
    @After//在测试方法执行完成之后执行
    public void destroy() throws IOException {
   
   
        sqlSession.commit();
        sqlSession.close();
    }
    //模糊查询用户信息
    @Test
    public void selectUserLike(){
   
   
        TUserExample example = new TUserExample();
        TUserExample.Criteria criteria = example.createCriteria();
        //模糊条件
        criteria.andUsernameLike("%三%");
        /*sql语句相当于:select id, username, age, birthday, sex, address 
                        from t_user WHERE ( username like ? )*/
        List<TUser> tUsers = mapper.selectByExample(example);
        for (TUser tUser : tUsers) {
   
   
            System.out.println(tUser);
        }
    }
    //查询年龄在18-30岁之间的用户信息
    @Test
    public void selectUserBetween(){
   
   
        TUserExample example = new TUserExample();
        TUserExample.Criteria criteria = example.createCriteria();
        //Between条件
        criteria.andAgeBetween(18,30);
        example.or(criteria);
        example.setDistinct(true);
        /*sql语句相当于:select distinct id, username, age, birthday, sex, address 
                        from t_user WHERE ( age between ? and ? ) or( age between ? and ? )*/
        List<TUser> tUsers = mapper.selectByExample(example);
        for (TUser tUser : tUsers) {
   
   
            System.out.println(tUser);
        }
    }
    //查询用户名A或B
    @Test
    public void selectUserOr(){
   
   
        TUserExample example = new TUserExample();
        TUserExample.Criteria criteria1 = example.createCriteria();
        criteria1.andUsernameEqualTo("黄飞鸿");
 
        TUserExample.Criteria criteria2 = example.createCriteria();
        criteria2.andUsernameEqualTo("马保国");
        //将criteria2条件拼接在 or 关键字字后面
        example.or(criteria2);
        /*sql语句相当于:select id, username, age, birthday, sex, address
            from t_user WHERE ( username = ? ) or( username = ? )*/
        List<TUser> tUsers = mapper.selectByExample(example);
        for (TUser tUser : tUsers) {
   
   
            System.out.println(tUser);
        }
    }
    //根据用户名删除用户
    @Test
    public void deleteUserExample(){
   
   
        TUserExample example = new TUserExample();
        TUserExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo("凡尔赛");
        //sql语句相当于:delete from t_user WHERE ( username = ? )
        int i = mapper.deleteByExample(example);
        System.out.println(i>0?"删除成功":"删除失败");
    }
}

至此Mybatis的逆向工程就全部介绍完成了,说难也不是特别难,只要一步步自己去实现,去理解一遍,是非常简单的,可能复杂一点的是那个XxxExample类,但如果自己多举几个例子也不难。

四、逆向工程代码扩展

问:MyBatis Generator 为什么不生成 service 层和 controller 层 ?
答:mybatis 是持久层框架。

①、自定义注释生成器

1、创建自定义注释生成器 CommentGenerator.java


import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
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.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;
 
import java.util.Properties;
 
/**
 * 自定义注释生成器
 * Created by macro on 2018/4/26.
 */
public class CommentGenerator extends DefaultCommentGenerator {
   
   
    private boolean addRemarkComments = false;
    private static final String EXAMPLE_SUFFIX="Example";
    private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty";
 
    /**
     * 设置用户配置的参数
     */
    @Override
    public void addConfigurationProperties(Properties properties) {
   
   
        super.addConfigurationProperties(properties);
        this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
    }
 
    /**
     * 给字段添加注释
     */
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable,
                                IntrospectedColumn introspectedColumn) {
   
   
        String remarks = introspectedColumn.getRemarks();
        //根据参数和备注信息判断是否添加备注信息
        if(addRemarkComments&&StringUtility.stringHasValue(remarks)){
   
   
//            addFieldJavaDoc(field, remarks);
            //数据库中特殊字符需要转义
            if(remarks.contains("\"")){
   
   
                remarks = remarks.replace("\"","'");
            }
            //给model的字段添加swagger注解
            field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\")");
        }
    }
 
    /**
     * 给model的字段添加注释
     */
    private void addFieldJavaDoc(Field field, String remarks) {
   
   
        //文档注释开始
        field.addJavaDocLine("/**");
        //获取数据库字段的备注信息
        String[] remarkLines = remarks.split(System.getProperty("line.separator"));
        for(String remarkLine:remarkLines){
   
   
            field.addJavaDocLine(" * "+remarkLine);
        }
        addJavadocTag(field, false);
        field.addJavaDocLine(" */");
    }
 
    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {
   
   
        super.addJavaFileComment(compilationUnit);
        //只在model中添加swagger注解类的导入
        if(!compilationUnit.isJavaInterface()&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){
   
   
            compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME));
        }
    }
}

2、添加 generatorConfig.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 
<generatorConfiguration>
    <properties resource="generator.properties"/>
    <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 为模型生成序列化方法-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 为生成的Java模型创建一个toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <!--生成mapper.xml时覆盖原文件-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
        
        <commentGenerator type="com.jzxs.etp.mbg.CommentGenerator">
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>
 
        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
 
        <!--指定生成model的路径-->
        <javaModelGenerator targetPackage="com.jzxs.etp.mbg.model"
                            targetProject="./src/main/java"/>
        <!--指定生成mapper.xml的路径-->
        <sqlMapGenerator targetPackage="com.jzxs.etp.mbg.mapper"
                         targetProject="./src/main/resources"/>
        <!--指定生成mapper接口的的路径-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.jzxs.etp.mbg.mapper"
                             targetProject="./src/main/java"/>
       
        <!--生成全部表tableName设为%-->
        <table tableName="history_picture"></table>
        
    </context>
</generatorConfiguration>

②、自定义Controller和Service插件

1、自定义生成Controller和Service的模板。


package com.jzxs.etp.mbg;
 
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
 
import java.util.ArrayList;
import java.util.List;
 
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;
 
public class ServiceAndControllerGeneratorPlugin extends PluginAdapter  {
   
   
 
    // 项目目录,一般为 src/main/java
    private String targetProject;
 
    // service包名,如:com.thinkj2ee.cms.service.service
    private String servicePackage;
 
    // service实现类包名,如:com.thinkj2ee.cms.service.service.impl
    private String serviceImplPackage;
    // Controlle类包名,如:com.thinkj2ee.cms.service.controller
    private String controllerPackage;
    // service接口名前缀
    private String servicePreffix;
 
    // service接口名后缀
    private String serviceSuffix;
 
    // service接口的父接口
    private String superServiceInterface;
 
    // service实现类的父类
    private String superServiceImpl;
    // controller类的父类
    private String superController;
 
    // dao接口基类
    private String superDaoInterface;
 
    // Example类的包名
    private String examplePacket;
 
    private String recordType;
 
    private String modelName;
 
    private FullyQualifiedJavaType model;
 
    private String serviceName;
    private String serviceImplName;
    private String controllerName;
 
    @Override
    public boolean validate(List<String> warnings) {
   
   
        boolean valid = true;
 
       /* if (!stringHasValue(properties
                .getProperty("targetProject"))) { //$NON-NLS-1$
            warnings.add(getString("ValidationError.18", //$NON-NLS-1$
                    "MapperConfigPlugin", //$NON-NLS-1$
                    "targetProject")); //$NON-NLS-1$
            valid = false;
        }
        if (!stringHasValue(properties.getProperty("servicePackage"))) { //$NON-NLS-1$
            warnings.add(getString("ValidationError.18", //$NON-NLS-1$
                    "MapperConfigPlugin", //$NON-NLS-1$
                    "servicePackage")); //$NON-NLS-1$
            valid = false;
        }
        if (!stringHasValue(properties.getProperty("serviceImplPackage"))) { //$NON-NLS-1$
            warnings.add(getString("ValidationError.18", //$NON-NLS-1$
                    "MapperConfigPlugin", //$NON-NLS-1$
                    "serviceImplPackage")); //$NON-NLS-1$
            valid = false;
        }
*/
        targetProject = properties.getProperty("targetProject");
        servicePackage = properties.getProperty("servicePackage");
        serviceImplPackage = properties.getProperty("serviceImplPackage");
        servicePreffix = properties.getProperty("servicePreffix");
        servicePreffix = stringHasValue(servicePreffix) ? servicePreffix : "";
        serviceSuffix = properties.getProperty("serviceSuffix");
        serviceSuffix = stringHasValue(serviceSuffix) ? serviceSuffix : "";
        superServiceInterface = properties.getProperty("superServiceInterface");
        superServiceImpl = properties.getProperty("superServiceImpl");
        superDaoInterface = properties.getProperty("superDaoInterface");
        controllerPackage = properties.getProperty("controllerPackage");
        superController = properties.getProperty("superController");
 
        return valid;
    }
 
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
   
   
        recordType = introspectedTable.getBaseRecordType();
        modelName = recordType.substring(recordType.lastIndexOf(".") + 1);
        model = new FullyQualifiedJavaType(recordType);
        serviceName = servicePackage + "." + servicePreffix + modelName + serviceSuffix;
        serviceImplName = serviceImplPackage + "." + modelName + serviceSuffix+"Impl";
        examplePacket=recordType.substring(0,recordType.lastIndexOf("."));
        controllerName=controllerPackage.concat(".").concat(modelName).concat("Controller");
        List<GeneratedJavaFile> answer = new ArrayList<>();
        GeneratedJavaFile gjf = generateServiceInterface(introspectedTable);
        GeneratedJavaFile gjf2 = generateServiceImpl(introspectedTable);
        GeneratedJavaFile gjf3 = generateController(introspectedTable);
        answer.add(gjf);
        answer.add(gjf2);
        answer.add(gjf3);
        return answer;
    }
 
    // 生成service接口
    private GeneratedJavaFile generateServiceInterface(IntrospectedTable introspectedTable) {
   
   
        FullyQualifiedJavaType service = new FullyQualifiedJavaType(serviceName);
        Interface serviceInterface = new Interface(service);
        serviceInterface.setVisibility(JavaVisibility.PUBLIC);
        // 添加父接口
        if(stringHasValue(superServiceInterface)) {
   
   
            String superServiceInterfaceName = superServiceInterface.substring(superServiceInterface.lastIndexOf(".") + 1);
            serviceInterface.addImportedType(new FullyQualifiedJavaType(superServiceInterface));
            serviceInterface.addImportedType(new FullyQualifiedJavaType(recordType));
            serviceInterface.addSuperInterface(new FullyQualifiedJavaType(superServiceInterfaceName + "<" + modelName + ">"));
        }
        GeneratedJavaFile gjf = new GeneratedJavaFile(serviceInterface, targetProject, context.getJavaFormatter());
        return gjf;
    }
 
    // 生成serviceImpl实现类
    private GeneratedJavaFile generateServiceImpl(IntrospectedTable introspectedTable) {
   
   
        FullyQualifiedJavaType service = new FullyQualifiedJavaType(serviceName);
        FullyQualifiedJavaType serviceImpl = new FullyQualifiedJavaType(serviceImplName);
        TopLevelClass clazz = new TopLevelClass(serviceImpl);
        //描述类的作用域修饰符
        clazz.setVisibility(JavaVisibility.PUBLIC);
        //描述类 引入的类
        clazz.addImportedType(service);
        //描述类 的实现接口类
        clazz.addSuperInterface(service);
        if(stringHasValue(superServiceImpl)) {
   
   
            String superServiceImplName = superServiceImpl.substring(superServiceImpl.lastIndexOf(".") + 1);
            clazz.addImportedType(superServiceImpl);
            clazz.addImportedType(recordType);
            clazz.setSuperClass(superServiceImplName + "<" + modelName + ">");
        }
        clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Service"));
        clazz.addAnnotation("@Service");
 
        String daoFieldType = introspectedTable.getMyBatis3JavaMapperType();
        String daoFieldName = firstCharToLowCase(daoFieldType.substring(daoFieldType.lastIndexOf(".") + 1));
        //描述类的成员属性
        Field daoField = new Field(daoFieldName, new FullyQualifiedJavaType(daoFieldType));
        clazz.addImportedType(new FullyQualifiedJavaType(daoFieldType));
        clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));
        //描述成员属性 的注解
        daoField.addAnnotation("@Autowired");
        //描述成员属性修饰符
        daoField.setVisibility(JavaVisibility.PRIVATE);
        clazz.addField(daoField);
 
        //描述 方法名
        Method method = new Method("getMapper");
        //方法注解
        method.addAnnotation("@Override");
        FullyQualifiedJavaType methodReturnType = new FullyQualifiedJavaType("Object");
        //返回值
        method.setReturnType(methodReturnType);
        //方法体,逻辑代码
        method.addBodyLine("return " + daoFieldName + ";");
        //修饰符
        method.setVisibility(JavaVisibility.PUBLIC);
        clazz.addMethod(method);
 
 
        Method method1 = new Method("getExample");
        method1.addAnnotation("@Override");
        FullyQualifiedJavaType methodReturnType1 = new FullyQualifiedJavaType("Object");
        clazz.addImportedType(new FullyQualifiedJavaType(examplePacket.concat(".").concat(modelName).concat("Example")));
        method1.setReturnType(methodReturnType1);
        method1.addBodyLine("return new " + modelName + "Example();");
        method1.setVisibility(JavaVisibility.PUBLIC);
        clazz.addMethod(method1);
 
        GeneratedJavaFile gjf2 = new GeneratedJavaFile(clazz, targetProject, context.getJavaFormatter());
        return gjf2;
    }
 
 
    // 生成controller类
    private GeneratedJavaFile generateController(IntrospectedTable introspectedTable) {
   
   
 
        FullyQualifiedJavaType controller = new FullyQualifiedJavaType(controllerName);
        TopLevelClass clazz = new TopLevelClass(controller);
        //描述类的作用域修饰符
        clazz.setVisibility(JavaVisibility.PUBLIC);
 
        //添加@Controller注解,并引入相应的类
        clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.web.bind.annotation.RestController"));
        clazz.addAnnotation("@RestController");
        //添加@RequestMapping注解,并引入相应的类
        clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.web.bind.annotation.RequestMapping"));
        clazz.addAnnotation("@RequestMapping(\"/"+firstCharToLowCase(modelName)+"\")");
        //添加@Api注解,并引入相应的类
        clazz.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.Api"));
        String controllerSimpleName = controllerName.substring(controllerName.lastIndexOf(".")</
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT小郭.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值