由于最近的项目老是修改,需求变一下,其他同事改了对象,别的同事表里又没有添加该字段,每次更新项目都得去看有没有新添加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注解,启动应用时会根据注解进行对新加的属性添加到对应的表中** */@Autowiredprivate SqlSession sqlSession;@Value("${tinypath}")private String tinypath;/*** 启动项目加载* */
//    @PostConstructpublic 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 "";
}

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

springboot+mybatis+新加属性自动加数据库字段相关推荐

  1. 注解方式—解决mybatis实体类属性名和数据库字段名不一致问题

    表 tb_brand 实体类 Brand属性名 解决方式一(为表字段取别名) // 根据字段id查询 @Select("select id, brand_name as brandName, ...

  2. java实体类生成mysql表_springboot+mybatis通过实体类自动生成数据库表的方法

    前言 本章介绍使用mybatis结合mysql数据库自动根据实体类生成相关的数据库表. 首先引入相关的pom包我这里使用的是springboot2.1.8.RELEASE的版本 org.mybatis ...

  3. Mybatis中resultMap的作用-解决实体类属性名和数据库字段不一致

    解决实体类属性名和数据库字段不一致 转载于:https://www.cnblogs.com/mww-NOTCOPY/p/10950712.html

  4. 百行代码打造一个DI容器(支持瞬时生命周期、单利生命周期、构造函数自动注入、属性自动注入、字段自动注入)...

    DI注入在.Net平台是非常流行的, 很多项目都用到了,很多开发人员或多或少也用到DI容器了,感觉DI容器很神奇很厉害.本文将通过百行代码展示DI容器的内部核心代码(包括组件的瞬时生命周期.单利生命周 ...

  5. oracle to_char 和 to_date的区别,斜杠和横杠日期转换,mybatis中入参日期,数据库字段是date的写法

    文章目录 斜线日期转换为横线 这样的时间字符串如何转换20201212040506258 ORA-01830: 日期格式图片在转换整个输入字符串之前结束 mybatis中入参日期,数据库字段是date ...

  6. springboot是如何实现配置文件自动加载的呢

    springboot提倡: 约定大于配置 springboot最常见的面试题: 1.springboot是如何实现自动加载配置呢? 2.如何写一个starter呢? 带着问题,我们以mybatis-s ...

  7. springboot数据源oracle,springboot+mybatis中使用多数据源oracle数据库

    写在前面:工作原因,使用的是oracle数据库.由于之前没有接触过,写一篇博客做点笔记. 如果要在springboot项目中连接oracle,首先肯定是要先加入依赖,但是好像在maven仓库里没有or ...

  8. Mybatis实体类属性名与数据库类名不对应的两种解决方法

    在Mybatis开发时,如果 Bean的属性名与数据库的类名不一致时,CRUD将出现问题. 数据库类名 Bean的属性名:(默认) 调整Bean中的属性名:(测试不一致) 此时原有代码将会报错,可预见 ...

  9. java时间空值_Java SpringBoot Mybatis 日期类型属性空值保存出现异常

    日期字段空导致保存异常 数据库端表结构 可以看到字段 bill_date 是 datetime 日期类型,没有设置为 not null,那么如果前段传递来的对象中该属性为空,应该可以保存. HTTP请 ...

最新文章

  1. PCL分割:Conditional Euclidean Clustering官方历程,在自己配置环境上调错
  2. SAP RETAIL MM41 不能将Class分配给商品主数据
  3. 63、使用Timer类来实现定时任务
  4. Linux 系统查看硬件配置信息
  5. 0基础搭建Hadoop大数据处理-初识
  6. matlab批量对图片进行添加椒盐噪声并批量保存到文件夹
  7. 字符串的动态顺序结构(C/C++语言)
  8. (转)在WCF服务的ServiceReferences.ClientConfig中使用相对路径
  9. Delphi如果要追赶C#,最应该做的
  10. 福建省考计算机专业,2020福建省考,这些报考专业问题你清楚吗?
  11. python转json中文乱码_python 序列化成json 乱码问题的解决
  12. [转载]python模块学习---HTMLParser(解析HTML文档元素)
  13. python机器人仿真软件_【RoboDK官方版下载】RoboDK(机器人仿真软件) v4.2.3 官方版-开心电玩...
  14. matlab实训心得,沟通实训心得体会
  15. 游戏陪玩小程序开发制作
  16. 智能车学习----最小二乘法求拟合曲线(中线)的斜率
  17. 全国青少年软件编程等级考试标准 (预备级)1-4级
  18. error:尝试引用已删除的函数或已显式删除函数
  19. 聚美优品根据关键词取商品列表 API
  20. 前端和后端是如何实现交互的

热门文章

  1. vim中文乱码问题的解决
  2. CDS (W2) -- Features, Data, Text Processing
  3. 编译go文件时内部包引用受限的问题(use of internal package /PATH/ not allowed)
  4. 输出200以内所有能被7整除的数
  5. office邮箱不能预览附件问题
  6. 会员动向丨威蓝汽车、深信科创、智行众维等成为ASAM会员
  7. Android 腾讯地图 选点定位,仿微信发送位置
  8. [转载]实时 Java,第 5 部分: 编写和部署实时 Java 应用程序
  9. web前端进阶<7>:3d图像翻转效果
  10. python flask安装教程_pycharm安装flask用什么命令