• [04] 利用注解生成实体类对应的建表sql语句


    1、实现功能

    我们已经对注解有了基本的认识,知道了如何自定义注解,如何使用和最基本的处理注解。

    本篇主要介绍,如何使用运行时级别的注解,配合反射来自动生成建表的sql语句。如下例:

    我们有实体类Student,并添加相应的注解 @Table、@Column,最终可以获取到创建对应表的sql语句
    @Table(name = "t_student") 
    public class Student {
    
        @Column(name = "c_name")
        public String name;
    
        @Column(name = "c_sex")
        public String sex;
    
        ...
    }

    2、自定义注解

    @Retention(RetentionPolicy.RUNTIME)
    public @interface Table {
        //设置表名
        String name();
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Column {
        //设置字段名
        String name();
    }

    3、对实体类使用注解

    /**
     * 学生类
     */
    @Table(name = "t_student")
    public class Student {
    
        @Column(name = "c_name")
        public String name;
    
        @Column(name = "c_sex")
        public String sex;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }

    4、运行时获取注解并转化

    4.1 获取表名

    private static String getTableName(Class<?> clazz) {
        String name = null;
        //如果有@Table注解
        if (clazz.isAnnotationPresent(Table.class)) {
            Table table = clazz.getAnnotation(Table.class);
            name = table.name();
        }
        
        return name;
    }

    4.2 获取字段名和类型

    4.2.1 建立NameAndType类用来封装获取到的字段名和类型
    public class NameAndType {
        
        String name;
        
        String type;
    
        public NameAndType(String name, String type) {
            this.name = name;
            this.type = type;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    }

    4.2.2 获取字段名和类型
    private static List<NameAndType> getColumns(Class<?> clazz) throws Exception {
        List<NameAndType> colums = new ArrayList<NameAndType>();
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null) {
            //分析clazz中变量是否需要生成sql字段
            for (Field field : fields) {
                if (field.isAnnotationPresent(Column.class)) {
                    //生成sql字段的字段名
                    Column column = field.getAnnotation(Column.class);
                    String name = column.name();
                    //生成sql字段的字段类型
                    String type;
                    if (int.class.isAssignableFrom(field.getType())) {
                        type = "integer";
                    }
                    else if (String.class.isAssignableFrom(field.getType())) {
                        type = "text";
                    }
                    else {
                        throw new Exception("unsupported type");
                    }
                    colums.add(new NameAndType(name, type));
                }
            }
        }
    
        return colums;
    }

    注意Class类的isAssignableFrom方法可以判断两个类是不是存在父子关系。

    4.3 生成建表sql

    public static String createTable(Class<?> clazz) throws Exception {
        String sql = null;
        String tableName = getTableName(clazz);
        List<NameAndType> columns = getColumns(clazz);
    
        if (tableName != null && !tableName.equals("") && !columns.isEmpty()) {
            StringBuffer strBuffer = new StringBuffer("CREATE TABLE " + tableName + "( ");
            for (NameAndType column : columns) {
                String bean = column.getName() + " " + column.getType() + ", ";
                strBuffer.append(bean);
            }
            //删除最后多余的一个逗号
            strBuffer.deleteCharAt(strBuffer.length() - 2);
            strBuffer.append(");");
            sql = strBuffer.toString();
        }
    
        return sql;
    }

    4.4 测试和结果

    public class TestAnnotation {
        public static void main(String[] args) throws Exception {
            String sql = TableAnnotationUtil.createTable(Student.class);
            System.out.println(sql);
        }
    }
    
    //结果输出
    CREATE TABLE t_student( c_name text, c_sex text );

    5、参考链接

    附件列表

    • 相关阅读:
      springcloud中常用的注解
      MySQL--Profiling和Trace使用
      MySQL Execution Plan--IN查询计划
      MySQL Config--参数system_time_zone和参数time_zone
      MySQL Replication--全局参数gtid_executed和gtid_purged
      MySQL Transaction--事务无法正常回滚导致的异常
      MySQL Execution Plan--数据排序操作
      MySQL Session--批量KILL会话
      MySQL Transaction--MySQL与SQL Server在可重复读事务隔离级别上的差异
      MySQL Transaction--事务相关查询
    • 原文地址:https://www.cnblogs.com/deng-cc/p/7462592.html
    Copyright © 2020-2023  润新知