根据Javabean生成数据库表结构

这篇博客介绍了一种利用Java注解自动生成数据库表的方法,通过定义DBTable、SQLColumn和Constraints注解,简化了大量字段的录入工作。TableCreator类解析这些注解,生成对应的MySQL和Oracle创建表语句,大大提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据javabean 生成数据库表

项目组长让我根据 接口文档搭建一个mock工程支持增删改查,一个接口字段值有七八十个字段,一个个粘贴到表中太慢,就搞了这么一个工具。

效果展示 目前就基本能用
在这里插入图片描述
其他类型在这里扩展
在这里插入图片描述

1 目录结构

在这里插入图片描述

2 代码

@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    String name() default "";
 }
@Inherited
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLColumn {
    //列名
    String name() default "";

    //描述
    String desc() default "";

    int size() default 64;

    // 约束注解
    Constraints constraints() default @Constraints;
}
@Inherited
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
   // 默认允许为空
   boolean allowNull() default true;
   // 默认允许重复
   boolean unique() default false;

   //是否递增
   boolean autoIncrement() default false;

   // 主键,默认为空
   boolean primaryKey() default false;
}
public class TableCreator {
    private static String getConstraints(Constraints constraints) { // 获取字段约束属性
        String cons = "";
        if (!constraints.allowNull()) {
            cons += " NOT NULL";
        }
        if (constraints.primaryKey()) {
            cons += " PRIMARY KEY";
        }
        if (constraints.unique()) {
            cons += " UNIQUE";
        }
        if (constraints.autoIncrement()) {
            cons += " AUTO_INCREMENT";
        }
        return cons;
    }

    public static String getMySQLSql(Class<?> cl) {
        // 通过注解得到表名
        DBTable dbtable = cl.getAnnotation(DBTable.class);
        String tableName = dbtable.name().length() > 1
                ? StringCaseUtils.camelCase2LowerSnackCase(dbtable.name())
                : StringCaseUtils.camelCase2LowerSnackCase(cl.getName().substring(cl.getName().lastIndexOf(".") + 1));
        List<String> columns = new ArrayList<>();
        // 得到该类下所有属性
        for (Field field : cl.getDeclaredFields()) {
            SQLColumn column = field.getAnnotation(SQLColumn.class);
            Optional.ofNullable(column).ifPresent(c -> {
                String columnName = column.name().length() < 1 ? field.getName() : column.name();
                String sqlType = getMySQLType(field.getType(), column);
                String name = StringCaseUtils.camelCase2LowerSnackCase(columnName);
                columns.add(name + " " + sqlType + getConstraints(column.constraints()) + getComment(column));
            });
        }
        return buildSQL(tableName, columns);
    }

    public static String getOracleSql(Class<?> cl) {
        // 通过注解得到表名
        DBTable dbtable = cl.getAnnotation(DBTable.class);
        String tableName = dbtable.name().length() > 1
                ? StringCaseUtils.camelCase2UpperSnackCase(dbtable.name())
                : StringCaseUtils.camelCase2UpperSnackCase(cl.getName().substring(cl.getName().lastIndexOf(".") + 1));
        List<String> columns = new ArrayList<>();
        List<String> comments = new ArrayList<>();
        // 得到该类下所有属性
        for (Field field : cl.getDeclaredFields()) {
            SQLColumn column = field.getAnnotation(SQLColumn.class);
            Optional.ofNullable(column).ifPresent(c -> {
                String columnName = column.name().length() < 1 ? field.getName() : column.name();
                String sqlType = getOracleType(field.getType(), column);
                String name = StringCaseUtils.camelCase2UpperSnackCase(columnName);
                columns.add(name + " " + sqlType + getConstraints(column.constraints()));
                // 字段注释
                if (column.desc().length() > 0) {
                    String comment = "COMMENT ON COLUMN " + tableName + "." + name + " IS '" + column.desc() + "';";
                    comments.add(comment);
                }
            });

        }
        StringBuilder sb = new StringBuilder(buildSQL(tableName, columns)).append("\n");
        comments.forEach(comment -> sb.append("\n ").append(comment));
        return sb.toString();
    }

    private static String buildSQL(String tableName, List<String> columns) {
        String sql;
        StringBuilder sb = new StringBuilder("CREATE TABLE " + tableName + "(");
        columns.forEach(column -> {
            // 拼接各个字段的定义语句
            sb.append("\n    ").append(column).append(",");
        });
        sql = sb.substring(0, sb.length() - 1) + "\n );";
        return sql;
    }

    private static String getOracleType(Class<?> type, SQLColumn column) {
        return " VARCHAR2(" + column.size() + ")";
    }


