content: package code;
  
  import static com.open.boot.core.CoreConstant.BASE_PACKAGE;
  import static com.open.boot.core.CoreConstant.MAPPER_INTERFACE_REFERENCE;
  
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.commons.lang3.StringUtils;
  import org.mybatis.generator.api.MyBatisGenerator;
  import org.mybatis.generator.config.Configuration;
  import org.mybatis.generator.config.Context;
  import org.mybatis.generator.config.GeneratedKey;
  import org.mybatis.generator.config.JDBCConnectionConfiguration;
  import org.mybatis.generator.config.JavaClientGeneratorConfiguration;
  import org.mybatis.generator.config.JavaModelGeneratorConfiguration;
  import org.mybatis.generator.config.ModelType;
  import org.mybatis.generator.config.PluginConfiguration;
  import org.mybatis.generator.config.PropertyRegistry;
  import org.mybatis.generator.config.SqlMapGeneratorConfiguration;
  import org.mybatis.generator.config.TableConfiguration;
  import org.mybatis.generator.internal.DefaultShellCallback;
  
  import com.google.common.base.CaseFormat;
  
  import freemarker.template.TemplateExceptionHandler;
  
  /**
   * 代码生成器，根据数据表名称生成对应的Model、Mapper、Service、Controller简化开发。
   */
  public class CodeGenerator {
  	// JDBC配置，请修改为你项目的实际配置
  	private static final String JDBC_URL = "jdbc:mysql://47.92.97.192:3306/jzxxpt";
  	private static final String JDBC_USERNAME = "tys";
  	private static final String JDBC_PASSWORD = "tysTYS";
  	private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
  
  	private static final String PROJECT_PATH = System.getProperty("user.dir");// 项目在硬盘上的基础路径
  	private static final String TEMPLATE_FILE_PATH = PROJECT_PATH + "/src/test/resources/generator/template";// 模板位置
  
  	private static final String JAVA_PATH = "/src/main/java"; // java文件路径
  	private static final String RESOURCES_PATH = "/src/main/resources";// 资源文件路径
  
  	private static final String AUTHOR = "actor-T";// @author
  	private static final String DATE = new SimpleDateFormat("yyyy/MM/dd").format(new Date());// @date
  
  	/**
  	 * 同一模块多张表可同时生成，为空默认按驼峰法生成 ，去掉前缀的写法"s_login_log", "LoginLog"
  	 *
  	 * @param args 参数
  	 */
  	public static void main(String[] args) {
  		List<TableMapper> tables = new ArrayList<>();
  		TableMapper MapperOne = new TableMapper("t_user", "User");
  		// TableMapper MapperTwo = new TableMapper("sampling_rock", "");
  		// TableMapper MapperThree = new TableMapper("s_login_log", "LoginLog");
  		// TableMapper MapperFour = new TableMapper("sampling_water", "");
  		// TableMapper MapperFive = new TableMapper("company", "");
  		tables.add(MapperOne);
  		// tables.add(MapperTwo);
  		// tables.add(MapperFour);
  		// tables.add(MapperFive);
  		genCode("user", tables);// 模块名、数据表名
  	}
  
  	/**
  	 * 通过数据表名称生成代码，Model 名称通过解析数据表名称获得，下划线转大驼峰的形式。 如输入表名称 "t_user_detail" 将生成
  	 * TUserDetail、TUserDetailMapper、TUserDetailService ...
  	 *
  	 * @param moduleName 模块名称
  	 * @param tables     数据表Mapper...
  	 */
  	public static void genCode(String moduleName, List<TableMapper> tables) {
  		if (StringUtils.isEmpty(moduleName)) {
  			throw new RuntimeException("需要输入模块名称。");
  		}
  		for (TableMapper tableMapper : tables) {
  			genCodeByCustomModelName(moduleName, tableMapper.getTableName(), tableMapper.getModelName());
  		}
  	}
  
  	/**
  	 * 通过数据表名称，和自定义的 Model 名称生成代码 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User" 将生成
  	 * User、UserMapper、UserService ...
  	 *
  	 * @param moduleName 所属模块名称
  	 * @param tableName  数据表名称
  	 * @param modelName  自定义的 Model 名称
  	 */
  	public static void genCodeByCustomModelName(String moduleName, String tableName, String modelName) {
  		genModelAndMapper(moduleName, tableName, modelName);
  		genService(moduleName, tableName, modelName);
  		genController(moduleName, tableName, modelName);
  	}
  
  	public static void genModelAndMapper(String moduleName, String tableName, String modelName) {
  		Context context = new Context(ModelType.FLAT);
  		context.setId("Potato");
  		context.setTargetRuntime("MyBatis3Simple");
  		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
  		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
  
  		JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
  		jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
  		jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
  		jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
  		jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
  		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
  
  		PluginConfiguration pluginConfiguration = new PluginConfiguration();
  		pluginConfiguration.setConfigurationType("tk.mybatis.mapper.generator.MapperPlugin");
  		pluginConfiguration.addProperty("mappers", MAPPER_INTERFACE_REFERENCE);
  		context.addPluginConfiguration(pluginConfiguration);
  
  		JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
  		javaModelGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
  		javaModelGeneratorConfiguration.setTargetPackage(BASE_PACKAGE + "." + moduleName + ".model");
  		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
  
  		SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
  		sqlMapGeneratorConfiguration.setTargetProject(PROJECT_PATH + RESOURCES_PATH + "/mapper");
  		sqlMapGeneratorConfiguration.setTargetPackage(moduleName);
  		context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
  
  		JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
  		javaClientGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
  		javaClientGeneratorConfiguration.setTargetPackage(BASE_PACKAGE + "." + moduleName + ".dao");
  		javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
  		context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
  
  		TableConfiguration tableConfiguration = new TableConfiguration(context);
  		tableConfiguration.setTableName(tableName);
  		if (StringUtils.isNotEmpty(modelName))
  			tableConfiguration.setDomainObjectName(modelName);
  		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
  		context.addTableConfiguration(tableConfiguration);
  
  		List<String> warnings;
  		MyBatisGenerator generator;
  		try {
  			Configuration config = new Configuration();
  			config.addContext(context);
  			config.validate();
  
  			boolean overwrite = true;
  			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
  			warnings = new ArrayList<>();
  			generator = new MyBatisGenerator(config, callback, warnings);
  			generator.generate(null);
  		} catch (Exception e) {
  			throw new RuntimeException("生成Model和Mapper失败", e);
  		}
  
  		if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
  			throw new RuntimeException("生成Model和Mapper失败：" + warnings);
  		}
  		if (StringUtils.isEmpty(modelName))
  			modelName = tableNameConvertUpperCamel(tableName);
  		System.out.println(modelName + ".java 生成成功");
  		System.out.println(modelName + "Mapper.java 生成成功");
  		System.out.println(modelName + "Mapper.xml 生成成功");
  	}
  
  	public static void genService(String moduleName, String tableName, String modelName) {
  		try {
  			freemarker.template.Configuration cfg = getConfiguration();
  
  			Map<String, Object> data = new HashMap<>();
  			data.put("date", DATE);
  			data.put("author", AUTHOR);
  			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
  					: modelName;
  			data.put("modelNameUpperCamel", modelNameUpperCamel);
  			data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
  			data.put("basePackage", BASE_PACKAGE + "." + moduleName);
  			data.put("corePackage", BASE_PACKAGE);
  
  			String PACKAGE_PATH_SERVICE = packageConvertPath(BASE_PACKAGE + "." + moduleName + ".service");
  
  			File file = new File(
  					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE + "I" + modelNameUpperCamel + "Service.java");
  			if (!file.getParentFile().exists()) {
  				file.getParentFile().mkdirs();
  			}
  			cfg.getTemplate("service.ftl").process(data, new FileWriter(file));
  			System.out.println(modelNameUpperCamel + "Service.java 生成成功");
  
  			String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(
  					packageConvertPath(BASE_PACKAGE + "." + moduleName + ".service.impl"));
  
  			File file1 = new File(
  					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE_IMPL + modelNameUpperCamel + "ServiceImpl.java");
  			if (!file1.getParentFile().exists()) {
  				file1.getParentFile().mkdirs();
  			}
  			cfg.getTemplate("service-impl.ftl").process(data, new FileWriter(file1));
  			System.out.println(modelNameUpperCamel + "ServiceImpl.java 生成成功");
  		} catch (Exception e) {
  			throw new RuntimeException("生成Service失败", e);
  		}
  	}
  
  	public static void genController(String moduleName, String tableName, String modelName) {
  		try {
  			freemarker.template.Configuration cfg = getConfiguration();
  
  			Map<String, Object> data = new HashMap<>();
  			data.put("date", DATE);
  			data.put("author", AUTHOR);
  			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
  					: modelName;
  			data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
  			data.put("modelNameUpperCamel", modelNameUpperCamel);
  			data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
  			data.put("basePackage", BASE_PACKAGE + "." + moduleName);
  			data.put("corePackage", BASE_PACKAGE);
  
  			String PACKAGE_PATH_CONTROLLER = packageConvertPath(BASE_PACKAGE + "." + moduleName + ".controller");
  			File file = new File(
  					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_CONTROLLER + modelNameUpperCamel + "Controller.java");
  			if (!file.getParentFile().exists()) {
  				file.getParentFile().mkdirs();
  			}
  			// cfg.getTemplate("controller-restful.ftl").process(data, new
  			// FileWriter(file));
  			cfg.getTemplate("controller.ftl").process(data, new FileWriter(file));
  
  			System.out.println(modelNameUpperCamel + "Controller.java 生成成功");
  		} catch (Exception e) {
  			throw new RuntimeException("生成Controller失败", e);
  		}
  
  	}
  
  	private static freemarker.template.Configuration getConfiguration() throws IOException {
  		freemarker.template.Configuration cfg = new freemarker.template.Configuration(
  				freemarker.template.Configuration.VERSION_2_3_23);
  		cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH));
  		cfg.setDefaultEncoding("UTF-8");
  		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
  		return cfg;
  	}
  
  	private static String tableNameConvertUpperCamel(String tableName) {
  		return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase());
  
  	}
  
  	private static String tableNameConvertMappingPath(String tableName) {
  		tableName = tableName.toLowerCase();// 兼容使用大写的表名
  		return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);
  	}
  
  	private static String modelNameConvertMappingPath(String modelName) {
  		String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
  		return tableNameConvertMappingPath(tableName);
  	}
  
  	private static String packageConvertPath(String packageName) {
  		return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
  	}
  
  }
  