注解加反射动态创建表

场景:一个实体,几十个字段,Java实体类建一遍,数据库建一遍,痛苦面具

 

所需代码:

package me.xiaomaju.base;

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

/**
 * @Description 注解 表名
 * @Author @xmj
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableNameAnnotation {

    String value(); //表名

}
TableNameAnnotation
package me.xiaomaju.base;

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

/**
 * @Description 注解 列名
 * @Author @xmj
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableColumnAnnotation {

    String value();//列名

    MySQLColumnType type() default MySQLColumnType.VARCHAR; //类型,默认varchar

    int length() default 20;//长度,默认20

}
TableColumnAnnotation
package me.xiaomaju.base;

/**
 * @Description 列类型枚举
 * @Author @xmj
 */
public enum MySQLColumnType {
    CHAR,
    VARCHAR,
    INT,
    DOUBLE,
    FLOAT
}
MySQLColumnType
package me.xiaomaju.base;

import java.lang.reflect.Field;

/**
 * @Description 动态SQL工具类
 * @Author @xmj
 */
public class DynamicSQLUtils {

    private static Class<?> clazz = null;

    public static void main(String[] args) {

        String str = "me.xiaomaju.entity.bd.FreqDefDO";

        System.out.println("建表sql----------------------------");
        String creatTableSql = creatTableSql(str);
        System.out.println(creatTableSql);

//        System.out.println("查询sql----------------------------");
//        String selectSql = getSelectSQL(str);
//        System.out.println(selectSql);

//        System.out.println("mybatis添加sql----------------------------");
//        String addSql = getAddSql(str);
//        System.out.println(addSql);

//        System.out.println("mybatis修改sql----------------------------");
//        String updateSQL = getUpdateSQL(str);
//        System.out.println(updateSQL);

    }

    /**
     * 获取mybatis添加SQL
     * @param str
     * @return
     */
    public static String getAddSql(String str){
        try {
            clazz = Class.forName(str);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        TableNameAnnotation tn = clazz.getAnnotation(TableNameAnnotation.class);
        String tableName = tn.value();

        StringBuffer insertStr = new StringBuffer();
        insertStr.append(" insert into "+tableName +"(");

        StringBuffer valuesStr = new StringBuffer();
        valuesStr.append(" values(");

        Field[] fields = clazz.getDeclaredFields();
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            insertStr.append(field.value() + ",");
            valuesStr.append("#{"+field.value() +"},");
        }
        insertStr.deleteCharAt(insertStr.length() - 1);
        insertStr.append(")");
        valuesStr.deleteCharAt(valuesStr.length() - 1);
        valuesStr.append(")");
        return insertStr.toString()+valuesStr.toString();
    }

