java根据实体类去自动生成Mysql常规建表sql

网上有很多根据数据库表结构生成实体类的列子,但是我个人在新建一个表的时候比较喜欢先把实体类写好,所以写了一个通过实体类去自动生成常规的建表sql,也可以根据需要转换驼峰格式,直接执行即可,且可重复执行!这样就不需要去写建表sql了

代码是运用反射的方式去拿到实体类上面的注解去获取相关信息,
如果实体类中用的是Lombok也是不影响的。

主要注解
@Table:表名
@Id:主键
@Transient:过滤实体字段
@ApiModelProperty:字段说明(该注解是Swagger的注解,也是很实用的定义接口及接口相关信息的工具,大家可以网上自行了解)

1、实现代码如下:
需要传一个实体类路径和boolean类型的是否需要转换驼峰格式===>true就会根据实体对象(userName)转换为数据库字段的(user_name)

/***
     * 根据实体类自动生成Mysql建表sql
     * @param beanName  实体类路径
     * @param isConvert  是否需要转换驼峰格式
     * @return
     */
    public String generateTableMysql(String beanName,boolean isConvert) {
        StringBuilder sqlSb = new StringBuilder();

        if (null != beanName && !"".equals(beanName)) {
            Object obj = null;
            try {
                obj = Class.forName(beanName).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            // 拿到该类
            Class<?> clz = obj.getClass();
            // 获取实体类的所有属性,返回Field数组
            Field[] fields = clz.getDeclaredFields();
            if (fields != null) {
                JavaTypesSocietyDatabaseTypes utilBean = new JavaTypesSocietyDatabaseTypes();

                //获取实体类的Table注解表名(导入persistence包)
                Table tableClass = clz.getAnnotation(Table.class);
                String tableName = "";
                if (tableClass!=null){
                    System.out.println("表名:"+tableClass.name());
                    tableName=tableClass.name();
                }
                sqlSb.append("drop table if exists "+tableName+"; \n");

                sqlSb.append("create table "+tableName+"( \n");

                String idKey = "";

                for (Field field : fields) {
                    if (!field.isAccessible()) {
                        field.setAccessible(true);
                    }
                    String type = field.getGenericType().toString();
                    System.out.println("类的属性类型全称:" + type);
                    if (type.indexOf(".") == -1 || type.indexOf("java.") != -1) {//过滤实体对象
                        //截取最后一个.后面的字符
                        type = type.substring(type.lastIndexOf(".") + 1);
                        System.out.println("对象属性类型:" + type);
                        if (!field.getType().equals(List.class)) {// 不匹配list类型
                            //字段名称
                            String name = field.getName();

                            Method doSomeMethod = null;
                            try {
                                //获取get方法
                                doSomeMethod = clz.getDeclaredMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1));
                            } catch (NoSuchMethodException e) {
                                e.printStackTrace();
                            }
                            boolean isExist = true;
                            //判断该方法上是否存在这个注解
                            /*if (doSomeMethod.isAnnotationPresent(Transient.class)) {
                                Transient aTransient = doSomeMethod.getAnnotation(Transient.class);
                                System.out.println(name+"==>对象不属于表字段:"+aTransient);
                                isExist =false;
                            }
                            //判断该字段上是否存在这个注解
                            if (field.isAnnotationPresent(Transient.class)) {
                                Transient aTransient = field.getAnnotation(Transient.class);
                                System.out.println(name+"==>对象不属于表字段:"+aTransient);
                                isExist =false;
                            }*/
                            //(Transient注解是导入persistence包)
                            if (field.isAnnotationPresent(Transient.class) ||(null!=doSomeMethod  && doSomeMethod.isAnnotationPresent(Transient.class))) {
                                System.out.println(name+"==>对象不属于表字段");
                                isExist =false;
                            }
                            //属于表字段
                            if(isExist){
                                StringBuilder convertName = new StringBuilder();
                                convertName.append(name);
                                //如果需要转换驼峰格式
                                if (isConvert) {
                                    convertName = new StringBuilder();
                                    for (int i = 0; i < name.length(); i++) {
                                        //如果是大写前面先加一个_
                                        if(isUpperCase(name.charAt(i))){
                                            convertName.append("_");
                                        }
                                        convertName.append(name.charAt(i));
                                    }
                                }
                                name=convertName.toString();
                                sqlSb.append("    "+name.toUpperCase()+" ");
                                //java 数据类型转换成 Oracle 字段数据类型
                                sqlSb.append(" "+utilBean.societyMysql(type));
                                //判断该字段是否是Id主键(导入persistence包)
                                if(field.isAnnotationPresent(Id.class)){
                                    Id id = field.getAnnotation(Id.class);
                                    idKey=name.toUpperCase();//id主键字段
                                    System.out.println("id主键字段:"+idKey);
                                    sqlSb.append("  NOT NULL  " );
                                }
                                sqlSb.append(" comment " );
                                //字段属性说明(没有ApiModelProperty包的把这段代码注释掉)
                                if(field.isAnnotationPresent(ApiModelProperty.class)){
                                    ApiModelProperty explain = field.getAnnotation(ApiModelProperty.class);
                                    System.out.println("字段说明:"+explain.value());
                                    sqlSb.append(" '"+explain.value()+"',\n" );
                                }else{
                                    sqlSb.append(" '',\n" );
                                }

                                /**
                                 * 字段属性说明
                                 * 没有ApiModelProperty包的把上面那段代码注释掉,用这个
                                 */
                                /*
                                sqlSb.append(" '',\n" );
                                */

                            }

                        }
                    }

                }
                if(null!=idKey && !"".equals(idKey) ){
                    sqlSb.append(" primary key ("+idKey+") \n" );
                }else{
                    String lastStr = sqlSb.substring(0, sqlSb.length() - 1);
                    //如果最后一个字符是逗号结尾
                    if(lastStr.equals(",")){
                        //删除最后一个字符
                        sqlSb=sqlSb.deleteCharAt(sqlSb.length() - 1);
                    }
                }
                sqlSb.append(" ); \n" );

            }
        }

        return sqlSb.toString();
    }
    
    //字母是否是大写
    public boolean isUpperCase(char c) {
        return c >=65 && c <= 90;
    }