    private static String getMySQLType(Class<?> type, SQLColumn column) {
        if (type.equals(String.class)) {
            return "varchar(" + column.size() + ")";
        } else if (type.equals(Integer.class)) {
            return "int";
        } else if (type.equals(Long.class)) {
            return "long";
        } else if (type.equals(Boolean.class)) {
            return "tinyint(1)";
        } else if (type.equals(Byte.class)) {
            return "tinyint(4)";
        } else {
            return "varchar(" + column.size() + ")";
        }
    }

    private static String getComment(SQLColumn column) {
        String comment = "";
        if (column.desc().length() > 0) {
            comment = " COMMENT '" + column.desc() + "'";
        }
        return comment;
    }
}
public class StringCaseUtils {
    /**
     * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
     * camelCase -> SNAKE_CASE
     *
     * @param name 转换前的驼峰式命名的字符串
     * @return 转换后下划线大写方式命名的字符串
     */
    public static String camelCase2UpperSnackCase(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 将第一个字符处理成大写
            result.append(name.substring(0, 1).toUpperCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
                String s = name.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成大写
                result.append(s.toUpperCase());
            }
        }
        return result.toString();
    }

    /**
     * 将驼峰式命名的字符串转换为下划线小写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
     * camelCase -> snake_case
     *
     * @param name 转换前的驼峰式命名的字符串
     * @return snack_case
     */
    public static String camelCase2LowerSnackCase(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 循环处理其余字符
            for (int i = 0; i < name.length(); i++) {
                String s = name.substring(i, i + 1);
                // 第一个字母就是大写转成小写
                if (i == 0 && s.equals(s.toUpperCase())) {
                    result.append(s.toLowerCase());
                    continue;
                }
                // 在大写字母前添加下划线并转换成小写
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_").append(s.toLowerCase());
                    continue;
                }
                result.append(s);
            }
        }
        return result.toString();
    }

}

3 使用

@Data
@DBTable
public class Student {
    @SQLColumn(constraints = @Constraints(primaryKey = true), desc = "学号")
    private String studentId;
    @SQLColumn
    private Integer age;
    @SQLColumn(desc = "姓名")
    private String studentName;
    @SQLColumn(desc = "0 女 1 男")
    private Boolean sex;
}
public class Main {
    public static void main(String[] args) {
        String sql = TableCreator.getMySQLSql(Student.class);
        System.out.println(sql);
        String sql1 = TableCreator.getOracleSql(Student.class);
        System.out.println(sql1);
    }

}
博客地址:http://blog.youkuaiyun.com/vipbooks 一直以来把数据库转换成Entity或DTO都是一件让人头痛的事情,既浪费时间又很繁琐,看着几十上百个的几百上千个字段,真是一件让人很头痛的事情。 我们也想过很多办法解决这个问题,包括用MyEclipse连接数据库生成JavaBean,但多多少少还是会有一些不尽人意的地方,包括字段的comment总是无法生成,而且还会生成很多无用的注释代码,让代码看起来一点都不干净,配置非常繁琐等等问题。 于是一怒之下,自己动手丰衣足食,就自己用Swing写了一个通过数据库生成JavaBean的工具,支持MySQL、Oracle、SQLServce、PostgreSQL,完美支持JPA注解,可以同时生成Entity和DTO,可以自动去除前缀,并支持去除多个前缀,支持精确指定只生成哪几个Bean,也支持模糊查找生成哪几个Bean,现在不但成员变量上能生成备注了,而且在Getter和Setter上也能有备注了! 更重要的是所有的配置都能被保存到本地,只要配置过一次,下次使用只要点一下生成JavaBean,下一秒就能拿到你想要的JavaBean了,完全实现秒生成。并且集成各种实用工具,使得工作效率瞬间爆棚,生产力瞬间爆! 该压缩包中包含32位和64位两个版本。 第11版更新震撼发布,此次版本更新如下: 1、新增数据源配置管理功能,可以为每种类型的数据库添加多个不同的数据源。 2、新增快速新增数据源功能,快速为当前选中的数据库添加数据源。 3、新增打开目录功能,左键打开菜单选择要打开的目录,点击右键可以快速打开当前应用所在目录。 4、新增对使用驼峰命名的名和字段名的支持,例如名是UserInfo,生成Bean的类名也是UserInfo; 字段名是userId,那么生成Bean字段也是userId。 5、主界面移除驱动名下拉选项,并新增快速切换数据源配置下拉选项。 6、改进精确匹配中“更多”的选功能,在文本框中已选中的在打开选对话框时会被勾选。 7、改进清除StringBuffer工具,选择SQL类型会自动将“//”替换为“--”。 8、改进字符串格式化工具,将有更多类型可选,操作更方便。 9、其他一些小Bug的修改和代码优化调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值