自定义Mybatis Plus代码生成器(增加Vo类的生成)

最近有在学习使用mybatis plus,了解到使用mp代码生成器可以方便快捷的生成代码,为了适用于自己开发需要,自定义了一个mp的代码生成器,增加了几个小功能:

1.增加了Vo类的生成,其实思路很简单,利用生成的entity实体类,复制一份,替换掉其中的几个关键字就可以了。

2.可以根据表名,根据参数判断是否去掉前缀,然后根据剩余部分自动生成包名,在批量生成时更好的区分每个表的数据。

代码如下:

public class CodeGeneratorPlus {
	/**
	 * 数据库类型
	 */
	private static final DbType DATA_SOURCE_TYPE = DbType.MYSQL;
	/**
	 * 数据库驱动
	 */
	private static final String DATA_SOURCE_DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";
	/**
	 * 数据库连接
	 */
	private static final String DATA_SOURCE_URL = "jdbc:mysql://127.0.0.1:3306/localmysql?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
	/**
	 * 数据库用户名
	 */
	private static final String DATA_SOURCE_USER_NAME = "root";
	/**
	 * 数据库连接密码
	 */
	private static final String DATA_SOURCE_PASSWORD = "root";
	/**
	 * 数据库默认表空间名称
	 */
	private static final String DATA_SOURCE_SCHEMA_NAME = "";
	/**
	 * 生成的代码默认输出文件目录
	 */
	private static final String DEFAULT_OUT_PUT_DIR = System.getProperty("user.dir") + "/src/main/java";
	/**
	 * 默认包名称
	 */
	private static final String DEFAULT_PARENT_PACK = "cn.com.mtd";
	/**
	 * 默认父级实体类全限定类名
	 */
	private static final String BASE_ENTITY_CLASS_NAME = "cn.com.mtd.entity.BaseEntity";
	/**
	 * 公共父类实体类中含有的字段
	 */
	private static final String[] SUPPER_ENTITY_CONTAINS_FIELD = { "ID", "CREATE_BY", "UPDATE_BY", "CREATE_DATE","UPDATE_DATE", "DELETE_FLAG", "JI_GOU_ID" };

	public static void main(String[] args) {
		// 数据库表名称
		String[] tableNames = { "REG_TI_JIAN_HAO_XU_HAO" };
		// 1.得到全局配置参数
		GlobalConfig config = getGlobalConfig();
		// 2.得到数据源配置参数
		DataSourceConfig dsConfig = getDataSourceConfig();
		// 3.得到策略配置参数
		StrategyConfig stConfig = null;
		// 4. 包名策略配置
		PackageConfig pkConfig = null;

		boolean isTablePrefix = true;
		for (int i = 0; i < tableNames.length; i++) {
			// 5. 整合配置
			AutoGenerator ag = new AutoGenerator();
			ag.setGlobalConfig(config).setDataSource(dsConfig);
			String tableName = tableNames[i];
			stConfig = getStrategyConfig(true, isTablePrefix, tableName);
			ag.setStrategy(stConfig);
			pkConfig = getPackageConfig(isTablePrefix, tableName);
			ag.setPackageInfo(pkConfig);
			// 6. 执行
			ag.execute();
		}
		// 生成Vo对象
		produceViewObject(isTablePrefix, tableNames);

		System.out.println("代码生成完成!");
	}

