手把手教你从数据库生成实体类(三)

建表语句分析

建表sql

下面是执行 sql show create table user 的结果:

CREATE TABLE `user` (                                                            
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',                         
  `name` varchar(225) DEFAULT NULL COMMENT '用户名',                             
  `create_date` datetime DEFAULT NULL,                                           
  `status` int(11) DEFAULT NULL,                                                 
  `age` int(11) DEFAULT NULL COMMENT '年龄',                                     
  `mark` varchar(225) DEFAULT NULL,                                              
  PRIMARY KEY (`id`)                                                             
) ENGINE=InnoDB AUTO_INCREMENT=2104778081 DEFAULT CHARSET=latin1 COMMENT='用户表'          

这里可以看出,要创建的实体类的名称就在第一行的CREATE TABLE 后的两个`符号中间,这样我们就可以通过正则将表的名称取出来,然后转换成为我们需要的class名称。首先我们先写一个通过正则提取数据的方法,下面是代码:

正则代码

    /**
     * 根据正则查找
     *
     * @param sql
     * @param pattern
     * @param group
     * @return
     */
    static String getByPattern(String sql, String pattern, int group) {
        Pattern compile = Pattern.compile(pattern);
        Matcher matcher = compile.matcher(sql);
        while (matcher.find()) {
            return matcher.group(group);
        }
        return null;
    }

现在开始从建表语句中提取table的名称(虽然在获得数据库所有表的时候就已经知道了,但是在写一次也没有什么问题不是 ~~~),下面是代码:

获取class名称

    /**
     * 获得表的名称
     *
     * @param sql
     * @return
     */
    public static String getTableName(String sql) {
        return getByPattern(sql, "CREATE TABLE `(.*)`", 1);
    }

这里就已经将table的名称取出来了。
接下来是获取class上的注释,这里我们取table的注释。下面是代码:

提取class注释

    public static String getTableComment(String sql) {
        return getByPattern(sql, "\\) .* COMMENT='(.*)'", 1);
    }

现在开始提取数据库中的字段,字段类型,字段注释。

字段,字段类型,字段注释

先取出来建表语句中的和字段相关的sql

    /**
     * 获取建表语句中和字段相关的sql
     *
     * @param sql
     * @return
     */
    public static List<String> getColumnSqls(String sql) {
        List<String> lines = new ArrayList<>();
        Scanner scanner = new Scanner(sql);
        boolean start = false;
        while (scanner.hasNextLine()) {
            String nextLine = scanner.nextLine();
            if (nextLine.indexOf("CREATE TABLE") != -1) {
                start = true;
                continue;
            }
            if (nextLine.indexOf("PRIMARY KEY") != -1) {
                start = false;
                continue;
            }
            if (start) {
                lines.add(nextLine);
            }
        }
        return lines;
    }

这里的运行结果是:

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',                         
  `name` varchar(225) DEFAULT NULL COMMENT '用户名',                             
  `create_date` datetime DEFAULT NULL,                                           
  `status` int(11) DEFAULT NULL,                                                 
  `age` int(11) DEFAULT NULL COMMENT '年龄',                                     
  `mark` varchar(225) DEFAULT NULL, 

这也就取到了table中所有的字段相关信息了,接下来我们来获取字段名称:

获取class属性名称,注释,sql中的数据类型

List<String> columns = SqlUtils.getColumnSqls(sql);
for (String oneLine : columns) {
    System.out.println(oneLine);
    String columnName = SqlUtils.getByPattern(oneLine, "`(.*)`", 1);
    String comment = SqlUtils.getByPattern(oneLine, "COMMENT '(.*)'", 1);
    String columnType = SqlUtils.getByPattern(oneLine, "`" + columnName + "` ([A-Za-z]*)", 1);
    System.out.printf("名称:%-20s 类型:%-20s 注释:%-20s \n", columnName, columnType, comment);
}

输出结果:

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',                         
名称:id                   类型:int                  注释:用户id                 
  `name` varchar(225) DEFAULT NULL COMMENT '用户名',                             
名称:name                 类型:varchar              注释:用户名                  
  `create_date` datetime DEFAULT NULL,                                           
名称:create_date          类型:datetime             注释:null                 
  `status` int(11) DEFAULT NULL,                                                 
名称:status               类型:int                  注释:null                 
  `age` int(11) DEFAULT NULL COMMENT '年龄',                                     
名称:age                  类型:int                  注释:年龄                   
  `mark` varchar(225) DEFAULT NULL,                                              
名称:mark                 类型:varchar              注释:null

这里我们拿到了字段名称,字段类型后还要将其转换为java中的格式,字段名称转换和上面的class名称转换类似,只是首字母不需要大写,这里就不贴代码了。把sql 的数据类型转换为java的数据类型代码在下面:

sql数据类型和java数据类型转换


import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class ColumnFieldTypeMapping {

    private Map<String, Class> sqlFieldTypeMapping = new HashMap<>();

    {
        sqlFieldTypeMapping.put("VARCHAR", String.class);
        sqlFieldTypeMapping.put("CHAR", String.class);
        sqlFieldTypeMapping.put("TEXT", String.class);
        sqlFieldTypeMapping.put("MEDIUMTEXT", String.class);
        sqlFieldTypeMapping.put("LONGTEXT", String.class);
        sqlFieldTypeMapping.put("TINYTEXT", String.class);
        sqlFieldTypeMapping.put("BIT", Boolean.class);

        sqlFieldTypeMapping.put("INT", int.class);
        sqlFieldTypeMapping.put("BIGINT", long.class);
        sqlFieldTypeMapping.put("DOUBLE", double.class);
        sqlFieldTypeMapping.put("TINYINT", int.class);
        sqlFieldTypeMapping.put("FLOAT", float.class);
        sqlFieldTypeMapping.put("DECIMAL", BigDecimal.class);

        sqlFieldTypeMapping.put("INT UNSIGNED", int.class);
        sqlFieldTypeMapping.put("BIGINT UNSIGNED", int.class);
        sqlFieldTypeMapping.put("DECIMAL UNSIGNED", BigDecimal.class);

        sqlFieldTypeMapping.put("DATETIME", Date.class);
        sqlFieldTypeMapping.put("TIME", Date.class);
        sqlFieldTypeMapping.put("DATE", Date.class);
        sqlFieldTypeMapping.put("TIMESTAMP", Date.class);
    }

    /**
     * 根据sql数据类型获取Java数据类型
     *
     * @param columnType
     * @return
     */
    public Class getFieldType(String columnType) {
        Class aClass = sqlFieldTypeMapping.get(columnType);
        if (aClass == null) {
            return sqlFieldTypeMapping.get(columnType.toUpperCase());
        }
        return null;
    }

}

这里只是简单的做了一个映射,有需要修改的各自自己修改一下就好了。接下来我们来获取表中的id

获取id

获取id依然是使用正则就好了,代码如下:

public static String getId(String sql) {
    String id = getByPattern(sql, "PRIMARY KEY (`.*`)", 1);
    return getByPattern(id, "`(.*)`", 1);
}

因为原本语句中有一对括号,所以使用正则提取了两次。如果有更好的方法的话麻烦告知。

到了这,我就就已经从建表语句里拿到了所有需要的数据了,下面就开始使用这些数据来生成java文件了。

下一篇继续~

猜你喜欢

转载自www.cnblogs.com/hebaibai/p/10287259.html