根据Java对象生成建表语句,支持Oracle,MySQL

7 篇文章 0 订阅

根据Java对象生成建表语句,支持Oracle,MySQL

基础功能

  1. 根据全类名、类路径、创建建表语句

    功能实现

    1. 适配Model 字段 转换为 数据库中的字段类型
    2. 构建create table 语句

扩充功能

  1. 可自定义表名
  2. 可通过自定义在数据库中的字段长度
  3. 可通过某种方式定义主键 或 notnull 或默认什么。

之后希望可以反向生成model对象(还未完成)

实现代码

1、两个关键的枚举类

package com.model;

import lombok.Getter;

/**
 * @author yuanmengfan
 * @date 2022/7/8 23:48
 * @description
 */
@Getter
public enum DbType {
    MySQL,Oracle;
}
-----------------------
package com.db;

import cn.hutool.core.util.StrUtil;
import com.model.DbType;
import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author yuanmengfan
 * @date 2022/7/8 23:29
 * @description 枚举出想要对应的关系,从而使对应的Java类型匹配上对应的字段类型
 */

@Getter
public enum FieldToColumnType {
    // MySQL类型
    MYSQL_BYTE_COLUMN_TYPE("byte", "big", "1", DbType.MySQL),
    MYSQL_INT_COLUMN_TYPE("int", "int", "11", DbType.MySQL),
    MYSQL_SHORT_COLUMN_TYPE("short", "int", "6", DbType.MySQL),
    MYSQL_LONG_COLUMN_TYPE("long", "bigint", "20", DbType.MySQL),
    MYSQL_BOOLEAN_COLUMN_TYPE("boolean", "tinyint", "1", DbType.MySQL),
    MYSQL_FLOAT_COLUMN_TYPE("float", "float", "", DbType.MySQL),
    MYSQL_DOUBLE_COLUMN_TYPE("double", "double", "", DbType.MySQL),
    MYSQL_CHAR_COLUMN_TYPE("char", "VARCHAR", "50", DbType.MySQL),
    MYSQL_BYTE_PACKING_COLUMN_TYPE("com.lang.Byte", "big", "1", DbType.MySQL),
    MYSQL_INT_PACKING_COLUMN_TYPE("com.lang.Integer", "int", "11", DbType.MySQL),
    MYSQL_SHORT_PACKING_COLUMN_TYPE("com.lang.Short", "int", "6", DbType.MySQL),
    MYSQL_LONG_PACKING_COLUMN_TYPE("com.lang.Long", "bigint", "20", DbType.MySQL),
    MYSQL_BOOLEAN_PACKING_COLUMN_TYPE("com.lang.Boolean", "tinyint", "1", DbType.MySQL),
    MYSQL_FLOAT_PACKING_COLUMN_TYPE("com.lang.Float", "float", "", DbType.MySQL),
    MYSQL_DOUBLE_PACKING_COLUMN_TYPE("com.lang.Double", "double", "", DbType.MySQL),
    MYSQL_CHAR_PACKING_COLUMN_TYPE("com.lang.Character", "VARCHAR", "255", DbType.MySQL),
    MYSQL_BYTEARRAY_COLUMN_TYPE("byte[]", "blob", "", DbType.MySQL),
    MYSQL_DATE_COLUMN_TYPE("java.util.Date", "datetime", "", DbType.MySQL),
    MYSQL_SQL_DATE_COLUMN_TYPE("java.sql.Date", "data", "", DbType.MySQL),
    MYSQL_TIMESTAMP_COLUMN_TYPE("java.sql.TIMESTAMP", "timestamp", "", DbType.MySQL),
    DEFAULT_MYSQL_UNKNOWN_TYPE("String", "VARCHAR", "255", DbType.MySQL),

