springboot+mybatis+新加属性自动加数据库字段

由于最近的项目老是修改,需求变一下,其他同事改了对象,别的同事表里又没有添加该字段,每次更新项目都得去看有没有新添加sql,领导觉得麻烦,让我找找有没有没有什么注解可以标在上面,新加的对象属性自己去生成库。花了一个小时,也终于写好,但不知道怎么样。。。。。

启动时执行的办法

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class TestSql {

    /*
    *
    * tiny
    * 2021/01/14
    * 使用该功能,需要配置tinypath路径(entity全路径)
    * 在新建的字段上面加上@Newfield注解,启动应用时会根据注解进行对新加的属性添加到对应的表中
    *
    * */

    @Autowired
    private SqlSession sqlSession;

    @Value("${tinypath}")
    private String tinypath;
    /*
    *
    * 启动项目加载
    * */
//    @PostConstruct
    public void  mains() throws Throwable{
        /*
        *
        * 通过包名获取到entity文件夹下的所有类名
        *
        * */
        List<String> list=InitSql.getClassName(tinypath,true);
        int len=list.size();
        for (int i = 0; i < len; i++) {
                 /*
                 * 用反射获取到field
                 *
                 * */
                 Class clz=Class.forName(tinypath+"."+list.get(i));
                 Field[] fields=clz.getDeclaredFields();
                 for (Field f:fields) {
                 /*
                 *
                 * 通过反射检查每个实体对象的属性上面是否标有@Newfield我创建的注解
                 * 如果有证明新建属性,数据库没有改字段
                 *
                 * */
                 if(null!=f.getAnnotation(Newfield.class)){

                     if(connection(checktable(list.get(i),f.getName()))){
                         Map<String,String> map=getcoumltype();

                         String sql=addsql(gethump(list.get(i)),gethump(f.getName()),(String)getcoumltype().get(f.getType().getName()));
                         ex(sql);
                     };

                 }
         }


        }
    }

    /*
    *检查该属性是否已经存再数据库
    * */
    public static String checktable(String tablaname,String filedsname){

        StringBuffer stringBuffer=new StringBuffer();

        stringBuffer.append("select table_name from information_schema.columns where table_name="+"'");

        stringBuffer.append(gethump(tablaname)+"' and column_name='");

        stringBuffer.append(filedsname+"'");

        System.out.println(stringBuffer.toString()+"##########");


        return stringBuffer.toString();
    }

    /*
    * 还原驼峰命名
    *
    * */
    public static  String gethump(String classname){
        char[] a=classname.toCharArray();
        StringBuffer stringBuffer=new StringBuffer();

        /*
         *将首字母大写变小写
         * */
        if(a[0]>=65 && a[0]<=90){
            stringBuffer.append((char)(a[0]+32));
        }
        else {
            stringBuffer.append(a[0]);
        }
        for(int i=1;i<a.length;i++){
            /*
            * 大写变小写
            * */
            if(a[i]>=65 && a[i]<=91){stringBuffer.append("_"+(char)(a[i]+32));continue;}
            stringBuffer.append(a[i]);
        }
        return  stringBuffer.toString();
    }

   /*
   * mybatis中直接获取connection执行非映射关系的sql
   *
   * */
   public boolean connection(String sql){
       ResultSet rs=null;
       String str=null;
       Connection connections=null;
        try {
            connections=sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
            Statement s=connections.createStatement();
            rs= s.executeQuery(sql);
            while (rs.next()){
                str =rs.getString("table_name");
            }
            connections.close();
        }catch (SQLException e){

        }
        if(null==str){
            return true;
        }
        return  false;
   }


   private void ex(String sql){
       Connection connections=null;
       try {
           connections=sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
           Statement s=connections.createStatement();

            s.execute(sql);
           connections.close();
       }catch (SQLException e){

       }
   }

   /*
   *
   * 匹配类型
   * */
   public Map getcoumltype(){
       Map<String,String> map=new HashMap<>();
       map.put("int","int(0)");
       map.put("java.lang.Integer","int(0)");
       map.put("double","double(11,2)");
       map.put("float","float(11,2)");
       map.put("char","char(0)");
       map.put("boolean","int(0)");
       map.put("long","bigint(11)");
       map.put("short","tinyint(0)");
       map.put("byte","tinyint(0)");
       map.put("java.lang.String","varchar(255)");
       map.put("java.math.BigDecimal","decimal(12,3)");
       map.put("java.time.LocalDateTime","datetime(0)");
       return  map;
   }

   /*
   *
   *添加字段sql
   *
   * */
   public String addsql(String tablename ,String coumname,String type){

       // ALTER TABLE settings ADD  registerprotocol text COMMENT '邀请协议';
       StringBuffer stringBuffer=new StringBuffer();
       stringBuffer.append("ALTER TABLE  ");
       stringBuffer.append(tablename+"  add ");
       stringBuffer.append(coumname+" ");
       stringBuffer.append(type+"  NULL ;");
       return stringBuffer.toString();

   }


}

通过扫描拿到entiy包下的所有类名

package com.timecolor.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.URL;
import java.util.List;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

@Component
public  class InitSql {



    private static  final Logger log= LoggerFactory.getLogger(InitSql.class);

    public static List<String> getClassName(String packageName) throws IOException {
        return getClassName(packageName, true);
    }

   /*
   *
   *
   * 类似spring包扫描,递归该包下所有的包的类名
   *
   * */
    public static List<String> getClassName(String packageName, boolean childPackage) throws IOException {
        List<String> fileNames = new ArrayList<>();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        String packagePath = packageName.replace(".", "/");
        Enumeration<URL> urls = loader.getResources(packagePath);
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            log.info(url.toString()+"##########");
            File file=new File(url.getFile());
            File[] filelist=file.listFiles();
            for (File f:filelist) {
                if(f.isDirectory()){
                    getClassName(packageName+"."+file.getName());
                }
                else {

                    fileNames.add(f.getName().replace(".class",""));
                }


            } }
        return fileNames;
    }

}

新注解

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

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Newfield {

    String value() default "";
}

主要在对应的属性上标上该注解,启动的时候便自动建数据库字段

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tiny(泰尼)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值