根据实体类生成表生成语句

新接手一个项目,没有数据库文件,并且Entity实体类放在不同的文件路径中,写了个转换工具,如下:

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.annotations.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static cn.hutool.core.io.FileUtil.newFile;/*** 根据实体类生成表生成语句*/
@Slf4jclass EntityToTablesUtil {/*** java类型与数据库类型映射*/public static HashMap<String,String> javaPropertyMap = new HashMap<>(16, 1);static {javaPropertyMap.put("integer", " int(8) ");javaPropertyMap.put("int", " int(8) ");javaPropertyMap.put("short", " tinyint(4) ");javaPropertyMap.put("byte", " tinyint(4) ");javaPropertyMap.put("long", " bigint(11) ");javaPropertyMap.put("bigdecimal", " decimal(20,4) ");javaPropertyMap.put("double", " double(10,2) ");javaPropertyMap.put("float", " float(10,2) ");javaPropertyMap.put("boolean", " tinyint(4) ");javaPropertyMap.put("timestamp", " datetime ");javaPropertyMap.put("date", " datetime ");javaPropertyMap.put("localdatetime", " datetime ");javaPropertyMap.put("string", " varchar(255) ");}public static void main(String[] args) {// 生成sql的文件夹String filePath = "E:\\";// 实体类所在的package在磁盘上的绝对路径String packageName1 = "D:\\4.program\\17\\tourdataplatform\\src\\main\\java\\com\\ichinae\\base\\mgr\\data\\entity";// 项目中实体类的路径String prefix1 = "com.ichinae.base.mgr.data.entity.";StringBuilder sqlStr1 = buildSql(packageName1, prefix1);// 实体类所在的package在磁盘上的绝对路径String packageName2 = "D:\\4.program\\17\\tourdataplatform\\src\\main\\java\\com\\ichinae\\base\\mgr\\data\\entity\\datareport";// 项目中实体类的路径String prefix2 = "com.ichinae.base.mgr.data.entity.datareport.";StringBuilder sqlStr2 = buildSql(packageName2, prefix2);// 实体类所在的package在磁盘上的绝对路径String packageName3 = "D:\\4.program\\17\\tourdataplatform\\src\\main\\java\\com\\ichinae\\base\\mgr\\data\\entity\\ticketstatistics\\task";// 项目中实体类的路径String prefix3 = "com.ichinae.base.mgr.data.entity.ticketstatistics.task.";StringBuilder sqlStr3 = buildSql(packageName3, prefix3);assert sqlStr1 != null;sqlStr1.append(sqlStr2).append(sqlStr3);System.out.println(sqlStr1);
//        sqlToFile(sqlStr1.toString(), filePath + "work.sql");}private static StringBuilder buildSql(String packageName, String prefix) {StringBuilder sqlStr = new StringBuilder();// 获取包下的所有类名称String className = "";List<String> list = getAllClasses(packageName);if (CollUtil.isEmpty(list)) {return null;}for (String str : list) {try {className = prefix + str.substring(0, str.lastIndexOf("."));String sql = generateSql(className, packageName,str);sqlStr.append("\n ").append(sql);}catch (Exception e) {e.printStackTrace();log.error("错误类:{}", str);}}return sqlStr;}/*** 根据实体类生成建表语句* @param className 全类名*/public static String generateSql(String className,String packPath,String javaName){try {Class<?> clz = Class.forName(className);String className1 = dealSubLine(clz.getSimpleName());//处理classNameclassName = className1.substring(1);//获取表中文名称String tableCommit = getTableName(packPath+"\\"+javaName);String tableCommitVarchar=" COMMENT='"+tableCommit+"';";Field[] fields = clz.getDeclaredFields();StringBuilder column = new StringBuilder();String primaryKey = null;List<String> colList = new ArrayList<>();for (Field f : fields) {String dealName;if(!"serialVersionUID".equals(f.getName())){//获取注解名称String commitVachr = "";ApiModelProperty apiModelProperty = f.getAnnotation(ApiModelProperty.class);if(Objects.nonNull(apiModelProperty)){String filedChineseName = apiModelProperty.value();commitVachr=" COMMENT '"+filedChineseName+"',";}else{commitVachr=" COMMENT '',";}//驼峰转换dealName = dealSubLine(f.getName());if (colList.contains(dealName)) {continue;}String filedTypeName = f.getType().getName();String suffix = filedTypeName.substring(filedTypeName.lastIndexOf(".")+1);if ("List".equals(suffix)) {continue;}String dataType = javaPropertyMap.get(suffix.toLowerCase());if (StringUtils.isBlank(dataType)) {log.error("字段类型为空:{}", suffix);continue;}TableId tableId = f.getAnnotation(TableId.class);if(Objects.nonNull(tableId)){column.append(" \n `").append(dealName).append("`").append(dataType).append("NOT NULL AUTO_INCREMENT").append(commitVachr);primaryKey = dealName;}else {column.append(" \n `").append(dealName).append("`").append(dataType).append(" DEFAULT NULL ").append(commitVachr);}colList.add(dealName);}}return "\n DROP TABLE IF EXISTS `" + className + "`; " +" \n CREATE TABLE `" + className + "`  (" + " \n " + column +" \n PRIMARY KEY (`" + primaryKey + "`) " +" \n ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci " +tableCommitVarchar;} catch (ClassNotFoundException e) {log.debug("该类未找到!");return null;}}/*** 获取包下的所有类名称,获取的结果类似于 XXX.java* @param packageName 包路径* @return 类List*/public static List<String> getAllClasses(String packageName){List<String> classList = new ArrayList<>();File f = new File(packageName);if (!f.exists() || !f.isDirectory()) {throw new RuntimeException("包路径未找到!");}File[] files = f.listFiles();assert files != null;for (File file : files) {if (file.isFile()) {classList.add(file.getName());}}log.info("包路径中类有:{}个", classList.size());return classList;}/*** 将string 写入sql文件* @param str sql* @param path sql打印路径*/public static void sqlToFile(String str, String path){byte[] sourceByte = str.getBytes();try {//文件路径(路径+文件名)File file = new File(path);//文件不存在则创建文件,先创建目录if (!file.exists()) {File dir = new File(file.getParent());dir.mkdirs();file.createNewFile();}//文件输出流用于将数据写入文件FileOutputStream outStream = new FileOutputStream(file);outStream.write(sourceByte);outStream.flush();//关闭文件输出流outStream.close();System.out.println("生成成功");} catch (Exception e) {e.printStackTrace();}}private static String dealSubLine(String str){//String str = "areaObjectCode";StringBuilder ss = new StringBuilder();char[] charArray = str.toCharArray();for (int i = 0; i < charArray.length; i++) {if (charArray[i] >= 'A' && charArray[i] <= 'Z') {ss.append("_").append(charArray[i]);} else {ss.append(charArray[i]);}}return ss.toString().toLowerCase();}/*** 获取表中文名称*/@SneakyThrowsprivate static String getTableName(String filePath){File f= newFile(filePath);InputStreamReader read= new InputStreamReader( new FileInputStream(f), StandardCharsets.UTF_8);BufferedReader reader= new BufferedReader(read);String line;while((line=reader.readLine())!= null){//判断字符串包含中文切读取中文char[] t = line.toCharArray();for (char a : t) {// 判断是否为汉字字符if (Character.toString(a).matches("[\\u4E00-\\u9FA5]+")) {// System.out.print("字符串含有汉字");// System.out.print(line.replaceAll("[^\\u4e00-\\u9fa5]", ""));//获取中文名称String tableChineseName =line.replaceAll("[^\\u4e00-\\u9fa5]", "");return tableChineseName;}}}return null;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/83484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(JavaEE)(多线程案例)线程池 (简单介绍了工厂模式)(含经典面试题ThreadPoolExector构造方法)

线程诞生的意义&#xff0c;是因为进程的创建/销毁&#xff0c;太重了&#xff08;比较慢&#xff09;&#xff0c;虽然和进程比&#xff0c;线程更快了&#xff0c;但是如果进一步提高线程创建销毁的频率&#xff0c;线程的开销就不能忽视了。 这时候我们就要找一些其他的办法…

Ansible之Playbook的任务控制

一&#xff09;Ansible 任务控制基本介绍 这⾥主要来介绍PlayBook中的任务控制。 任务控制类似于编程语⾔中的if … 、for … 等逻辑控制语句。 这⾥我们给出⼀个实际场景应⽤案例去说明在PlayBook中&#xff0c;任务控制如何应⽤。 在下⾯的PlayBook中&#xff0c;我们创建了…

pnpm入门教程

一、概述 1、更小 使用 npm 时&#xff0c;依赖每次被不同的项目使用&#xff0c;都会重复安装一次。 而在使用 pnpm 时&#xff0c;依赖会被存储在内容可寻址的存储中。 2、更快 依赖解析。 仓库中没有的依赖都被识别并获取到仓库。目录结构计算。 node_modules 目录结构是…

什么是GPT磁盘?介绍GPT(GUID 分区表)磁盘及其优势!

GPT概述 GPT磁盘是什么意思&#xff1f;GPT是全局唯一标识符分区表&#xff08;GUID Partition Table&#xff09;的简称&#xff0c;它是硬盘分区表结构的一个标准模式。在我们深入了解GPT磁盘的特性之前须知&#xff0c;MBR磁盘的分区信息直接保存在主引导记录&#xff0…

【探索C语言中VS调试技巧】:提高效率和准确性

文章目录 前言1. 什么是bug&#xff1f;2. 调试是什么&#xff1f;有多重要&#xff1f;2.1 调试是什么&#xff1f;2.2 调试的基本步骤2.3 Debug和Release的介绍 3. Windows环境调试介绍3.1 调试环境的准备3.2 学会快捷键3.3 调试的时候查看程序当前信息3.3.1 查看临时变量的值…

【C++】动态内存管理 ③ ( C++ 对象的动态创建和释放 | new 运算符 为类对象 分配内存 | delete 运算符 释放对象内存 )

文章目录 一、C 对象的动态创建和释放1、C 语言 对象的动态创建和释放 的方式2、C 语言 对象的动态创建和释放 的方式 二、代码示例 - 对象的动态创建和释放 一、C 对象的动态创建和释放 使用 C 语言中的 malloc 函数 可以为 类对象 分配内存 ; 使用 free 函数可以释放上述分配…

RK3568-drm框架

1 DRM 概述 DRM 全称是 Direct Rendering Manager,进行显示输出管理、buffer 分配、帧缓冲。对应 userspace 库 为 libdrm,,libdrm 库提供了一系列友好的控制封装,使用户可以方便的进行显示的控制和 buffer 申请。DRM 的设备节点为 "/dev/dri/cardX", X 为 0-15…

Android 富文本SpannableString

一、认识SpannableString 为什么要使用富文本 在Android开发中&#xff0c;有很多UI会画出一些特别炫酷的界面出来&#xff0c;比如一个字符串里有特殊的字会有其他颜色并加粗、变大变小、插入小图片、给某几个文字添加边框&#xff0c;如果我们使用笨办法用几个TextView或者Im…

单片机第三季-第三课:STM32开发板原理图、配置、浮点运算单元

目录 1&#xff0c;开发板原理图 2&#xff0c;浮点运算单元&#xff08;FPU&#xff09; 1&#xff0c;开发板原理图 课程视频比较早&#xff0c;介绍了三款开发板。观看视频时用的开发板说和51单片机共板的STM32核心板&#xff0c;将51单片机从底座拆下来后&#xff0c;安…

avi怎么转换成视频?

avi怎么转换成视频&#xff1f;在我们日常使用的视频格式中&#xff0c;AVI是一种常见且经常被使用的音频视频交叉格式之一。它的优点之一是占用的存储空间相对较小&#xff0c;但也明显存在着画质损失的缺点。虽然AVI格式的视频在某种程度上也很常见&#xff0c;但与最常见的M…

zabbix的原理与安装

一、Zabbix介绍 1、zabbix 是什么&#xff1f; zabbix是一个开源的IT基础监控软件&#xff0c;能实时监控网络服务&#xff0c;服务器和网络设备的状态&#xff0c;如网络使用&#xff0c;CPU负载、磁盘空间等&#xff0c;主要是包括数据的收集、报警和通知的可视化界面zabbi…

需求文档书写规范

需求文档的格式应该清晰易读&#xff0c;便于阅读和理解&#xff0c;应该有一个明确的标题和编号。需求文档应该包含以下内容&#xff1a;背景、目的、需求、功能、性能、接口、安全、测试和质量保证等。需求应该明确具体&#xff0c;避免歧义&#xff0c;同时考虑用户的需求和…

VHOST-SCSI代码分析(1)VHOST SCSI设备模拟

VHOST SCSI设备的模拟是由QEMU和HOST共同实现的&#xff0c;QEMU模拟VHOST SCSI设备配置空间等&#xff0c;而对于虚拟机通知HOST和HOST通知虚拟机机制由HOST内核实现。 在QEMU中VHOST SCSI设备继承关系如下&#xff1a; 其它设备以及对应class_init函数和realize具现化实现与V…

LLM微调(一)| 单GPU使用QLoRA微调Llama 2.0实战

最近LLaMA 2在LLaMA1 的基础上做了很多优化&#xff0c;比如上下文从2048扩展到4096&#xff0c;使用了Grouped-Query Attention&#xff08;GQA&#xff09;共享多头注意力的key 和value矩阵&#xff0c;具体可以参考&#xff1a; 关于LLaMA 2 的细节&#xff0c;可以参考如下…

zotero通过DOI快速导入文献

之前我经常采用两种方式导入文献&#xff1a; &#xff08;1&#xff09;下载PDF&#xff0c;然后拖入zotero 这种方法比较费时间&#xff0c;有些文献无法下载pdf &#xff08;2&#xff09;通过google scholar检索文献&#xff0c;然后点击引用——EndNote&#xff0c;chorme…

Kotlin中函数的基本用法以及函数类型

函数的基本用法 1、函数的基本格式 2、函数的缺省值 可以为函数设置指定的初始值&#xff0c;而不必要传入值 private fun fix(name: String,age: Int 2){println(name age) }fun main(args: Array<String>) {fix("张三") }输出结果为&#xff1a;张三2 …

WebGL层次模型——多节点模型

目录 多节点模型 MultiJointModel中的层次结构 控制各部件旋转角度的变量 示例程序——共用顶点数据&#xff0c;通过模型矩阵缩放实现&#xff08;MultiJointModel.js&#xff09; MultiJointModel.js&#xff08;按键响应部分&#xff09; MultiJointModel.js&#x…

刷题日记——将x减到0的最小操作数

将x减到0的最小操作数 题目链接&#xff1a;https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/ 题目解读 题目要求移除元素总和等于参数x&#xff0c;这道题给我的第一感觉就是从数组的两边入手&#xff0c;对数据进行加和删除&#xff0c;但是这里有一…

Python Excel 操作 Openpyxl 模块笔记

xlsx 是 Microsoft Excel 使用的开放 XML 电子表格文件格式的文件扩展名。xlsm 文件支持宏。xlsx 是专有的二进制格式&#xff0c;而 xlsx 是基于 Office Open XML 格式的。 Excel 文件处理 1. 打开 excel 文件 import openpyxl book openpyxl.load_workbook(sample.xlsx)2…

滚雪球学Java(24):Java反射

&#x1f3c6;本文收录于「滚雪球学Java」专栏&#xff0c;专业攻坚指数级提升&#xff0c;助你一臂之力&#xff0c;带你早日登顶&#x1f680;&#xff0c;欢迎大家关注&&收藏&#xff01;持续更新中&#xff0c;up&#xff01;up&#xff01;up&#xff01;&#xf…