    // Oracle类型
    // Number类型是oralce的数值类型,存储的数值的精度可以达到38位。
    // Number是一种变长类型,长度为0-22字节。取值范围为:10^(-130) —— 10^126(不包括)。以十进制格式进行存储的,
    // 它便于存储,但是在计算上,系统会自动的将它转换成为二进制进行运算的。
    // Number(p,s):
    // p和s都是可选的。
    // p指精度(precision),即总位数。默认情况下精度为38。精度的取值范围为1~38。
    // s指小数位(scale),小数点右边的位数。小数点位数的合法值为-84~127。小数位的默认值由精度来决定。如果没有指定精度,小数位默认为最大的取值区间。
    // 如果指定了精度,没有指定小数位。小数位默认为0(即没有小数位)。
    // 精度和小数位不会影响数据如何存储,只会影响允许哪些数值及数值如何舍入。
    ORACLE_BYTE_COLUMN_TYPE("byte", "CHAR", "1", DbType.Oracle),
    ORACLE_INT_COLUMN_TYPE("int", "NUMBER", "11", DbType.Oracle),
    ORACLE_SHORT_COLUMN_TYPE("short", "NUMBER", "6", DbType.Oracle),
    ORACLE_LONG_COLUMN_TYPE("long", "NUMBER", "20", DbType.Oracle),
    ORACLE_BOOLEAN_COLUMN_TYPE("boolean", "CHAR", "1", DbType.Oracle),
    ORACLE_FLOAT_COLUMN_TYPE("float", "NUMBER", "13,2", DbType.Oracle),
    ORACLE_DOUBLE_COLUMN_TYPE("double", "NUMBER", "23,2", DbType.Oracle),
    ORACLE_CHAR_COLUMN_TYPE("char", "VARCHAR2", "255", DbType.Oracle),
    ORACLE_BYTE_PACKING_COLUMN_TYPE("com.lang.Byte", "CHAR", "1", DbType.Oracle),
    ORACLE_INT_PACKING_COLUMN_TYPE("com.lang.Integer", "NUMBER", "11", DbType.Oracle),
    ORACLE_SHORT_PACKING_COLUMN_TYPE("com.lang.Short", "NUMBER", "6", DbType.Oracle),
    ORACLE_LONG_PACKING_COLUMN_TYPE("com.lang.Long", "NUMBER", "20", DbType.Oracle),
    ORACLE_BOOLEAN_PACKING_COLUMN_TYPE("com.lang.Boolean", "CHAR", "1", DbType.Oracle),
    ORACLE_FLOAT_PACKING_COLUMN_TYPE("com.lang.Float", "NUMBER", "13.2", DbType.Oracle),
    ORACLE_DOUBLE_PACKING_COLUMN_TYPE("com.lang.Double", "NUMBER", "23.2", DbType.Oracle),
    ORACLE_CHAR_PACKING_COLUMN_TYPE("com.lang.Character", "VARCHAR2", "255", DbType.Oracle),
    ORACLE_BYTEARRAY_COLUMN_TYPE("byte[]", "BLOB", "", DbType.Oracle),
    ORACLE_DATE_COLUMN_TYPE("java.util.Date", "DATE", "", DbType.Oracle),
    ORACLE_SQL_DATE_COLUMN_TYPE("java.sql.Date", "DATE", "", DbType.Oracle),
    ORACLE_TIMESTAMP_COLUMN_TYPE("java.sql.TIMESTAMP", "TIMESTAMP", "", DbType.MySQL),
    DEFAULT_ORACLE_UNKNOWN_TYPE("String", "VARCHAR2", "255", DbType.Oracle);

    // Model对象属性的类型
    private final String fieldType;
    // 数据库中列的类型
    private final String columnType;
    // 数据库中列的长 或 精度
    private final String columnLength;
    // 数据库类型
    private final DbType dbType;

    FieldToColumnType(String fieldType, String columnType, String columnLength, DbType dbType) {
        this.fieldType = fieldType;
        this.columnType = columnType;
        this.columnLength = columnLength;
        this.dbType = dbType;
    }

    /**
     * //TODO
     *
     * @param fieldType Model属性类型 例如:int、java.util.Integer
     * @param dbType    数据库类型
     * @return com.db.FieldToColumnType
     * @title getColumnTypeByField 根据Model属性类型得到转换后数据中的类型
     * @author yuanmengfan
     * @date 2022/7/12 21:45
     */
    public static FieldToColumnType getColumnTypeByField(String fieldType, DbType dbType) {
        // fieldType 不能为空
        if (StrUtil.isBlank(fieldType)) throw new RuntimeException("fieldType is null");
        // dbType 不能为空
        Objects.requireNonNull(dbType, "DbType NOT NULL");
        // 寻找匹配的字段类型
        Optional<FieldToColumnType> first = getFieldToColumnTypesByDbType(dbType).stream()
                .filter((map) -> fieldType.equals(map.getFieldType())).findFirst();
        // 如果没有找到合适的类型直接返回该数据库类型中默认的类型
        if (first.isEmpty()) {
            return defaultTypeByDbType(dbType);
        }
        return first.get();
    }

