自定义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;
	}
}

由下划线组成的字符串去掉下划线转小写,工具类:

/**
	 * 下划线转驼峰法(默认小驼峰)
	 *
	 * @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();
	}
posted @ 2020-01-01 10:34  三分魔系  阅读(374)  评论(0编辑  收藏  举报