2、java实体对象属性对应的Mysql字段数据类型

 public String societyMysql(String javaType){
        String oracleType ="";
        if(javaType.equals("String")){
            oracleType="varchar(255)";
        }
        //不区分大小写
        else if(javaType.equalsIgnoreCase("BigDecimal") ||javaType.equalsIgnoreCase("short")
                ||javaType.equalsIgnoreCase("boolean")||javaType.equalsIgnoreCase("long"))
        {
            oracleType="decimal(6)";
        }else if(javaType.equals("Date")){
            oracleType="date";
        }else if(javaType.equalsIgnoreCase("Timestamp")){
            oracleType="datetime";
        }else if(javaType.equals("byte[]")){
            oracleType="blob";
        }else if(javaType.equals("int")){
            oracleType="int";
        }else if(javaType.equals("Integer")){
            oracleType="integer";
        }else if(javaType.equalsIgnoreCase("double")){
            oracleType="double";
        }else if(javaType.equalsIgnoreCase("float")){
            oracleType="float";
        }
        return oracleType;
    }

3、测试的实体类

package com.test.entity;

import io.swagger.annotations.ApiModelProperty;

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

@Table(name = "TEST_TABLE_A")
public class TestBean {
    //id
    @Id
    private  int  id;
    //菜单名称
    @ApiModelProperty(value = "菜单名称")
    private  String  name_ss;
    //菜单url
    @Transient
    private  String  url;
    //顺序
    @ApiModelProperty(value = "顺序")
    private  int  sort;

    private Date endDate;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName_ss() {
        return name_ss;
    }

    public void setName_ss(String name_ss) {
        this.name_ss = name_ss;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public int getSort() {
        return sort;
    }

    public void setSort(int sort) {
        this.sort = sort;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }
}

4、main方法

package com.test.testClass;

import com.test.util.BeanToGenerateTable;

public class Test{
    public static void main(String[] args) throws InterruptedException {
        BeanToGenerateTable bean = new BeanToGenerateTable();
        String sql = bean.generateTableMysql("com.test.entity.TestBean",true);
        System.out.println(sql);
    }

}

5、执行结果

drop table if exists TEST_TABLE_A; 
create table TEST_TABLE_A( 
    ID  int  NOT NULL   comment  '',
    NAME_SS  varchar(255) comment  '菜单名称',
    SORT  int comment  '顺序',
    END_DATE  date comment  '',
 primary key (ID) 
 ); 

不完善的地方大家根据自己需要进行修改!

根据实体类自动生成Oracle常规建表sql地址:
https://blog.csdn.net/qq_37928228/article/details/111066778

每天一个转行小技巧,你学废了吗?

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值