	/**
	 * 根据表名生成VO对象,用于mybatis-plus代码生成以后再生成
	 * 
	 * @param isTablePrefix
	 * @param tableNames
	 */
	private static void produceViewObject(boolean isTablePrefix, String... tableNames) {
		for (int i = 0; i < tableNames.length; i++) {
			String tableName = tableNames[i];
			tableName = isTablePrefix ? tableName.substring(tableName.indexOf("_") + 1) : tableName;
			String suPkStr = StringUtils.remove(tableName, "_").toLowerCase();
			String outPutDir = DEFAULT_OUT_PUT_DIR + "/" + (DEFAULT_PARENT_PACK.replace(".", "/")) + "/vo/" + suPkStr
					+ "/";
			String baseFileName = StringUtil.underline2Camel(tableName, false);
			try {
				File outFile = new File(outPutDir);
				if (!outFile.exists()) {
					outFile.mkdirs();
				}
				File voFile = new File(outFile, baseFileName + "Vo.java");
				if (!voFile.exists()) {
					voFile.createNewFile();
				}
				BufferedReader reader = new BufferedReader(
						new FileReader(DEFAULT_OUT_PUT_DIR + "/" + (DEFAULT_PARENT_PACK.replace(".", "/")) + "/entity/"
								+ suPkStr + "/" + baseFileName + "Entity.java"));
				FileWriter fw = new FileWriter(voFile);
				String line = null;
				while ((line = reader.readLine()) != null) {
					// 将实体类中的entity变为Vo
					line = line.replace("entity", "vo").replace("Entity", "Vo");
					// 去掉mybatis-plus注解
					if (line.contains("TableName") || line.contains("TableField") || line.contains("Accessors")) {
						continue;
					}
					line += "\r\n";
					fw.write(line);
				}
				fw.close();
				reader.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private static PackageConfig getPackageConfig(boolean isTablePrefix, String tableName) {
		// 包名策略配置
		PackageConfig pkConfig = new PackageConfig();
		tableName = isTablePrefix ? tableName.substring(tableName.indexOf("_") + 1) : tableName;
		String suPkStr = StringUtils.remove(tableName, "_").toLowerCase();
		pkConfig.setParent(DEFAULT_PARENT_PACK) // 父包
				.setMapper("mapper." + suPkStr)// mapper文件的包名
				.setService("service." + suPkStr)// servcie文件的包名
				.setServiceImpl("service.impl." + suPkStr) // serviceimpl文件的包名
				.setController("controller." + suPkStr)// controller文件的包名
				.setEntity("entity." + suPkStr) // entity文件的包名
				.setXml("mapper.mapping." + suPkStr); // mapper.xml文件存放的位置
		return pkConfig;
	}

	/**
	 * 获取策略配置
	 * 
	 * @param isExtendsSuper 是否基础默认父类
	 * @param isTablePrefix  表是否有需要取消的前缀
	 * @param tableNames     表名
	 * @return
	 */
	private static StrategyConfig getStrategyConfig(boolean isExtendsSuper, boolean isTablePrefix,
			String... tableNames) {
		// 3. 策略配置globalConfiguration中
		if (tableNames == null || tableNames.length == 0) {
			throw new RuntimeException("请不要传入空的表名参数!");
		}
		StrategyConfig stConfig = new StrategyConfig();
		if (isTablePrefix) {
			Set<String> prefixSet = new HashSet<>();
			for (int i = 0; i < tableNames.length; i++) {
				int index = tableNames[0].indexOf("_");
				if (index != -1) {
					prefixSet.add(tableNames[0].substring(0, index));
				}
			}
			stConfig.setTablePrefix(prefixSet.toArray(new String[prefixSet.size()]));
		}
		if (isExtendsSuper) {
			stConfig.setSuperEntityClass(BASE_ENTITY_CLASS_NAME) // 实体类继承的公共父类
					.setSuperEntityColumns(SUPPER_ENTITY_CONTAINS_FIELD);// 父类中的字段 ,子类继承了父类会忽略这些字段
		}
		stConfig.setCapitalMode(true) // 全局大写命名
				.setRestControllerStyle(false) // 生成 @RestController 控制器
				// .setDbColumnUnderline(true)
				.setEntityTableFieldAnnotationEnable(true) // 在实体类的字段上面添加注解映射数据的字段名称
				// 数据库表映射到实体的命名策略
				.setNaming(NamingStrategy.underline_to_camel) // 将数据库中有下划线分割的字段在实体类中转为驼峰命名法
				.setColumnNaming(NamingStrategy.underline_to_camel).setEntityLombokModel(true)// 使用lombok注解模式

				.setInclude(tableNames);
		return stConfig;
	}

	private static DataSourceConfig getDataSourceConfig() {
		// 2. 数据源配置
		DataSourceConfig dsConfig = new DataSourceConfig();
		dsConfig.setDbType(DATA_SOURCE_TYPE) // 设置数据库类型
				.setDriverName(DATA_SOURCE_DRIVER_CLASS_NAME) // 数据库驱动名称
				.setUrl(DATA_SOURCE_URL)// 数据库连接url
				.setUsername(DATA_SOURCE_USER_NAME) // 数据库用户
				.setPassword(DATA_SOURCE_PASSWORD); // 数据库密码
		if (StringUtils.isNotBlank(DATA_SOURCE_SCHEMA_NAME)) {
			dsConfig.setSchemaName(DATA_SOURCE_SCHEMA_NAME);// 数据库表空间名称
		}
		return dsConfig;
	}

	private static GlobalConfig getGlobalConfig() {
		// 1. 全局配置
		GlobalConfig config = new GlobalConfig();
		config.setActiveRecord(false) // 是否使用AR模式
				.setAuthor("jinghx") // 类作者名称
				.setOutputDir(DEFAULT_OUT_PUT_DIR) // 代码文件生成路径
				.setFileOverride(true) // 文件是否覆盖
				// .setIdType(IdType.NONE) // 主键策略
				.setServiceName("%sService") // 设置生成的service接口的名字的首字母是否为I
				.setServiceImplName("%sServiceImpl") // 设置Service实现类名称格式
				.setMapperName("%sMapper") // 设置Mapper类的名称格式
				.setControllerName("%sController") // 设置Controller类的名称格式
				.setEntityName("%sEntity") // 设置Entity类的名称格式
				.setOpen(false) // 生成文件后是否打开文件
				.setBaseResultMap(true)// 在mapper.xml文件中生成基本的resultMap
				.setBaseColumnList(true);// 在mapper.xml文件中生成基本的SQL片段
		return config;
	}
}

由下划线组成的字符串去掉下划线首字母转小写方法实现,为了方便大家参考,贴出整个StringUtil工具类的代码:

public class StringUtil {

    /**
     * 下划线转驼峰法(默认小驼峰)
     *
     * @param line 源字符串
     * @param smallCamel 大小驼峰,是否为小驼峰(驼峰,第一个字符是大写还是小写)
     * @return 转换后的字符串
     */
    public static String underline2Camel(String line, boolean... smallCamel) {
        if (StringUtils.isBlank(line)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        Pattern pattern = Pattern.compile("([A-Za-z\\d]+)(_)?");
        Matcher matcher = pattern.matcher(line);
        // 匹配正则表达式
        while (matcher.find()) {
            String word = matcher.group();
            // 当是true 或则是空的情况
            if ((smallCamel.length == 0 || smallCamel[0]) && matcher.start() == 0) {
                sb.append(Character.toLowerCase(word.charAt(0)));
            } else {
                sb.append(Character.toUpperCase(word.charAt(0)));
            }

            int index = word.lastIndexOf('_');
            if (index > 0) {
                sb.append(word.substring(1, index).toLowerCase());
            } else {
                sb.append(word.substring(1).toLowerCase());
            }
        }
        return sb.toString();
    }

    /**
     * 驼峰法转下划线
     *
     * @param line 源字符串
     * @return 转换后的字符串
     */
    public static String camel2Underline(String line) {
        if (StringUtils.isBlank(line)) {
            return "";
        }
        line = String.valueOf(line.charAt(0)).toUpperCase().concat(line.substring(1));
        StringBuffer sb = new StringBuffer();
        Pattern pattern = Pattern.compile("[A-Z]([a-z\\d]+)?");
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()) {
            String word = matcher.group();
            sb.append(word.toUpperCase());
            sb.append(matcher.end() == line.length() ? "" : "_");
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String line = "are_you_ok";
        // 下划线转驼峰(大驼峰)
        // AreYouOk
        String camel = underline2Camel(line, false);
        System.out.println(camel);

        // 下划线转驼峰(小驼峰)
        // areYouOk
        camel = underline2Camel(line);
        System.out.println(camel);

        // 驼峰转下划线
        // ARE_YOU_OK
        System.out.println(camel2Underline(camel));
    }
}
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
Mybatis-Plus 是一个基于 Mybatis 的增强工具,它简化了 Mybatis 的开发流程,提供了很多实用的功能,其中之一就是代码生成器代码生成器可以根据数据库表结构自动生成实体、mapper 接口、xml 文件等代码,极大地提高了开发效率。但是,Mybatis-Plus 自动生成的实体并不一定满足我们的需求,因此我们需要自定义模板来生成我们需要的。 下面,我将介绍如何使用 Mybatis-Plus 自定义模板生成 dto、vo、convertor。 1. 创建自定义模板 我们需要在 Mybatis-Plus 的代码生成器中创建自定义模板。打开 Mybatis-Plus 的代码生成器,点击“自定义模板”选项卡,然后点击“添加模板”按钮,输入模板名称和文件名,然后点击“保存”按钮。 在模板编辑器中,我们可以使用 FreeMarker 语法来编写模板。下面是一个简单的模板示例,用于生成 dto : ``` package ${dtoPackage}; import lombok.Data; @Data public class ${dtoName} { <#list table.columnList as column> private ${column.javaType} ${column.propertyName}; </#list> } ``` 在这个模板中,我们使用 `${}` 占位符来引用变量。`dtoPackage` 和 `dtoName` 变量由代码生成器自动提供,表示生成的 dto 的包名和名。`table` 变量表示当前生成的表信息,包含表名、列名、列型等信息。我们使用 `<#list>` 和 `</#list>` 标签来遍历表的列信息,并生成对应的属性。 2. 配置代码生成器 在使用自定义模板之前,我们需要配置代码生成器。打开 Mybatis-Plus 的代码生成器,点击“全局配置”选项卡,在“自定义配置”中添加以下配置: ``` # dto 模板配置 dto=templates/dto.java.vm dtoOutputDir=src/main/java/${dtoPackage}/ ``` 其中,`dto` 是我们自定义模板的名称,`dtoOutputDir` 是生成的 dto 的输出目录。我们还可以添加其他自定义模板和输出目录,例如: ``` # vo 模板配置 vo=templates/vo.java.vm voOutputDir=src/main/java/${voPackage}/ # convertor 模板配置 convertor=templates/convertor.java.vm convertorOutputDir=src/main/java/${convertorPackage}/ ``` 3. 生成代码 配置完成后,我们可以点击“执行”按钮来生成代码。代码生成器将根据配置生成实体、mapper 接口、xml 文件、dto、vo、convertor 等代码。我们只需要将生成的代码复制到项目中即可。 总结 使用 Mybatis-Plus 的代码生成器可以大大提高开发效率,而自定义模板则可以生成我们需要的。通过自定义模板,我们可以生成 dto、vo、convertor 等常用,避免手写重复的代码,提高开发效率和代码质量。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码探险家_cool

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

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

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

打赏作者

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

抵扣说明:

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

余额充值