一、問題
1、SQL腳本
DROP TABLE IF EXISTS `pms_brand`;
CREATE TABLE pms_brand
(
create_user bigint comment '創建人',
create_time datetime comment '創建時間',
update_user bigint comment '上次修改人',
update_time datetime comment '上次修改時間',
is_deleted int comment '是否已刪除',
sort int comment '排序',
tenant_id varchar(12) comment '租戶id',
create_dept bigint comment '創建部門',
id bigint not null auto_increment comment '編號',
name varchar(64) comment '名稱',
letter varchar(64) comment '每個漢字的首字母',
product_count int comment '關聯產品數量',
primary key (id)
);
2、生成后的代碼
3、這個我自己用MyBatis-Plus
的代碼生成器生成的
4、出錯的地方在於數據庫問題
原來是數據庫備注亂碼了,估計是本地以前執行SQL語句的時候忘選擇編碼了
二、需要注意的地方
1、腳本編碼問題
MySQL數據庫執行腳本的時候,要注意腳本編碼的問題,不然很容易就亂碼了
2、數據庫版本問題
MySQL數據庫版本 5.x和6.x的版本相差比較大,jdbc的配置需要注意,注意就是下面的兩個參數
有兩個參數需要注意:nullCatalogMeansCurrent
、allowPublicKeyRetrieval
原文:
https://blog.csdn.net/jiaoshaoping/article/details/80748065
https://blog.csdn.net/Yuriey/article/details/80423504
可參考默認數據庫鏈接的配置
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/blade?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&serverTimezone=GMT%2B8
#spring.datasource.username=root
#spring.datasource.password=root
#author=Blade
3、在線代碼生成器的問題
在使用前需要配置一下數據源,不然就會使用本地的blade數據庫,在數據源管理就可以配置。
4、代碼生成器本地調試調試問題
需要特別注意一下數據庫鏈接地址
如是在blade-core-develop
這個項目運行,數據庫的配置在這里'resources/templates/code.properties'
如果是在org.springblade
這個項目運行,就需要在線配置一下數據源的地址
這里也有一個數據庫配置文件,我把源碼改過一下,就沒有用到這里的這個文件
三、代碼的一些調整
1、修改的類
2、BladeCodeGenerator
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄騫 (smallchill@163.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.develop.support;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.OracleTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.develop.constant.DevelopConstant;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* 代碼生成器配置類
*
* @author Chill
*/
@Slf4j
public class BladeCodeGenerator {
// configGlobalConfig 方法使用-----------------------
/**
* 代碼所在服務名
*/
private String serviceName = "blade-service";
/**
* 租戶字段
*/
private String tenantColumn = "tenant_id";
/**
* 是否包含包裝器
*/
private Boolean hasWrapper = Boolean.FALSE;
/**
* 輸出路徑
*/
private String outputDir;
/**
* 是否啟用swagger
*/
private Boolean isSwagger2 = Boolean.TRUE;
/**
* 作者
*/
private String author;
// configDataSource 方法使用-----------------------
/**
* 數據庫驅動名
*/
private String driverName;
/**
* 數據庫鏈接地址
*/
private String url;
/**
* 數據庫用戶名
*/
private String username;
/**
* 數據庫密碼
*/
private String password;
// configStrategyConfig 方法使用-----------------------
/**
* 需要去掉的表前綴
*/
private String[] tablePrefix = {"blade_"};
/**
* 需要生成的表名(兩者只能取其一)
*/
private String[] includeTables = {};
/**
* 需要排除的表名(兩者只能取其一)
*/
private String[] excludeTables = {};
/**
* 是否包含基礎業務字段
*/
private Boolean hasSuperEntity = Boolean.FALSE;
/**
* 基礎業務字段
*/
private String[] superEntityColumns = {"create_time" , "create_user" , "create_dept" , "update_time" , "update_user" , "status" , "is_deleted"};
// configPackageConfig 方法使用-----------------------
/**
* 代碼生成的包名
*/
private String packageName = "org.springblade.test";
// configPackageConfig 方法使用-----------------------
/**
* 代碼模塊名稱
*/
private String codeName;
/**
* 代碼所在系統
*/
private String systemName = DevelopConstant.SWORD_NAME;
/**
* 前端代碼生成的地址
*/
private String packageWebDir;
// getOutputDir 方法使用-----------------------
/**
* 后端代碼生成的地址
*/
private String packageDir;
/**
* CodeGenerator這個類使用
* @param codeName 代碼模塊名稱
* @param serviceName 代碼所在服務名
* @param systemName 代碼所在系統
* @param packageName 代碼生成的包名
* @param packageWebDir 前端代碼生成的地址
* @param tablePrefix 需要去掉的表前綴
* @param includeTables 需要生成的表名(兩者只能取其一)
* @param excludeTables 需要排除的表名(兩者只能取其一)
* @param hasSuperEntity 是否包含基礎業務字段
* @param superEntityColumns 基礎業務字段
*/
public BladeCodeGenerator(String codeName,String serviceName,String systemName,String packageName
,String packageWebDir,String[] tablePrefix,String[] includeTables,String[] excludeTables
,boolean hasSuperEntity,String[] superEntityColumns) {
this.codeName=codeName;
this.serviceName=serviceName;
this.systemName=systemName;
this.packageName=packageName;
this.packageWebDir=packageWebDir;
this.tablePrefix=tablePrefix;
this.includeTables=includeTables;
this.excludeTables=excludeTables;
this.hasSuperEntity=hasSuperEntity;
this.superEntityColumns=superEntityColumns;
// 從配置文件獲取數據庫鏈接
Properties props = getProperties();
this.driverName = props.getProperty("spring.datasource.driver-class-name");
this.url = props.getProperty("spring.datasource.url");
this.username = props.getProperty("spring.datasource.username");
this.password = props.getProperty("spring.datasource.password");
this.author = props.getProperty("author");
}
/**
* CodeController類使用
* @param driverName 數據庫驅動名
* @param url 數據庫鏈接地址
* @param username 數據庫用戶名
* @param password 數據庫密碼
* @param systemName 代碼所在系統
* @param serviceName 代碼所在服務名
* @param packageName 代碼生成的包名
* @param packageDir 后端代碼生成的地址
* @param packageWebDir 前端代碼生成的地址
* @param tablePrefix 需要去掉的表前綴
* @param includeTables 需要生成的表名(兩者只能取其一)
* @param hasSuperEntity 需要排除的表名(兩者只能取其一)
* @param hasWrapper 是否包含基礎業務字段
*/
public BladeCodeGenerator(String driverName,String url,String username,String password
,String systemName,String serviceName,String packageName,String packageDir,String packageWebDir
,String[] tablePrefix,String[] includeTables,boolean hasSuperEntity,boolean hasWrapper){
this.driverName=driverName;
this.url=url;
this.username=username;
this.password=password;
this.systemName=systemName;
this.serviceName=serviceName;
this.packageName=packageName;
this.packageDir=packageDir;
this.packageWebDir=packageWebDir;
this.tablePrefix=tablePrefix;
this.includeTables=includeTables;
this.hasSuperEntity=hasSuperEntity;
this.hasWrapper=hasWrapper;
//其它值的初始化
this.outputDir = getOutputDir();
}
/**
* 自定義生成文件配置
*
* @return
*/
private InjectionConfig configCustomerConfig() {
String servicePackage = serviceName.split("-").length > 1 ? serviceName.split("-")[1] : serviceName;
// 自定義配置
Map<String, Object> map = new HashMap<>(16);
InjectionConfig config = new InjectionConfig() {
@Override
public void initMap() {
map.put("codeName" , codeName);
map.put("serviceName" , serviceName);
map.put("servicePackage" , servicePackage);
map.put("servicePackageLowerCase" , servicePackage.toLowerCase());
map.put("tenantColumn" , tenantColumn);
map.put("hasWrapper" , hasWrapper);
this.setMap(map);
}
};
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/sql/menu.sql.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
map.put("entityKey" , (tableInfo.getEntityName().toLowerCase()));
map.put("menuId" , IdWorker.getId());
map.put("addMenuId" , IdWorker.getId());
map.put("editMenuId" , IdWorker.getId());
map.put("removeMenuId" , IdWorker.getId());
map.put("viewMenuId" , IdWorker.getId());
return getOutputDir() + "/" + "/sql/" + tableInfo.getEntityName().toLowerCase() + ".menu.mysql";
}
});
focList.add(new FileOutConfig("/templates/entityVO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputDir() + "/" + packageName.replace("." , "/") + "/" + "vo" + "/" + tableInfo.getEntityName() + "VO" + StringPool.DOT_JAVA;
}
});
focList.add(new FileOutConfig("/templates/entityDTO.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputDir() + "/" + packageName.replace("." , "/") + "/" + "dto" + "/" + tableInfo.getEntityName() + "DTO" + StringPool.DOT_JAVA;
}
});
if (hasWrapper) {
focList.add(new FileOutConfig("/templates/wrapper.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputDir() + "/" + packageName.replace("." , "/") + "/" + "wrapper" + "/" + tableInfo.getEntityName() + "Wrapper" + StringPool.DOT_JAVA;
}
});
}
if (Func.isNotBlank(packageWebDir)) {
if (Func.equals(systemName, DevelopConstant.SWORD_NAME)) {
focList.add(new FileOutConfig("/templates/sword/action.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/actions" + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
}
});
focList.add(new FileOutConfig("/templates/sword/model.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/models" + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
}
});
focList.add(new FileOutConfig("/templates/sword/service.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/services" + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
}
});
focList.add(new FileOutConfig("/templates/sword/list.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + ".js";
}
});
focList.add(new FileOutConfig("/templates/sword/add.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + "Add.js";
}
});
focList.add(new FileOutConfig("/templates/sword/edit.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + "Edit.js";
}
});
focList.add(new FileOutConfig("/templates/sword/view.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + "View.js";
}
});
} else if (Func.equals(systemName, DevelopConstant.SABER_NAME)) {
focList.add(new FileOutConfig("/templates/saber/api.js.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/api" + "/" + servicePackage.toLowerCase() + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
}
});
focList.add(new FileOutConfig("/templates/saber/crud.vue.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return getOutputWebDir() + "/views" + "/" + servicePackage.toLowerCase() + "/" + tableInfo.getEntityName().toLowerCase() + ".vue";
}
});
}
}
config.setFileOutConfigList(focList);
return config;
}
/**
* 全局配置
*
* @return
*/
private GlobalConfig configGlobalConfig() {
GlobalConfig config = new GlobalConfig();
config.setOutputDir(this.outputDir);
config.setAuthor(this.author);
config.setFileOverride(true);
config.setOpen(false);
config.setActiveRecord(false);
config.setEnableCache(false);
config.setBaseResultMap(true);
config.setBaseColumnList(true);
config.setMapperName("%sMapper");
config.setXmlName("%sMapper");
config.setServiceName("I%sService");
config.setServiceImplName("%sServiceImpl");
config.setControllerName("%sController");
config.setSwagger2(isSwagger2);
return config;
}
/**
* 數據源配置
*
* @return
*/
private DataSourceConfig configDataSource() {
DataSourceConfig config = new DataSourceConfig();
if (StringUtil.containsAny(this.driverName, DbType.MYSQL.getDb())) {
config.setDbType(DbType.MYSQL);
config.setTypeConvert(new MySqlTypeConvert());
} else if (StringUtil.containsAny(this.driverName, DbType.POSTGRE_SQL.getDb())) {
config.setDbType(DbType.POSTGRE_SQL);
config.setTypeConvert(new PostgreSqlTypeConvert());
} else {
config.setDbType(DbType.ORACLE);
config.setTypeConvert(new OracleTypeConvert());
}
config.setDriverName(this.driverName);
config.setUrl(this.url);
config.setUsername(this.username);
config.setPassword(this.password);
return config;
}
/**
* 策略配置
*
* @return
*/
private StrategyConfig configStrategyConfig() {
// 策略配置
StrategyConfig config = new StrategyConfig();
// config.setCapitalMode(true);// 全局大寫命名
// config.setDbColumnUnderline(true);//全局下划線命名
config.setNaming(NamingStrategy.underline_to_camel);
config.setColumnNaming(NamingStrategy.underline_to_camel);
config.setTablePrefix(tablePrefix);
if (includeTables.length > 0) {
config.setInclude(includeTables);
}
if (excludeTables.length > 0) {
config.setExclude(excludeTables);
}
if (hasSuperEntity) {
config.setSuperEntityClass("org.springblade.core.mp.base.BaseEntity");
config.setSuperEntityColumns(superEntityColumns);
config.setSuperServiceClass("org.springblade.core.mp.base.BaseService");
config.setSuperServiceImplClass("org.springblade.core.mp.base.BaseServiceImpl");
} else {
config.setSuperServiceClass("com.baomidou.mybatisplus.extension.service.IService");
config.setSuperServiceImplClass("com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");
}
// 自定義 controller 父類
config.setSuperControllerClass("org.springblade.core.boot.ctrl.BladeController");
config.setEntityBuilderModel(false);
config.setEntityLombokModel(true);
config.setControllerMappingHyphenStyle(true);
return config;
}
/**
* 包名策略配置
*
* @return
*/
private PackageConfig configPackageConfig() {
// 包配置
PackageConfig config = new PackageConfig();
// 控制台掃描
config.setModuleName(null);
config.setParent(packageName);
config.setController("controller");
config.setEntity("entity");
config.setXml("mapper");
return config;
}
/**
* 獲取配置文件
*
* @return 配置Props
*/
private Properties getProperties() {
// 讀取配置文件
Resource resource = new ClassPathResource("/templates/code.properties");
Properties props = new Properties();
try {
props = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
/**
* 生成到項目中
*
* @return outputDir
*/
public String getOutputDir() {
return (Func.isBlank(packageDir) ? System.getProperty("user.dir") + "/blade-ops/blade-develop" : packageDir) + "/src/main/java";
}
/**
* 生成到Web項目中
*
* @return outputDir
*/
public String getOutputWebDir() {
return (Func.isBlank(packageWebDir) ? System.getProperty("user.dir") : packageWebDir) + "/src";
}
/**
* 頁面生成的文件名
*/
private String getGeneratorViewPath(String viewOutputDir, TableInfo tableInfo, String suffixPath) {
String name = StringUtils.firstToLowerCase(tableInfo.getEntityName());
String path = viewOutputDir + "/" + name + "/" + name + suffixPath;
File viewDir = new File(path).getParentFile();
if (!viewDir.exists()) {
viewDir.mkdirs();
}
return path;
}
public void run() {
AutoGenerator mpg = new AutoGenerator();
mpg.setGlobalConfig(configGlobalConfig());
mpg.setDataSource(configDataSource());
mpg.setStrategy(configStrategyConfig());
mpg.setPackageInfo(configPackageConfig());
mpg.setCfg(configCustomerConfig());
mpg.execute();
}
}
3、CodeGenerator
public static void run() {
BladeCodeGenerator generator = new BladeCodeGenerator(
CODE_NAME,SERVICE_NAME,SYSTEM_NAME,PACKAGE_NAME
,PACKAGE_WEB_DIR,TABLE_PREFIX,INCLUDE_TABLES
,EXCLUDE_TABLES,HAS_SUPER_ENTITY,SUPER_ENTITY_COLUMNS
);
generator.run();
}
4、CodeController
/**
* 代碼生成
*/
@PostMapping("/gen-code")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "代碼生成" , notes = "傳入ids")
public R genCode(@ApiParam(value = "主鍵集合" , required = true) @RequestParam String ids, @RequestParam(defaultValue = "sword") String system) {
Collection<Code> codes = codeService.listByIds(Func.toLongList(ids));
codes.forEach(code -> {
String driverName = "";
String url = "";
String username = "";
String password = "";
String systemName = "";
String serviceName = "";
String packageName = "";
String packageDir = "";
String packageWebDir = "";
String[] tablePrefix = null;
String[] includeTables = null;
boolean hasSuperEntity = false;
boolean hasWrapper = false;
// 設置數據源
Datasource datasource = datasourceService.getById(code.getDatasourceId());
driverName = datasource.getDriverClass();
url = datasource.getUrl();
username = datasource.getUsername();
password = datasource.getPassword();
// 設置基礎配置
systemName = system;
serviceName = code.getServiceName();
packageName = code.getPackageName();
packageDir = code.getApiPath();
packageWebDir = code.getWebPath();
tablePrefix = Func.toStrArray(code.getTablePrefix());
includeTables = Func.toStrArray(code.getTableName());
hasSuperEntity = code.getBaseMode() == 2;
hasWrapper = code.getWrapMode() == 2;
//構造函數初始化
BladeCodeGenerator generator = new BladeCodeGenerator(driverName, url, username, password
, systemName, serviceName, packageName, packageDir, packageWebDir
, tablePrefix, includeTables, hasSuperEntity, hasWrapper
);
generator.run();
});
return R.success("代碼生成成功");
}