• 自定义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 += "
    ";
    					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();
    	}
    
    一颗安安静静的小韭菜。文中如果有什么错误,欢迎指出。
  • 相关阅读:
    前端工程化之动态数据代理
    webapp开发之需要知道的css细节
    html-webpack-plugin详解
    file-loader引起的html-webpack-plugin坑
    浅谈react受控组件与非受控组件
    React创建组件的三种方式及其区别
    react项目开发中遇到的问题
    css伪元素:before和:after用法详解
    python之文件操作
    python之range和xrange
  • 原文地址:https://www.cnblogs.com/c-Ajing/p/13448367.html
Copyright © 2020-2023  润新知