    /**
     * 返回数据库中默认的字段类型
     *
     * @param dbType 数据库类型
     * @return com.db.FieldToColumnType
     * @title defaultTypeByDbType
     * @author yuanmengfan
     * @date 2022/7/12 21:51
     */
    private static FieldToColumnType defaultTypeByDbType(DbType dbType) {
        switch (dbType) {
            case MySQL:
                return FieldToColumnType.DEFAULT_MYSQL_UNKNOWN_TYPE;
            case Oracle:
                return FieldToColumnType.DEFAULT_ORACLE_UNKNOWN_TYPE;
            default:
                return null;
        }
    }

    /**
     * //TODO 返回为DbType的FieldToColumnType
     *
     * @param dbType
     * @return java.util.List<com.db.FieldToColumnType>
     * @title getFieldToColumnTypesByDbType
     * @author yuanmengfan
     * @date 2022/7/12 21:56
     */
    public static List<FieldToColumnType> getFieldToColumnTypesByDbType(DbType dbType) {
        return Arrays.stream(FieldToColumnType.values()).filter((map) -> dbType == map.getDbType()).collect(Collectors.toList());
    }
}

2、可以扩展的注解类

package com.db;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author yuanmengfan
 * @date 2022/7/9 16:59
 * @description 字段的扩展属性
 * /@Retention 的用法:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
 * RetentionPolicy.CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释
 * RetentionPolicy.RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取
 * RetentionPolicy.SOURCE 编译器要丢弃的注释
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface TableExtension {
    // 是否为主键
    boolean isId() default false;
    
    // 自定义的列名
    String columnName() default "";
    
    // 字段的长度
    int length() default Integer.MIN_VALUE;

    // 字段是否不为空
    boolean isNotNull() default false;
    
    // 字段的默认值
    String defaultValue() default DefaultValues.NONE;
    
    // 字段的注释
    String remark() default "";
}

3、重要的逻辑生成类

package com.db;

import cn.hutool.core.util.StrUtil;
import com.model.DbType;

import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.*;


/**
 * @author yuanmengfan
 * @date 2022/7/9 16:06
 * @description
 */
public class TableBuilder {
	/**
     * //TODO 根据全类名生成建表语句
     * @title createTableSql
     * @param className
     * @param dbType
     * @return java.lang.String
     * @author yuanmengfan
     * @date 2022/7/12 22:36
     */
    public String createTableSql(String className, DbType dbType) throws ClassNotFoundException {
        if(StrUtil.isNotBlank(className)) throw new RuntimeException("className cannot null");

        return createTableSql(Class.forName(className),dbType);
    }

    /**
     * //TODO 获得建表语句
     *
     * @param model  需要生成表的Model对象
     * @param dbType 数据库的类型
     * @return java.lang.String
     * @title createTableSql
     * @author yuanmengfan
     * @date 2022/7/12 22:01
     */
    public String createTableSql(Class<?> model, DbType dbType) {
        String result = "";
        switch (dbType) {
            case MySQL:
                result = createMySQLTableSQL(model);
                break;
            case Oracle:
                result = createOracleTableSQL(model);
                break;
            default:
                break;
        }
        return result;
    }


    /**
     * //TODO 生成MySQL类型的建表语句
     *
     * @param model 
     * @return java.lang.String
     * @title createMySQLTableSQL
     * @author yuanmengfan
     * @date 2022/7/12 22:03
     */
    private String createMySQLTableSQL(Class<?> model) {
        // model不能为空
        Objects.requireNonNull(model, "MODEL MUST NOT NULL");

        StringBuffer sql = new StringBuffer();

        TableExtension extension = model.getAnnotation(TableExtension.class);

        // 表注释
        String columnRemark = extension == null ? "" : extension.remark();
        // 表名
        String tableName = getTableName(model);
        // 主体内容
        String context = getMySQLModelContext(model);

        // 前置处理表存在的导致表创建不了的Sql
        sql.append("DROP TABLE IF EXISTS `").append(tableName).append("`;\n");

        // 构建CREATE TABLE 语句
        sql.append("CREATE TABLE ").append("`").append(tableName).append("`").append("(\n")
                .append(context)
                .append(") ").append(" COMMENT '").append(columnRemark).append("';");
        return sql.toString();
    }

