GBase 8s
其他
文章
GBASE 8s mybatis-plus代码生成获取表注释和字段注释
发表于2025-08-01 12:30:47241次浏览3个评论
mybatis-plus代码生成器相关配置,具体说明可以参见mybatis-plus文档,在dataSourceConfig:
.dataSourceConfig(builder -> builder
.driverClassName("com.gbasedbt.jdbc.Driver")
.databaseQueryClass(SQLQuery.class)
.dbQuery(new Gbase8sQuery())
.typeConvert(new Gbase8sTypeConvert())
)主要核心读取注释在Gbase8sQuery文件。类型转换在Gbase8sTypeConvert文件内。
以下为相关文件代码:
文件:Gbase8sQuery
import com.baomidou.mybatisplus.generator.config.querys.AbstractDbQuery;
public class Gbase8sQuery extends AbstractDbQuery {
@Override
public String tablesSql() {
return "select c.comments,t.* from systables t left join SYSCOMMS c on c.tabid = t.tabid where t.tabid > 99";
}
@Override
public String tableFieldsSql() {
return "SELECT " +
" a.tabname, " +
" b.colname, " +
" b.coltype, " +
" CASE b.colname " +
" WHEN 'id' THEN 'PRI' " +
" END AS key, " +
" b.coltypename, " +
" c.comments, " +
" b.colno " +
"FROM " +
" systables a " +
"LEFT JOIN syscolumnsext b " +
" ON a.tabid = b.tabid " +
"LEFT JOIN syscolcomments c " +
" ON c.tabname = a.tabname AND c.colname = b.colname " +
"WHERE " +
" a.tabid > 99 " +
" AND a.tabtype = 'T' and a.tabname = '%s' " +
"ORDER BY " +
" a.tabname, b.colno;";
}
@Override
public String tableName() {
return "tabname";
}
@Override
public String tableComment() {
return "comments";
}
@Override
public String fieldName() {
return "colname";
}
@Override
public String fieldType() {
return "coltypename";
}
@Override
public String fieldComment() {
return "comments";
}
@Override
public String fieldKey() {
return "key";
}
}文件:Gbase8sTypeConvert(类型对应可能不全,常用的都包含了,其他可自行扩展)
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.ITypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import static com.baomidou.mybatisplus.generator.config.rules.DbColumnType.*;
import static com.dsicsoft.core.generate.Gbase8sTypeConverts.contains;
import static com.dsicsoft.core.generate.Gbase8sTypeConverts.containsAny;
/**
* MYSQL 数据库字段类型转换
* bit类型数据转换 bit(1) -> Boolean类型 bit(2->64) -> Byte类型
* <p>
* 查看使用的类型方便添加转换器
* SELECT b.coltypename, COUNT(*) AS column_count FROM systables a LEFT JOIN syscolumnsext b ON a.tabid = b.tabid LEFT JOIN syscolcomments c ON c.tabname = a.tabname AND c.colname = b.colname WHERE a.tabid > 99 AND a.tabtype = 'T' GROUP BY b.coltypename ORDER BY b.coltypename;
*
* @author hubin, hanchunlin, xiaoliang
* @since 2017-01-20
*/
public class Gbase8sTypeConvert implements ITypeConvert {
public static final Gbase8sTypeConvert INSTANCE = new Gbase8sTypeConvert();
/**
* {@inheritDoc}
*/
@Override
public IColumnType processTypeConvert(GlobalConfig config, String fieldType) {
return Gbase8sTypeConverts.use(fieldType)
.test(contains("serial").then(LONG))
.test(containsAny("char", "varchar", "text", "json", "enum").then(STRING))
.test(contains("bigint").then(LONG))
.test(containsAny("tinyint(1)", "bit(1)").then(BOOLEAN))
.test(contains("bit").then(BYTE))
.test(containsAny("int", "integer").then(INTEGER))
.test(contains("decimal").then(BIG_DECIMAL))
.test(contains("clob").then(STRING))
.test(contains("blob").then(STRING))
.test(contains("binary").then(BYTE_ARRAY))
.test(contains("float").then(FLOAT))
.test(contains("double").then(DOUBLE))
.test(containsAny("date", "time", "year").then(t -> toDateType(config, t)))
.or(STRING);
}
/**
* 转换为日期类型
*
* @param config 配置信息
* @param type 类型
* @return 返回对应的列类型
*/
public static IColumnType toDateType(GlobalConfig config, String type) {
String dateType = type.replaceAll("\\(\\d+\\)", "");
switch (config.getDateType()) {
case ONLY_DATE:
return DbColumnType.DATE;
case SQL_PACK:
switch (dateType) {
case "date":
case "year":
return DbColumnType.DATE_SQL;
case "time":
return DbColumnType.TIME;
default:
return DbColumnType.TIMESTAMP;
}
case TIME_PACK:
switch (dateType) {
case "date":
return DbColumnType.LOCAL_DATE;
case "time":
return DbColumnType.LOCAL_TIME;
case "year":
return DbColumnType.YEAR;
default:
return DbColumnType.LOCAL_DATE_TIME;
}
}
return STRING;
}
}文件:Gbase8sTypeConverts
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.config.ITypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.*;
import com.baomidou.mybatisplus.generator.config.converts.select.BranchBuilder;
import com.baomidou.mybatisplus.generator.config.converts.select.Selector;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
/**
* 该注册器负责注册并查询类型注册器
*
* @author nieqiuqiu, hanchunlin
* @since 3.3.1
*/
public class Gbase8sTypeConverts {
/**
* 查询数据库类型对应的类型转换器
*
* @param dbType 数据库类型
* @return 返回转换器
*/
public static ITypeConvert getTypeConvert(DbType dbType) {
switch (dbType) {
case ORACLE:
return OracleTypeConvert.INSTANCE;
case DB2:
return DB2TypeConvert.INSTANCE;
case DM:
case GAUSS:
return DmTypeConvert.INSTANCE;
case KINGBASE_ES:
return KingbaseESTypeConvert.INSTANCE;
case OSCAR:
return OscarTypeConvert.INSTANCE;
case MYSQL:
case MARIADB:
return MySqlTypeConvert.INSTANCE;
case POSTGRE_SQL:
return PostgreSqlTypeConvert.INSTANCE;
case SQLITE:
return SqliteTypeConvert.INSTANCE;
case SQL_SERVER:
return SqlServerTypeConvert.INSTANCE;
case FIREBIRD:
return FirebirdTypeConvert.INSTANCE;
case CLICK_HOUSE:
return ClickHouseTypeConvert.INSTANCE;
}
return null;
}
/**
* 使用指定参数构建一个选择器
*
* @param param 参数
* @return 返回选择器
*/
static Selector<String, IColumnType> use(String param) {
return new Selector<>(param.toLowerCase());
}
/**
* 这个分支构建器用于构建用于支持 {@link String#contains(CharSequence)} 的分支
*
* @param value 分支的值
* @return 返回分支构建器
* @see #containsAny(CharSequence...)
*/
static BranchBuilder<String, IColumnType> contains(CharSequence value) {
return BranchBuilder.of(s -> s.contains(value));
}
/**
* @see #contains(CharSequence)
*/
static BranchBuilder<String, IColumnType> containsAny(CharSequence... values) {
return BranchBuilder.of(s -> {
for (CharSequence value : values) {
if (s.contains(value)) {
return true;
}
}
return false;
});
}
}文件:Gbase8sDatabaseQuery
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.builder.Entity;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.jdbc.DatabaseMetaDataWrapper;
import com.baomidou.mybatisplus.generator.query.AbstractDatabaseQuery;
import com.baomidou.mybatisplus.generator.type.ITypeConvertHandler;
import com.baomidou.mybatisplus.generator.type.TypeRegistry;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 元数据查询数据库信息.
*
* @author nieqiurong 2022/5/11.
* @see ITypeConvertHandler 类型转换器(如果默认逻辑不能满足,可实现此接口重写类型转换)
* <p>
* 测试通过的数据库:H2、Mysql-5.7.37、Mysql-8.0.25、PostgreSQL-11.15、PostgreSQL-14.1、Oracle-11.2.0.1.0、DM8
* </p>
* <p>
* FAQ:
* 1.Mysql无法读取表注释: 链接增加属性 remarks=true&useInformationSchema=true 或者通过{@link DataSourceConfig.Builder#addConnectionProperty(String, String)}设置
* 2.Oracle无法读取注释: 增加属性remarks=true,也有些驱动版本说是增加remarksReporting=true {@link DataSourceConfig.Builder#addConnectionProperty(String, String)}
* </p>
* @since 3.5.3
*/
public class Gbase8sDatabaseQuery extends AbstractDatabaseQuery {
private final TypeRegistry typeRegistry;
protected final DatabaseMetaDataWrapper databaseMetaDataWrapper;
public Gbase8sDatabaseQuery(@NotNull ConfigBuilder configBuilder) {
super(configBuilder);
typeRegistry = new TypeRegistry(configBuilder.getGlobalConfig());
this.databaseMetaDataWrapper = new DatabaseMetaDataWrapper(dataSourceConfig.getConn(), dataSourceConfig.getSchemaName());
}
@Override
public @NotNull List<TableInfo> queryTables() {
try {
boolean isInclude = !strategyConfig.getInclude().isEmpty();
boolean isExclude = !strategyConfig.getExclude().isEmpty();
//所有的表信息
List<TableInfo> tableList = new ArrayList<>();
List<DatabaseMetaDataWrapper.Table> tables = this.getTables();
//需要反向生成或排除的表信息
List<TableInfo> includeTableList = new ArrayList<>();
List<TableInfo> excludeTableList = new ArrayList<>();
tables.forEach(table -> {
String tableName = table.getName();
if (StringUtils.isNotBlank(tableName)) {
TableInfo tableInfo = new TableInfo(this.configBuilder, tableName);
tableInfo.setComment(table.getRemarks());
if (isInclude && strategyConfig.matchIncludeTable(tableName)) {
includeTableList.add(tableInfo);
} else if (isExclude && strategyConfig.matchExcludeTable(tableName)) {
excludeTableList.add(tableInfo);
}
tableList.add(tableInfo);
}
});
filter(tableList, includeTableList, excludeTableList);
// 性能优化,只处理需执行表字段 https://github.com/baomidou/mybatis-plus/issues/219
tableList.forEach(this::convertTableFields);
return tableList;
} finally {
// 数据库操作完成,释放连接对象
databaseMetaDataWrapper.closeConnection();
}
}
protected List<DatabaseMetaDataWrapper.Table> getTables() {
// 是否跳过视图
boolean skipView = strategyConfig.isSkipView();
// 获取表过滤
String tableNamePattern = null;
if (strategyConfig.getLikeTable() != null) {
tableNamePattern = strategyConfig.getLikeTable().getValue();
}
return databaseMetaDataWrapper.getTables(tableNamePattern, skipView ? new String[]{"TABLE"} : new String[]{"TABLE", "VIEW"});
}
protected void convertTableFields(@NotNull TableInfo tableInfo) {
String tableName = tableInfo.getName();
Map<String, DatabaseMetaDataWrapper.Column> columnsInfoMap = getColumnsInfo(tableName);
Entity entity = strategyConfig.entity();
columnsInfoMap.forEach((k, columnInfo) -> {
String columnName = columnInfo.getName();
TableField field = new TableField(this.configBuilder, columnName);
// 处理ID
if (columnInfo.isPrimaryKey()) {
field.primaryKey(columnInfo.isAutoIncrement());
tableInfo.setHavePrimaryKey(true);
if (field.isKeyIdentityFlag() && entity.getIdType() != null) {
LOGGER.warn("当前表[{}]的主键为自增主键,会导致全局主键的ID类型设置失效!", tableName);
}
}
field.setColumnName(columnName).setComment(columnInfo.getRemarks());
String propertyName = entity.getNameConvert().propertyNameConvert(field);
// 设置字段的元数据信息
TableField.MetaInfo metaInfo = new TableField.MetaInfo(columnInfo, tableInfo);
IColumnType columnType;
ITypeConvertHandler typeConvertHandler = dataSourceConfig.getTypeConvertHandler();
if (typeConvertHandler != null) {
columnType = typeConvertHandler.convert(globalConfig, typeRegistry, metaInfo);
} else {
columnType = typeRegistry.getColumnType(metaInfo);
}
field.setPropertyName(propertyName, columnType);
field.setMetaInfo(metaInfo);
tableInfo.addField(field);
});
tableInfo.setIndexList(getIndex(tableName));
tableInfo.processTable();
}
protected Map<String, DatabaseMetaDataWrapper.Column> getColumnsInfo(String tableName) {
return databaseMetaDataWrapper.getColumnsInfo(tableName, true);
}
protected List<DatabaseMetaDataWrapper.Index> getIndex(String tableName) {
return databaseMetaDataWrapper.getIndex(tableName);
}
}评论
登录后才可以发表评论
热门帖子
- 12025-12-01浏览数:182759
- 22023-05-09浏览数:25044
- 42023-09-25浏览数:18519
- 52020-05-11浏览数:17526