首页 > 数据库 >使用反射按照类结构生成MySQL表

使用反射按照类结构生成MySQL表

时间:2023-04-14 10:46:12浏览次数:42  
标签:反射 java String 生成 MySQL type public append name

因为一个表对应一个java类,如果java类多了,一个一个创建表太消耗时间了,同时也想造下轮子。加深下对反射和注解的使用

反射和注解把java一切皆对象的思想完全的体现了出来,同时也给java提供了强大的动态性。

主要进行工作的类,可以在里面加上jdbc,就可以实现自动创建表了。

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class AutoCreatTable {
    private String pre  = "CREATE TABLE ";
    private String bodyPre = "(";
    private String bodySub = ")";
    private String NN     = "NOT NULL";
    private String N      = "NULL";
    private String idAuto      = "AUTO_INCREMENT";
    private String PRIMARY_KEY = "PRIMARY KEY";
    private String ENGINE = "ENGINE=InnoDB";

    private String[] havaLength = {"varchar","char","bit"};
    enum rowType {
       Int("int"),Char("char"),Strings("varchar") ;
        String type;
        rowType(String type) {
            this.type = type;
        }
    }
  public   void creatTable(Class<?> table){
      String[] colum;
      ArrayList<String> pkey = new ArrayList<>();
      int i = 0;
       //获取注解
      Table  tableAnnotation = table.getAnnotation(Table.class);
      if (tableAnnotation == null){
          System.out.println("没使用Table注解");
          return;
      }
      String creatSQL;
      creatSQL = pre + tableAnnotation.name();
      System.out.println(creatSQL);
      Field field[] = table.getDeclaredFields();
      colum = new String[field.length];
        for (Field f:field) {

            f.setAccessible(true);
            Annotation[] annotations = f.getDeclaredAnnotations();
            String name = null;
            String type = null;
            String size = null;
            boolean isiD =false;
            boolean isN  = true;
            if (annotations.length == 0){
                return;
            }
            for (Annotation a:annotations) {
                if (a instanceof Column){

                   if (((Column) a).name().equals("")){
                          typeBean tb = getField(f);
                          name = tb.name;
                   }else {
                       name = ((Column) a).name();
                   }
                   if (((Column) a).type().equals("")){
                       typeBean tb = getField(f);
                       type = tb.type;
                   }else {
                        type = ((Column) a).type();
                   }
                   if (((Column) a).length().equals("")){

                       size = "255";
                   }else {
                       size = ((Column) a).length();
                   }
                   isN = ((Column) a).okNull();
                }
                if (a instanceof Id){
                        isiD = true;
                        pkey.add(f.getName());
                }
            }
            String row = creatRow(name,type,isN,isiD,size);
            colum[i] = row;
            i = i+1;
            System.out.println(row);
        }
      StringBuilder body = new StringBuilder(String.join(",",colum))  ;
        System.out.println(body);
        String[] ks = new String[pkey.size()];
        pkey.toArray(ks);
       body.append(",").append(setPRIMARY_KEY(ks)) ;
       creatSQL = creatSQL+"(" + body + ")"+";";
       System.out.println(creatSQL);
    }
    String creatRow(String name,String type,boolean isnull,boolean isID,String size){
        StringBuilder row = new StringBuilder();
        row.append(name).append(" ");
        //设置类型
        if (size!=null){
            if (haveLength(type)){
                row.append(setSize(type,size)).append(" ");
            }else {
                row.append(type).append(" ");
            }

        }else {
            row.append(type).append(" ");
        }
        //设置字段是否为空
        if (isnull){
            //值为true
             row.append(N).append(" ");
        }else {
             row.append(NN).append(" ");
        }
        //设置id
        if (isID){
            row.append(idAuto).append(" ");
        }
        return row.toString();
    }
    String setPRIMARY_KEY(String ...field){
        String fields = String.join(",",field);
        return this.PRIMARY_KEY+bodyPre+fields+bodySub;
    }
    String setSize(String type,String size){
        return  type+bodyPre+size+bodySub;
    }
    typeBean getField(Field field){
        typeBean tb = new typeBean();
        tb.name = field.getName();
        tb.setType(field.getType().toString());
        return tb;
    }
    boolean haveLength(String type){
        Set<String> set = new HashSet<>(Arrays.asList(havaLength));
      return   set.contains(type);
    }

    public void catTable(Class<?>...classes){
        for (Class c:classes
             ) {
            creatTable(c);
        }

    }
class typeBean{
        String name;
        String type;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        if (type.lastIndexOf("String")!=-1){
            type ="varchar" ;
        }

        this.type = type;
    }
}

}