    /**
     * //TODO 根据model对象中的扩张属性来处理,有哪些字段?是什么样类型?是什么样的约束条件?并生成对应的Sql
     *
     * @param model
     * @return java.lang.String
     * @title getMySQLModelContext
     * @author yuanmengfan
     * @date 2022/7/12 22:10
     */
    private String getMySQLModelContext(Class<?> model) {
        Field[] declaredFields = model.getDeclaredFields();
        StringBuffer context = new StringBuffer();
        Arrays.stream(declaredFields).forEach(field -> {
            // 根据对应的字段类型与数据库类型获取匹配的FieldToColumnType
            FieldToColumnType columnTypeByField = FieldToColumnType.getColumnTypeByField(field.getType().getName(), DbType.MySQL);

            // 字段名
            String fieldName = field.getName();
            // 数据库列类型
            String columnType = columnTypeByField.getColumnType();
            // 字段类型长度
            String columnLength = StrUtil.isBlank(columnTypeByField.getColumnLength()) ?
                    "" : String.format("(%s)", columnTypeByField.getColumnLength());
            // 字段是否为主键
            boolean idPresent = false;
            // 字段是否不能为NULL
            boolean isNotNull = false;
            // 字段默认值
            String defaultValue = "";
            // 数据库字段注释
            String columnRemark = "";

            // 判断该字段是否有扩展属性的这个注解 如果有个话 针对每个字段进行特殊处理
            TableExtension extension = field.getAnnotation(TableExtension.class);
            if (extension != null) {
                // 扩展属性的 isNotNull 为true 时defaultValue不能为 DefaultValues.NULL
                if (extension.isNotNull() && extension.defaultValue().equals(DefaultValues.NULL))
                    throw new RuntimeException("Table " + model.getSimpleName() + " Field " + fieldName +
                            "! When Extension IsNotNull are true, DefaultValue cannot be DefaultValues.NULL.");
                fieldName = StrUtil.isNotBlank(extension.columnName()) ? extension.columnName() : fieldName;
                columnLength = extension.length() == Integer.MIN_VALUE ?
                        columnLength : String.format("(%s)", extension.length());
                idPresent = extension.isId();
                isNotNull = extension.isNotNull();
                // 可自定义默认值
                defaultValue = getDefaultValue(extension.defaultValue());
                columnRemark = extension.remark();
            }
            context.append("\t")
                    .append(" `").append(fieldName).append("` ")
                    .append(columnType)
                    .append(columnLength)
                    // 该字段是主键的话添加 PRIMARY KEY这个关键字
                    .append(idPresent ? " PRIMARY KEY" : "")
                    // 该字段如果不为NULL添加 NOT NULL这个关键字
                    .append(isNotNull ? " NOT NULL" : "")
                    .append(StrUtil.isBlank(defaultValue) ? "" : (" DEFAULT " + defaultValue))
                    .append(" COMMENT '").append(columnRemark).append("'")
                    // 判断是否为最后一个字段 做最后一个逗号的处理
                    .append(field == declaredFields[declaredFields.length - 1] ? "" : ",")
                    .append("\n");
        });
        return context.toString();
    }
    /**
     * //TODO 生成Oracle类型的建表语句
     * @title createOracleTableSQL
     * @param model
     * @return java.lang.String
     * @author yuanmengfan 
     * @date 2022/7/12 22:23
     */
    private String createOracleTableSQL(Class<?> model) {
        Objects.requireNonNull(model, "MODEL MUST NOT NULL");
        StringBuffer sql = new StringBuffer();
        // 表名
        String tableName = getTableName(model).toUpperCase();
        // 主体内容
        String context = getOracleModelContext(model);
        // 主体内容
        String fieldNodes = getOracleFieldNotes(model, tableName);

        // 表存在则删除表的的前置语句
        sql.append(String.format("DECLARE \n" +
                "      NUM   NUMBER; \n" +
                "BEGIN \n" +
                "      SELECT COUNT(1) INTO NUM FROM ALL_TABLES WHERE TABLE_NAME = '%1$s'; \n" +
                "      IF   NUM = 1   THEN \n" +
                "          EXECUTE IMMEDIATE 'DROP TABLE %1$s'; \n" +
                "      END IF; \n" +
                "END;\n", tableName));

        // 处理begin 后不能执行其他语句的问题
        sql.append("/\n");

        sql.append("CREATE TABLE ").append(tableName).append("(\n")
                .append(context)
                .append(") ;");
        sql.append("\n").append(fieldNodes);
        return sql.toString();
    }
    /**
     * //TODO 根据model对象中的扩张属性来处理,有哪些字段?是什么样类型?是什么样的约束条件?并生成对应的Sql
     * 由于Oracle跟MySQL的建表语句有一些细节的差异 所有封装的方法就分开写了 怕之后不好扩展
     * @param model
     * @return java.lang.String
     * @title getOracleModelContext
     * @author yuanmengfan
     * @date 2022/7/12 22:10
     */
    private String getOracleModelContext(Class<?> model) {
        String tableName = model.getSimpleName().toUpperCase();
        Field[] declaredFields = model.getDeclaredFields();
        StringBuffer context = new StringBuffer();
        Arrays.stream(declaredFields).forEach(field -> {
            FieldToColumnType columnTypeByField = FieldToColumnType.getColumnTypeByField(field.getType().getName(), DbType.Oracle);
            // 字段名
            String fieldName = field.getName();
            // 数据库列类型
            String columnType = columnTypeByField.getColumnType();
            // 字段类型长度
            String columnLength = StrUtil.isBlank(columnTypeByField.getColumnLength()) ?
                    "" : String.format("(%s)", columnTypeByField.getColumnLength());
            // 字段是否为主键
            boolean idPresent = false;
            // 字段是否不能为NULL
            boolean isNotNull = false;
            // 字段默认值
            String defaultValue = "";
            TableExtension extension = field.getAnnotation(TableExtension.class);
            if (extension != null) {
                if (extension.isNotNull() && extension.defaultValue().equals(DefaultValues.NULL))
                    throw new RuntimeException("Table " + tableName + " Field " + fieldName +
                            "! When Extension IsNotNull are true, DefaultValue cannot be DefaultValues.NULL.");

                fieldName = (StrUtil.isNotBlank(extension.columnName()) ? extension.columnName() : fieldName).toUpperCase();
                columnLength = extension.length() == Integer.MIN_VALUE ?
                        columnLength : String.format("(%s)", extension.length());
                idPresent = extension.isId();
                isNotNull = extension.isNotNull();
                defaultValue = getDefaultValue(extension.defaultValue());
            }
            context.append("\t")
                    .append(" ").append(fieldName).append(" ")
                    .append(columnType)
                    .append(columnLength)
                    .append(idPresent ? " PRIMARY KEY" : "")
                    .append(StrUtil.isBlank(defaultValue) ? "" : (" DEFAULT " + defaultValue))
                    .append(isNotNull ? " NOT NULL" : "")
                    // 判断是否为最后一个字段 做最后一个逗号的处理
                    .append(field == declaredFields[declaredFields.length - 1] ? "" : ",")
                    .append("\n");
        });
        return context.toString();
    }