    /**
     * 获取mybatis修改SQL
     * @param str
     * @return
     */
    public static String getUpdateSQL(String str) {
        StringBuffer sql = new StringBuffer();
        try {
            clazz = Class.forName(str);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        TableNameAnnotation tn = clazz.getAnnotation(TableNameAnnotation.class);
        String tableName = tn.value();
        sql.append(" update "+tableName+" set ");
        Field[] fields = clazz.getDeclaredFields();
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            sql.append(field.value()+"=#{"+field.value() +"},");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(" where id=#{id} " );
        return sql.toString();
    }

    /**
     * 获取建表SQL
     * @param str
     * @return
     */
    public static String creatTableSql(String str) {
        StringBuffer sql = new StringBuffer();
        try {
            clazz = Class.forName(str);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        TableNameAnnotation tn = clazz.getAnnotation(TableNameAnnotation.class);
        String tableName = tn.value();
        sql.append(" DROP TABLE IF EXISTS " + tableName + " ; ");
        sql.append("CREATE TABLE " + tableName + " ( ");
        Field[] fields = clazz.getDeclaredFields();
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            sql.append(field.value() + " " + field.type() + "(" + field.length() + "),");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(")");
        return sql.toString();
    }

    /**
     * 获取查询SQL
     * @param str
     * @return
     */
    public static String getSelectSQL(String str) {
        StringBuffer sql = new StringBuffer();
        try {
            clazz = Class.forName(str);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        TableNameAnnotation tn = clazz.getAnnotation(TableNameAnnotation.class);
        String tableName = tn.value();
        sql.append(" select ");
        Field[] fields = clazz.getDeclaredFields();
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            sql.append(field.value() + " ,");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(" from " + tableName);
        return sql.toString();
    }

}
DynamicSQLUtils

实体类中使用注解:

 

 运行 DynamicSQLUtils 中的 main 方法,将控制台的打印语句放到数据库工具中执行

 

 个人认为可以改进的点:

1、拼接建表语句的时候把列的注释也拼进去(列注解最少要传2个参数)

2、写个JDBC执行SQL(个人还是喜欢用数据库工具)

3、获取指定包下面的所有实体的全类名,批量建表(目前表不是很多,没必要)

 

package me.xiaomaju.base;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description 动态建表SQL工具类 (迭代版2.0)
 * @Author @xmj
 */
public class DynamicSQLUtils2 {

    // 已解析的类和字段信息的缓存
    private static Map<Class<?>, ClassInfo> classInfoCache = new HashMap<Class<?>, ClassInfo>();

    public static void main(String[] args) {

        String fullName = "me.xiaomaju.entity.CiOrderDO";
        Class clazz = getClass(fullName);

        System.out.println("建表sql----------------------------");
        String creatTableSql = creatTableSql(clazz);
        String creatTableSql2 = creatTableSql(fullName);
        System.out.println(creatTableSql);
        System.out.println(creatTableSql2);

//        System.out.println("查询sql----------------------------");
//        String selectSql = getSelectSQL(fullName);
//        System.out.println(selectSql);
//
//        System.out.println("添加sql----------------------------");
//        String addSql = getAddSql(fullName);
//        System.out.println(addSql);
//
//        System.out.println("修改sql----------------------------");
//        String updateSQL = getUpdateSQL(fullName);
//        System.out.println(updateSQL);

    }

    /**
     * 获取指定类的Class对象
     *
     * @param fullName
     * @return
     */
    public static Class getClass(String fullName){
        Class<?> clazz = null;
        try {
            clazz = Class.forName(fullName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clazz;
    }

    /**
     * 获取Class对象的信息
     *
     * @param clazz
     * @return
     */
    public static ClassInfo getClassInfo(Class<?> clazz){
        // 检查缓存中是否存在已解析的类信息
        if (classInfoCache.containsKey(clazz)) {
            ClassInfo classInfo = classInfoCache.get(clazz);
            return classInfo;
        }
        // 反射解析类信息
        ClassInfo classInfo = parseClassInfo(clazz);
        // 存入缓存
        classInfoCache.put(clazz, classInfo);
        return classInfo;
    }

    /**
     * 解析类信息
     *
     * @param clazz
     * @return
     */
    private static ClassInfo parseClassInfo(Class<?> clazz) {
        String tableName = null;//表名
        Field[] fields = null;//列数组
        TableNameAnnotation tn = clazz.getAnnotation(TableNameAnnotation.class);
        tableName= tn.value();
        fields = clazz.getDeclaredFields();
        return new ClassInfo(tableName, fields);
    }

    /**
     * 获取添加SQL的字符串
     *
     * @param fullName
     * @return
     */
    public static String getAddSql(String fullName){
        Class<?> clazz = getClass(fullName);
        return getAddSql(clazz);
    }

    /**
     * 获取添加SQL的字符串
     *
     * @param clazz
     * @return
     */
    public static String getAddSql(Class<?> clazz){
        ClassInfo classInfo = getClassInfo(clazz);
        String tableName = classInfo.getTableName();
        Field[] fields = classInfo.getFields();

        StringBuffer insertStr = new StringBuffer();
        insertStr.append(" insert into "+tableName +"(");

        StringBuffer valuesStr = new StringBuffer();
        valuesStr.append(" values(");

        TableColumnAnnotation field;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            insertStr.append(field.value() + ",");
            valuesStr.append("#{"+field.value() +"},");
        }
        insertStr.deleteCharAt(insertStr.length() - 1);
        insertStr.append(")");
        valuesStr.deleteCharAt(valuesStr.length() - 1);
        valuesStr.append(")");
        return insertStr.toString()+valuesStr.toString();
    }

    /**
     * 获取修改SQL的字符串
     *
     * @param fullName
     * @return
     */
    public static String getUpdateSQL(String fullName) {
        Class<?> clazz = getClass(fullName);
        return getUpdateSQL(clazz);
    }
    /**
     * 获取修改SQL的字符串
     *
     * @param clazz
     * @return
     */
    public static String getUpdateSQL(Class<?> clazz) {
        ClassInfo classInfo = getClassInfo(clazz);
        String tableName = classInfo.getTableName();
        Field[] fields = classInfo.getFields();

        StringBuffer sql = new StringBuffer();
        sql.append(" update "+tableName+" set ");
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            sql.append(field.value()+"=#{"+field.value() +"},");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(" where id=#{id} " );
        return sql.toString();
    }

    /**
     * 获取建表SQL的字符串
     *
     * @param fullName
     * @return
     */
    public static String creatTableSql(String fullName) {
        Class<?> clazz = getClass(fullName);
        return creatTableSql(clazz);
    }

    /**
     * 获取建表SQL的字符串
     *
     * @param clazz
     * @return
     */
    public static String creatTableSql(Class<?> clazz) {
        ClassInfo classInfo = getClassInfo(clazz);
        String tableName = classInfo.getTableName();
        Field[] fields = classInfo.getFields();

        StringBuffer sql = new StringBuffer();
        sql.append(" DROP TABLE IF EXISTS " + tableName + " ;");
        sql.append(" CREATE TABLE " + tableName + " ( ");
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            sql.append(field.value() + " " + field.type() + "(" + field.length() + "),");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(")");
        return sql.toString();
    }

    /**
     * 获取查询SQL的字符串
     *
     * @param fullName
     * @return
     */
    public static String getSelectSQL(String fullName) {
        Class<?> clazz = getClass(fullName);
        return getSelectSQL(clazz);
    }

    /**
     * 获取查询SQL的字符串
     *
     * @param clazz
     * @return
     */
    public static String getSelectSQL(Class<?> clazz) {
        ClassInfo classInfo = getClassInfo(clazz);
        String tableName = classInfo.getTableName();
        Field[] fields = classInfo.getFields();

        StringBuffer sql = new StringBuffer();
        sql.append(" select ");
        TableColumnAnnotation field = null;
        for (Field f : fields) {
            field = f.getAnnotation(TableColumnAnnotation.class);
            if (field == null)
                continue;
            sql.append(field.value() + " ,");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(" from " + tableName);
        return sql.toString();
    }

}
DynamicSQLUtils2
package me.xiaomaju.base;

import java.lang.reflect.Field;

public class ClassInfo {

    private String tableName; //表名
    private Field[] fields; //

    public ClassInfo(String tableName, Field[] fields) {
        this.tableName = tableName;
        this.fields = fields;

    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public Field[] getFields() {
        return fields;
    }

    public void setFields(Field[] fields) {
        this.fields = fields;
    }
}
ClassInfo

 

posted @ 2022-11-10 15:53  请叫我小马驹  阅读(31)  评论(0编辑  收藏  举报