This commit is contained in:
Looly
2025-10-29 10:24:23 +08:00
parent 182103120c
commit 4df295ed3f
5 changed files with 32 additions and 174 deletions

View File

@@ -2,6 +2,7 @@ package cn.hutool.v7.db.dialect;
import cn.hutool.v7.core.collection.CollUtil;
import cn.hutool.v7.core.lang.Assert;
import cn.hutool.v7.core.text.StrJoiner;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.db.meta.*;
import cn.hutool.v7.db.sql.QuoteWrapper;
@@ -27,14 +28,9 @@ public class DDLBuilder {
// 列定义
Collection<Column> columns = tableMeta.getColumns();
Assert.notEmpty(columns, "Table must have at least one column");
boolean firstColumn = true;
for (Column column : columns) {
if (!firstColumn) {
sqlBuilder.append(",\n");
}
sqlBuilder.append(" ").append(buildColumnDefinition(column));
firstColumn = false;
}
final String columnsDefinition = StrJoiner.of(",\n")
.append(columns, column -> " " + buildColumnDefinition(column)).toString();
sqlBuilder.append(columnsDefinition);
// 主键约束定义
buildPrimaryKey(sqlBuilder, tableMeta.getPkNames());

View File

@@ -229,6 +229,10 @@ public class TableMeta implements Serializable, Cloneable {
*/
public TableMeta addColumn(final Column column) {
this.columns.put(column.getName(), column);
// 主键
if(column.isPk()){
this.pkNames.add(column.getName());
}
return this;
}

View File

@@ -1,154 +0,0 @@
package cn.hutool.v7.db.meta.ddl;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.db.meta.*;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* 根据Table对象生成MySQL的CREATE TABLE语句
*
* @author Looly
*/
public class MysqlTableGenerator {
/**
* 根据Table对象生成MySQL的CREATE TABLE语句
*
* @param tableMeta Table对象
* @return MySQL的CREATE TABLE语句
*/
public static String generateCreateTableSql(TableMeta tableMeta) {
StringBuilder sqlBuilder = new StringBuilder();
// 表名
final String tableName = tableMeta.getTableName();
if (StrUtil.isBlank(tableName)) {
throw new IllegalArgumentException("Table name cannot be blank!");
}
sqlBuilder.append("CREATE TABLE `").append(tableName).append("` (\n");
// 列定义
Collection<Column> columns = tableMeta.getColumns();
if (columns.isEmpty()) {
throw new IllegalArgumentException("Table must have at least one column");
}
boolean firstColumn = true;
for (Column column : columns) {
if (!firstColumn) {
sqlBuilder.append(",\n");
}
sqlBuilder.append(" ").append(generateColumnDefinition(column));
firstColumn = false;
}
// 主键定义
Set<String> pkNames = tableMeta.getPkNames();
if (!pkNames.isEmpty()) {
sqlBuilder.append(",\n PRIMARY KEY (");
boolean firstPk = true;
for (String pkName : pkNames) {
if (!firstPk) {
sqlBuilder.append(", ");
}
sqlBuilder.append("`").append(pkName).append("`");
firstPk = false;
}
sqlBuilder.append(")");
}
// 索引定义 (如果有)
List<IndexInfo> indexInfoList = tableMeta.getIndexInfoList();
if (indexInfoList != null && !indexInfoList.isEmpty()) {
for (IndexInfo indexInfo : indexInfoList) {
sqlBuilder.append(",\n ");
if (!indexInfo.isNonUnique()) {
sqlBuilder.append("UNIQUE ");
}
sqlBuilder.append("INDEX `").append(indexInfo.getIndexName()).append("` (");
// 遍历索引列信息列表
List<ColumnIndex> columnIndexInfoList = indexInfo.getColumnIndexInfoList();
if (columnIndexInfoList != null && !columnIndexInfoList.isEmpty()) {
boolean firstIndexColumn = true;
for (ColumnIndex columnIndex : columnIndexInfoList) {
if (!firstIndexColumn) {
sqlBuilder.append(", ");
}
sqlBuilder.append("`").append(columnIndex.getColumnName()).append("`");
// 可以添加排序信息,如果需要的话
String ascOrDesc = columnIndex.getAscOrDesc();
if ("D".equalsIgnoreCase(ascOrDesc)) {
sqlBuilder.append(" DESC");
} else if ("A".equalsIgnoreCase(ascOrDesc)) {
sqlBuilder.append(" ASC");
}
firstIndexColumn = false;
}
}
sqlBuilder.append(")");
}
}
sqlBuilder.append("\n)");
// 表注释
String remarks = tableMeta.getRemarks();
if (remarks != null && !remarks.isEmpty()) {
sqlBuilder.append(" COMMENT='").append(remarks.replace("'", "''")).append("'");
}
sqlBuilder.append(";");
return sqlBuilder.toString();
}
/**
* 根据Column对象生成列定义
* <p>
* 注意: 这里是一个简化的实现实际项目中需要根据Column类的具体属性
* 和数据库类型映射来完善
*
* @param column Column对象
* @return 列定义字符串
*/
private static String generateColumnDefinition(Column column) {
StringBuilder columnBuilder = new StringBuilder();
// 列名
columnBuilder.append("`").append(column.getName()).append("`");
// 数据类型 (这里假设Column有getTypeName方法)
// 实际应用中需要更复杂的类型映射
ColumnType type = column.getType();
if (type != null) {
columnBuilder.append(" ").append(type.getTypeName());
} else {
// 默认使用VARCHAR
columnBuilder.append(" VARCHAR(255)");
}
// 是否允许为空 (假设Column有isNullable方法)
if (!column.isNullable()) {
columnBuilder.append(" NOT NULL");
}
// 默认值 (假设Column有getDefaultValue方法)
String defaultValue = column.getColumnDef();
if (defaultValue != null) {
columnBuilder.append(" DEFAULT '").append(defaultValue.replace("'", "''")).append("'");
}
// 注释 (假设Column有getRemarks方法)
String remarks = column.getRemarks();
if (remarks != null && !remarks.isEmpty()) {
columnBuilder.append(" COMMENT '").append(remarks.replace("'", "''")).append("'");
}
return columnBuilder.toString();
}
}

View File

@@ -1,6 +0,0 @@
/**
* 数据库DDL元信息生成如建表语句等
*
* @author Looly
*/
package cn.hutool.v7.db.meta.ddl;

View File

@@ -1,4 +1,20 @@
package cn.hutool.v7.db.meta.ddl;
/*
* Copyright (c) 2025 Hutool Team and hutool.cn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 cn.hutool.v7.db.dialect;
import cn.hutool.v7.db.meta.*;
import org.junit.jupiter.api.Assertions;
@@ -7,14 +23,14 @@ import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Collections;
public class MysqlTableGeneratorTest {
public class DDLBuilderTest {
@Test
public void testGenerateCreateTableSql_WithIndexes() {
public void testGenerateCreateTableSqlWithIndexes() {
TableMeta tableMeta = new TableMeta("products");
// 列定义
Column idCol = new Column().setName("id").setType(new ColumnType(-5, "BIGINT", 20));
Column idCol = new Column().setName("id").setType(new ColumnType(-5, "BIGINT", 20)).setPk(true);
Column nameCol = new Column().setName("name").setType(new ColumnType(12, "VARCHAR", 100));
Column priceCol = new Column().setName("price").setType(new ColumnType(3, "DECIMAL", 10));
@@ -30,12 +46,14 @@ public class MysqlTableGeneratorTest {
tableMeta.addColumn(idCol).addColumn(nameCol).addColumn(priceCol);
tableMeta.setIndexInfoList(Arrays.asList(uniqueIndex, normalIndex));
String sql = MysqlTableGenerator.generateCreateTableSql(tableMeta);
final DDLBuilder ddlBuilder = new DDLBuilder();
String sql = ddlBuilder.buildCreateTableSql(tableMeta);
Assertions.assertEquals("""
CREATE TABLE `products` (
CREATE TABLE products (
`id` BIGINT NOT NULL,
`name` VARCHAR NOT NULL,
`price` DECIMAL NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX `idx_name` (`name` ASC),
INDEX `idx_price` (`price` DESC)
);""", sql);