    /**
     * //TODO 生成添加Oracle注释的语句
     * @title getOracleFieldNotes
     * @param model
     * @param tableName
     * @return java.lang.String
     * @author yuanmengfan
     * @date 2022/7/12 22:21
     */
    private String getOracleFieldNotes(Class<?> model, String tableName) {
        StringBuffer fieldNotes = new StringBuffer();
        TableExtension extension = model.getAnnotation(TableExtension.class);
        // 生成表注释
        if (extension != null && StrUtil.isNotBlank(extension.remark())) {
            fieldNotes.append(String.format("comment on table %s is '%s' ;\n", tableName, extension.remark()));
        }
        // 只为有remark值的字段添加注释
        Arrays.stream(model.getDeclaredFields()).filter(field -> {
            TableExtension fieldAnnotation = field.getAnnotation(TableExtension.class);
            if (fieldAnnotation != null && StrUtil.isNotBlank(fieldAnnotation.remark())) return true;
            else return false;
        }).forEach(field -> {
            TableExtension fieldAnnotation = field.getAnnotation(TableExtension.class);
            String fieldName = (StrUtil.isNotBlank(fieldAnnotation.columnName()) ? fieldAnnotation.columnName() : field.getName()).toUpperCase();
            fieldNotes.append(String.format("comment on column %s.%s is '%s';\n"
                    , tableName, fieldName, fieldAnnotation.remark()));
        });
        return fieldNotes.toString();
    }