注解:Column 用于标记表的列,也就是类的字段
代码实现:

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

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String name() default "";
    String length() default "";
    String type() default "";
    boolean okNull() default false;
}

主键注解,用于标记主键

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

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {


}

表注解,用于标识表,和包扫描配合在一起,就可以实现自动创建、

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

@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String name();
}

测试一下:定义一个类

@Table(name = "testName")
public class User {
    @Id
    @Column
    int uid;
    @Column
    String name;
    @Column(name = "pass",type = "int",okNull = true)
    String pass;
    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }
}

测试代码:

 @Test
    public void testAutoCreatTable(){
        AutoCreatTable creatTable = new AutoCreatTable();
        creatTable.catTable(User.class);
    }

测试结果:生成的sql语句

image

看上去没什么大问题。可以进行很多拓展,比如支持所有的mysql类型,支持外键等,还可以自动生成简单crud等。但这样的轮子已经有了,就不重复造了。

标签:反射,java,String,生成,MySQL,type,public,append,name
From: https://www.cnblogs.com/aoCat/p/17317582.html

相关文章

  • Fabric生成身份信息文件
    以Ubuntu为例fabric网络架构为3order节点,2org组织,2peer节点1.创建文件并下载二进制文件mkdir3order-2peercd3order-2peer/ 生成身份信息文件需要一些可执行文件,因此我们需要下载fabric的二进制文件,文件路径如下:fabric二进制文件选择适合的fabric版本进行下载,下载完成......
  • mysql笔记
    1.3、数据库分类关系型数据库:(sql)MySql,Oracle,SqlServer,DB2,SQLlite通过表和表之间,行和列之间的关系进行数据的存储,学员信息表,考勤表,。。。。。非关系型数据库:(NoSQL)NotOnlyRedis,MongDB非关系型数据库,对象存储,通过对象的自身属性来决定。DBMS(数据库管理系统)数据库的......
  • MySql查询语句根据年份或月份查询
    1.按年份查询select字段名from表whereyear(字段名)='年份';2.按月份查询:select字段名from表wheremonth(字段名)='月份';3.查本年的某一天(例本年的第6天)select字段名from表wheredayofyear(字段名)='6';......
  • 使用java.util.zip对生成的字节数组输出文件流 进行打包压缩(单个、批量),并返回压缩包
    废话不多说直接上代码 packagegov.test.util;importjava.io.ByteArrayInputStream;importjava.io.ByteArrayOutputStream;importjava.io.IOException;importjava.util.List;importjava.util.Map;importorg.apache.tools.zip.ZipEntry;importorg.apache.tools.zip.Zip......
  • JAVA生成行程单PDF
    JAVA生成行程单PDF一、pom依赖首先引入PDF需要的pom依赖<!--pdf--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version>......
  • Codeforces Round #303 (Div. 2) E. Paths and Trees (最短路+变形最小生成树)
    题目地址:E.PathsandTrees模拟了一场CF,这场实在太水了。。边玩边做的。。最后半分钟交了一发E题。。不幸AK绝杀失败。。。。首先的思路肯定是先求最短路,把可能为最短路的边挑出来,然后第二步我本来写的是直接用无向图的最小生成树,于是绝杀失败。。。后来才发现这样是不行的。......
  • percona-toolkit工具:使用pt-table-checksum检查MySQL主从库的差异
    环境介绍CentOS7.6MySQL5.7PerconaToolkit3.4.0 下载并安装PerconaToolkit从WEB端下载https://www.percona.com/downloads或者通过wget下载[root]#wgethttps://downloads.percona.com/downloads/percona-toolkit/3.5.2/binary/redhat/7/x86_64/percona-toolkit-3.......
  • 快速登录任意mysql脚本
    ######################!/bin/bash#获取输入参数ip=""port=""database=""query=""password_BASE64='WldFeU1HTXhaVFkxWWpnMk56WTFNVFUyTkRObE5qazQK'while[$#-gt0]docase$1in-h)i......
  • docker 容器操作、应用部署、mysql,redis,nginx、迁移与备份、Dockerfile
    容器操作#启动容器dockerstart容器id#停止容器dockerstop容器id#文件拷贝先创建文件mkdir:文件夹vivimtouch:文件#容器的文件copy到宿主机上(不是在容器内部操作)dockercp容器名称:容器目录需要拷贝的文件或目录dockercp......
  • MySQL日志、事务原理 -- undolog、redolog、binlog、两阶段提交
        1.undolog1.1 undolog–原子性   1.2回滚日志,记录数据被修改前的信息,属于逻辑日志什么是逻辑日志?比如我们执行一条delete语句,undolog里边记录的是相反的操作insert记录【相当于存放的是操作逻辑语句,而不是数据】逻辑日志好处比如全表更新,如果......