根据类上的注解信息生成创建表的SQL语句

第一步:创建实体类

定义一个实体类,在字段上使用knife4j的接口文档注解@ApiModelProperty注解指定字段名。

package cn.edu.sgu.www.mhxysy.entity.role;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDate;

/**
 * 黑名单
 * @author heyunlin
 * @version 1.0
 */
@Data
@ApiModel
@TableName("black_list")
public class BlackList implements Serializable {
    private static final long serialVersionUID = 18L;

    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "ID")
    private Integer id;

    /**
     * 角色ID
     */
    @ApiModelProperty(value = "角色ID")
    private String roleId;

    /**
     * 角色名
     */
    @ApiModelProperty(value = "角色名")
    private String roleName;

    /**
     * 拉黑理由
     */
    @ApiModelProperty(value = "拉黑理由")
    private String reason;

    /**
     * 拉黑时间
     */
    @ApiModelProperty(value = "拉黑时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate operateTime;
}

第二步:创建一个类保存表的信息

package cn.edu.sgu.www.mhxysy.entity.other;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @author heyunlin
 * @version 1.0
 */
@Data
@ApiModel
public class ClassProperty implements Serializable {
    private static final long serialVersionUID = 18L;

    /**
     * 字段名称
     */
    @ApiModelProperty(value = "表名称")
    private String name;

    /**
     * 字段类型
     */
    @ApiModelProperty(value = "字段类型")
    private String dataType;

    /**
     * 字段注释
     */
    @ApiModelProperty(value = "字段注释")
    private String comment;
}

第三步:Java和数据库的类型映射

 创建Java数据类型和表字段类型的对应关系

package cn.edu.sgu.www.mhxysy.base;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Java数据类型-字段类型
 * @author heyunlin
 * @version 1.0
 */
public class FieldTypes {

    /**
     * 创建一个map,保存Java数据类型和数据库字段类型的映射关系
     */
    private static final Map<Class<?>, String> CLASS_STRING_MAP = new HashMap<>();

    static {
        CLASS_STRING_MAP.put(Integer.class, "int(11) unsigned");
        CLASS_STRING_MAP.put(Date.class, "date");
        CLASS_STRING_MAP.put(LocalDate.class, "date");
        CLASS_STRING_MAP.put(LocalDateTime.class, "datetime");
        CLASS_STRING_MAP.put(String.class, "varchar(255)");
    }

    public static String getType(Class<?> propertyType) {
        return CLASS_STRING_MAP.get(propertyType);
    }

}

第四步:使用反射生成创建表的SQL语句

package cn.edu.sgu.www.mhxysy;

import cn.edu.sgu.www.mhxysy.base.FieldTypes;
import cn.edu.sgu.www.mhxysy.entity.other.ClassProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * springboot测试类
 * @author heyunlin
 * @version 1.0
 */
@SpringBootTest
class MhxysyTests {

    @Test
    void generateTableCreatementSQL() throws ClassNotFoundException {
        String className = "cn.edu.sgu.www.mhxysy.entity.role.BlackList";

        /*
         * 表名
         */
        String tableName = toLower(className);

        Class<?> type = Class.forName(className);

        // 获取类的所有字段信息
        Field[] fields = type.getDeclaredFields();
        List<ClassProperty> list = new ArrayList<>(fields.length);

        for (Field field : fields) {
            ClassProperty classProperty = new ClassProperty();

            // 字段名
            if (field.isAnnotationPresent(TableField.class)) {
                TableField tableField = field.getAnnotation(TableField.class);

                classProperty.setName(tableField.value());
            } else {
                classProperty.setName(toLower(field.getName()));
            }

            // 字段类型
            String fieldType = FieldTypes.getType(field.getType());

            classProperty.setDataType(fieldType);

            // 字段注释
            if (field.isAnnotationPresent(ApiModelProperty.class)) {
                ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);

                classProperty.setComment(apiModelProperty.value());
            }

            list.add(classProperty);
        }

        // 开始拼接SQL语句
        StringBuilder sb = new StringBuilder();

        sb.append("create table ").append(tableName).append("(");

        for (ClassProperty classProperty : list) {
            if (!"serialVersionUID".equals(classProperty.getName())) {
                sb.append(classProperty.getName()).append(" ");
                sb.append(classProperty.getDataType()).append(" ");

                if ("id".equals(classProperty.getName())) {
                    sb.append("primary key ");

                    if (classProperty.getDataType().contains("int")) {
                        sb.append("auto_increment ");
                    }
                }

                sb.append("comment '").append(classProperty.getComment()).append("', ");
            }
        }

        String sql = sb.substring(0, sb.length() - 2) + ")";

        System.out.println(sql);
    }

    /**
     * 驼峰命名转下划线命名
     * @param str 待转换的字符串
     * @return String
     */
    public static String toLower(String str) {
        // 小写和大写紧挨一起的地方加上分隔符_,然后全部转为小写
        str = str.replaceAll("([a-z])([A-Z])", "$1_$2");

        return str.toLowerCase();
    }

}

Java通过反射注解生成对应的SQL语句的步骤如下: 1. 定义注解:首先需要定义一个注解,该注解用于标识字段信息,例如字段名、字段类型、是否为主键等信息。 ``` @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String name(); // 字段名 String type(); // 字段类型 boolean primaryKey() default false; // 是否为主键 } ``` 2. 定义实体类:在实体类的字段上使用上面定义的注解。 ``` public class User { @Column(name = "id", type = "int", primaryKey = true) private int id; @Column(name = "name", type = "varchar") private String name; @Column(name = "age", type = "int") private int age; // 省略getter和setter方法 } ``` 3. 通过反射获取实体类的字段信息:通过反射获取实体类的字段信息,然后读取字段上的注解,获取字段名、字段类型和是否为主键等信息。 ``` public static <T> String generateCreateTableSql(Class<T> clazz) { StringBuilder sb = new StringBuilder(); sb.append("CREATE TABLE IF NOT EXISTS "); sb.append(clazz.getSimpleName()); sb.append("("); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Column.class)) { Column column = field.getAnnotation(Column.class); sb.append(column.name()); sb.append(" "); sb.append(column.type()); if (column.primaryKey()) { sb.append(" PRIMARY KEY"); } sb.append(","); } } sb.deleteCharAt(sb.length() - 1); sb.append(")"); return sb.toString(); } ``` 4. 生成SQL语句:将读取到的字段信息拼接成对应的SQL语句,例如创建表、插入数据、更新数据等。 ``` public static <T> String generateInsertSql(T entity) { StringBuilder sb = new StringBuilder(); sb.append("INSERT INTO "); sb.append(entity.getClass().getSimpleName()); sb.append("("); Field[] fields = entity.getClass().getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Column.class)) { Column column = field.getAnnotation(Column.class); sb.append(column.name()); sb.append(","); } } sb.deleteCharAt(sb.length() - 1); sb.append(") VALUES ("); for (Field field : fields) { if (field.isAnnotationPresent(Column.class)) { field.setAccessible(true); Object value = field.get(entity); if (value instanceof String) { sb.append("'"); sb.append(value); sb.append("'"); } else { sb.append(value); } sb.append(","); } } sb.deleteCharAt(sb.length() - 1); sb.append(")"); return sb.toString(); } ``` 以上就是利用反射注解生成对应的SQL语句的步骤,可以根据需要进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值