    /**
     * //TODO 处理特殊的默认值
     * @title getDefaultValue
     * @param defaultValue
     * @return java.lang.String
     * @author yuanmengfan
     * @date 2022/7/12 22:20
     */
    private String getDefaultValue(String defaultValue) {
        if (StrUtil.isBlank(defaultValue)) return "";
        switch (defaultValue) {
            case DefaultValues.NULL:
            case DefaultValues.EMPTY_STRING:
            case DefaultValues.NULL_STRING:
            case DefaultValues.TRUE:
            case DefaultValues.FALSE:
                return defaultValue;
            default:
                return "'" + defaultValue + "'";
        }
    }

    /**
     * //TODO 根据Model类获取生成的表名
     *
     * @param model Model对象
     * @return java.lang.String
     * @title getTableName
     * @author yuanmengfan
     * @date 2022/7/12 21:59
     */
    private String getTableName(Class<?> model) {
        String tableName = "";
        // 当model 有 Table 这个注解时 且 Table注解的name值不是空时 直接取tableName为 生成表名
        // 否则 类名 当表名
        if (model.isAnnotationPresent(Table.class) && StrUtil.isNotBlank(model.getAnnotation(Table.class).name())) {
            tableName = model.getAnnotation(Table.class).name();
        } else {
            tableName = model.getSimpleName();
        }
        return tableName;
    }
}

4、处理默认值的类

package com.db;

/**
 * @author yuanmengfan
 * @date 2022/7/10 16:33
 * @description
 */

public class DefaultValues {
    public static final String NULL = "NULL";
    public static final String NULL_STRING = "'NULL'";
    public static final String EMPTY_STRING = "''";
    public static final String FALSE = "0";
    public static final String TRUE = "1";
    public static final String NONE = "";
}

5、测试

public static void main(String[] args) {
        System.out.println(new TableBuilder().createTableSql(TestModel.class, DbType.Oracle));
    }

package com.db;

import lombok.Getter;
import lombok.Setter;
import org.springframework.lang.NonNull;

import javax.persistence.Table;
import java.util.Date;

/**
 * @author yuanmengfan
 * @date 2022/7/9 17:26
 * @description
 */

@Getter
@Setter
@Table(name = "t_testModel")
@TableExtension(remark = "测试表")
public class TestModel {
    @TableExtension(isId = true)
    private String id;
    @TableExtension(columnName = "userName",defaultValue = "name1", remark = "姓名")
    private String name;
    @TableExtension(remark = "年龄", length = 10)
    private int age;
    @TableExtension(defaultValue = DefaultValues.NULL, remark = "工资")
    private Double salary;
    @TableExtension(remark = "生日")
    private Date birth;
    @TableExtension(defaultValue=DefaultValues.TRUE,remark = "是否禁用")
    private boolean disabled;
}

6、结果

// 生成结果
------------- Oralce
DECLARE 
      NUM   NUMBER; 
BEGIN 
      SELECT COUNT(1) INTO NUM FROM ALL_TABLES WHERE TABLE_NAME = 'T_TESTMODEL'; 
      IF   NUM = 1   THEN 
          EXECUTE IMMEDIATE 'DROP TABLE T_TESTMODEL'; 
      END IF; 
END;
/
CREATE TABLE T_TESTMODEL(
	 ID VARCHAR2(255) PRIMARY KEY,
	 USERNAME VARCHAR2(255) DEFAULT 'name1',
	 AGE NUMBER(10),
	 SALARY VARCHAR2(255) DEFAULT NULL,
	 BIRTH DATE,
	 DISABLED CHAR(1) DEFAULT 1
) ;
comment on table T_TESTMODEL is '测试表' ;
comment on column T_TESTMODEL.USERNAME is '姓名';
comment on column T_TESTMODEL.AGE is '年龄';
comment on column T_TESTMODEL.SALARY is '工资';
comment on column T_TESTMODEL.BIRTH is '生日';
comment on column T_TESTMODEL.DISABLED is '是否禁用';
  
------------- MySQL
DROP TABLE IF EXISTS `t_testModel`;
CREATE TABLE `t_testModel`(
	 `id` VARCHAR(255) PRIMARY KEY COMMENT '',
	 `userName` VARCHAR(255) DEFAULT 'name1' COMMENT '姓名',
	 `age` int(10) COMMENT '年龄',
	 `salary` VARCHAR(255) DEFAULT NULL COMMENT '工资',
	 `birth` datetime COMMENT '生日',
	 `disabled` tinyint(1) DEFAULT 1 COMMENT '是否禁用'
)  COMMENT '测试表';
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

假女吖☌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值