实体类转SQL工具类
主要的目标是简化开发人员在有实体类的情况下时做的重复性工作,提高开发效率。
单个实体类的转换工具类
1.EntityToTableConverter工具类
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;/*** 将实体类转换为MySQL建表语句并输出到文件中的工具类* Author: 木芒果*/
public class EntityToTableConverter {/*** 将实体类转换为MySQL建表语句并输出到文件中** @param clazz 实体类的Class对象* @param filePath 输出文件的路径:如"User.sql",就会在项目根目录下创建一个名为User.sql的文件,文件路径为空则将建表语句输出到控制台* @throws IOException 如果输出文件时发生错误*/public static void convertToCreateTableStatement(Class<?> clazz, String filePath) {try {StringBuilder sb = new StringBuilder();sb.append("DROP TABLE IF EXISTS ");String simpleName = clazz.getSimpleName();sb.append(convertCamelToUnderline(simpleName));sb.append(";\n");sb.append("CREATE TABLE ");sb.append(convertCamelToUnderline(simpleName));sb.append(" (\n");Field[] fields = clazz.getDeclaredFields();for (int i = 0; i < fields.length; i++) {Field field = fields[i];sb.append(" ");String fieldName = field.getName();if (fieldName != "serialVersionUID") {sb.append(convertCamelToUnderline(fieldName));sb.append(" ");sb.append(getColumnType(field.getType()));if (fieldName.equals("id")) { // 如果字段名为"id",则自动设置为主键,自动增长sb.append(" PRIMARY KEY AUTO_INCREMENT");}sb.append(",\n");}}sb.deleteCharAt(sb.lastIndexOf(","));sb.append(");");if (filePath == null) {System.out.println(sb);return;}FileWriter writer = new FileWriter(filePath);writer.write(sb.toString());writer.close();System.out.println("建表语句已输出到" + filePath);} catch (Exception e) {e.printStackTrace();}}/*** 获取字段类型对应的MySQL数据类型** @param fieldType 字段类型* @return MySQL数据类型*/private static String getColumnType(Class<?> fieldType) {if (fieldType == String.class) {return "VARCHAR(255)";} else if (fieldType == int.class || fieldType == Integer.class) {return "INT";} else if (fieldType == long.class || fieldType == Long.class) {return "BIGINT";} else if (fieldType == double.class || fieldType == Double.class) {return "DOUBLE";} else if (fieldType == boolean.class || fieldType == Boolean.class) {return "BOOLEAN";} else if (fieldType == byte[].class) {return "LONGBLOB";} else if (fieldType == java.util.Date.class || fieldType == java.sql.Timestamp.class || fieldType == java.time.LocalDateTime.class) {return "DATETIME";} else if (fieldType == BigDecimal.class) {return "DECIMAL(10,2)"; // 可根据需要调整精度和小数位数}// 如果遇到无法识别的类型,可以根据实际需求进行扩展return "VARCHAR(255)";}/*** 将驼峰命名法转换为下划线命名法** @param camel 驼峰命名法字符串* @return 下划线命名法字符串*/private static String convertCamelToUnderline(String camel) {StringBuilder sb = new StringBuilder();for (int i = 0; i < camel.length(); i++) {char c = camel.charAt(i);if (Character.isUpperCase(c)) {if (i == 0) {sb.append(Character.toLowerCase(c));} else {sb.append('_');sb.append(Character.toLowerCase(c));}} else {sb.append(c);}}return sb.toString();}
}
2.测试
/*** @author 木芒果*/
public class Test {public static void main(String[] args) {//生成sql文件的方式EntityToTableConverter.convertToCreateTableStatement(User.class, "user.sql");//直接输出在控制台的方式EntityToTableConverter.convertToCreateTableStatement(User.class, null);}
}
整个包中的实体类转换工具类
1.EntityToTableConverter工具类
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;/*** 将整个包下的实体类转换为MySQL建表语句* Author: 木芒果*/
public class EntityToTableConverter {/*** 将指定包下的所有实体类转换为MySQL建表语句并输出到文件中** @param packageName 包名* @param filePath 输出文件的路径* @throws IOException 如果输出文件时发生错误*/public static void convertEntitesToCreateTableStatements(String packageName, String filePath) {try {Set<Class<?>> classes = getClassesInPackage(packageName);StringBuilder sb = new StringBuilder();for (Class<?> clazz : classes) {sb.append(convertToCreateTableStatement(clazz));sb.append("\n\n");}if (filePath == null || filePath.isEmpty()) {System.out.println(sb);return;}FileWriter writer = new FileWriter(filePath);writer.write(sb.toString());writer.close();System.out.println("建表语句已输出到" + filePath);} catch (Exception e) {e.printStackTrace();}}/*** 获取指定包下的所有类** @param packageName 包名* @return 类集合*/private static Set<Class<?>> getClassesInPackage(String packageName) {try {Set<Class<?>> classes = new HashSet<>();String packagePath = packageName.replace(".", "/");ClassLoader classLoader = Thread.currentThread().getContextClassLoader();Enumeration<URL> resources = classLoader.getResources(packagePath);while (resources.hasMoreElements()) {URL resource = resources.nextElement();if (resource.getProtocol().equals("jar")) {JarURLConnection jarConnection = (JarURLConnection) resource.openConnection();JarFile jarFile = jarConnection.getJarFile();for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements(); ) {JarEntry entry = entries.nextElement();String entryName = entry.getName();if (entryName.startsWith(packagePath) && entryName.endsWith(".class")) {String className = entryName.substring(0, entryName.length() - 6).replace("/", ".");Class<?> clazz = Class.forName(className);classes.add(clazz);}}} else if (resource.getProtocol().equals("file")) {File packageDir = new File(resource.getFile());if (packageDir.exists()) {File[] files = packageDir.listFiles();for (File file : files) {String fileName = file.getName();String className;if (fileName.endsWith(".class")) {className = packageName + "." + fileName.substring(0, fileName.length() - 6);Class<?> clazz = Class.forName(className);classes.add(clazz);} else if (file.isDirectory()) {String subPackageName = packageName + "." + fileName;classes.addAll(getClassesInPackage(subPackageName));}}}}}return classes;} catch (Exception e) {e.printStackTrace();return null;}}/*** 将实体类转换为MySQL建表语句** @param clazz 实体类的Class对象* @return 建表语句*/private static String convertToCreateTableStatement(Class<?> clazz) {StringBuilder sb = new StringBuilder();sb.append("DROP TABLE IF EXISTS ");String simpleName = clazz.getSimpleName();sb.append(convertCamelToUnderline(simpleName));sb.append(";\n");sb.append("CREATE TABLE ");sb.append(convertCamelToUnderline(simpleName));sb.append(" (\n");Field[] fields = clazz.getDeclaredFields();for (int i = 0; i < fields.length; i++) {Field field = fields[i];sb.append(" ");String fieldName = field.getName();if (fieldName != "serialVersionUID") {sb.append(convertCamelToUnderline(fieldName));sb.append(" ");sb.append(getColumnType(field.getType()));if (fieldName.equals("id")) { // 如果字段名为"id",则自动设置为主键,自动增长sb.append(" PRIMARY KEY AUTO_INCREMENT");}sb.append(",\n");}}sb.deleteCharAt(sb.lastIndexOf(","));sb.append("\n);");return sb.toString();}/*** 获取字段类型对应的MySQL数据类型** @param fieldType 字段类型* @return MySQL数据类型*/private static String getColumnType(Class<?> fieldType) {if (fieldType == String.class) {return "VARCHAR(255)";} else if (fieldType == int.class || fieldType == Integer.class) {return "INT";} else if (fieldType == long.class || fieldType == Long.class) {return "BIGINT";} else if (fieldType == double.class || fieldType == Double.class) {return "DOUBLE";} else if (fieldType == boolean.class || fieldType == Boolean.class) {return "BOOLEAN";} else if (fieldType == byte[].class) {return "LONGBLOB";} else if (fieldType == java.util.Date.class || fieldType == java.sql.Timestamp.class || fieldType == java.time.LocalDateTime.class) {return "DATETIME";} else if (fieldType == BigDecimal.class) {return "DECIMAL(10,2)"; // 可根据需要调整精度和小数位数}// 如果遇到无法识别的类型,可以根据实际需求进行扩展return "VARCHAR(255)";}/*** 将驼峰命名法转换为下划线命名法** @param camel 驼峰命名法字符串* @return 下划线命名法字符串*/private static String convertCamelToUnderline(String camel) {StringBuilder sb = new StringBuilder();for (int i = 0; i < camel.length(); i++) {char c = camel.charAt(i);if (Character.isUpperCase(c)) {if (i == 0) {sb.append(Character.toLowerCase(c));} else {sb.append('_');sb.append(Character.toLowerCase(c));}} else {sb.append(c);}}return sb.toString();}
}
2.测试
public class Test {public static void main(String[] args) {//生成sql文件的方式EntityToTableConverter.convertEntitesToCreateTableStatements("com.mmg.entity", "D:\\test.sql");//直接输出在控制台的方式EntityToTableConverter.convertEntitesToCreateTableStatements("com.mmg.entity", null);}
}
如有更好的想法,可以在评论区交流,完善此工具类!
相关文章:
实体类转SQL工具类
主要的目标是简化开发人员在有实体类的情况下时做的重复性工作,提高开发效率。 单个实体类的转换工具类 1.EntityToTableConverter工具类 import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; import java.math.BigDecimal…...

高端制造业中的通用性超精密3D光学测量仪器
超精密光学3D测量仪器具有高精度、自动化程度高、实时反馈和范围广等优势。它能够实现微米级别的精确测量,能够精确测量产品的尺寸、形状和表面粗糙度等,具有广泛的应用价值和重要意义。 超精密光学3D测量仪器配备多种传感器、控制器和计算机系统&#…...
微信公众号非静默授权获取头像和昵称
要在Vue前端应用程序中实现微信公众号非静默授权获取头像和昵称,您需要遵循以下步骤: 1.在微信公众平台上注册并创建一个公众号。 2.在Vue项目中安装wechat-js-sdk库,该库提供了与微信JS-SDK的交互功能。 npm install wechat-js-sdk --sav…...

Java项目学生管理系统四编辑学生
编辑学生 欢迎阅读本篇博客,今天我们将继续探索Java项目学生管理系统的功能,重点关注学生信息的修改模块。在学生管理系统中,修改学生信息是一个关键操作,通过该功能可以方便地更新学生的个人信息、成绩以及其他相关数据。通过本…...
不同数据库进行同步和增量数据(SQL server 与MySQL数据库为例)
场景 最近在做的一个项目需要将远程服务器的SQL server数据库中表的数据传输到本机的MySQL数据库中,并且远程的SQL server数据库表的数据会实时进行更新,并且差不多是一分钟内传输18条数据,例如现在是2023-12-4 15:09,在15:08这个…...

国内的几款强大的AI智能—AI语言模型
R5Ai智能助手是一款由百度研发的文心一言,它支持gpt4 / gpt-3.5 / claude,也支持AI绘画,每天提供十次免费使用机会,无需魔法。该智能助手具有以下优点:会画画,没有使用次数限制,可以在界面上找到…...
linux下恶意软件的七种反分析技术
7 类主流的 Linux 恶意软件反分析/检测躲避技术 反调试(Anti-Debug): 软件调试是恶意软件分析的常⽤⼿段之⼀,但恶意软件可以通过识别调试器特征,实现⾃⾝恶意⾏为的隐藏,或导致调试失败,从⽽规避分析与检测…...
Spring Security OAuth2 认证服务器自定义异常处理
目录 前言WebResponseExceptionTranslator自定义异常处理1、自定义我们响应实体类2、定义响应结果枚举类3、自定义异常转换类4、配置自定义异常转换器5、测试 前言 Spring Security OAuth2 认证失败的格式如下 {"error": "unsupported_grant_type","…...
selenium环境安装
一、下载安装python 下载python安装python设置python环境变量安装selenium (1)下载python 您可以从Python官方网站(https://www.python.org/downloads/)下载Python。在页面上,您将看到不同版本的Python供您选择。根…...

(C++)和为s的两个数字--双指针算法
个人主页:Lei宝啊 愿所有美好如期而遇 和为S的两个数字_牛客题霸_牛客网输入一个升序数组 array 和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果。题目来自【牛客题霸】https://www.nowcoder.com/practice/390da4f7a…...
鸿蒙(HarmonyOS)应用开发——构建页面(题目答案)
判断题 1.在Column容器中的子组件默认是按照从上到下的垂直方向布局的,其主轴的方向是垂直方向,在Row容器中的组件默认是按照从左到右的水平方向布局的,其主轴的方向是水平方向。 正确(True) 2.List容器可以沿水平方向排列,也可…...

Python基础快速过一遍
文章目录 一、变量及基本概念1、变量2、变量类型3、变量格式化输出4、type()函数5、input()函数6、类型转换函数7、注释 二、Python运算/字符1、算数运算2、比较运算3、逻辑运算4、赋值运算符5、转义字符6、成员运算符 三、判断/循环语句1、if判断语句2、while循环语句3、for循…...

等保测评报价相差很大,里面有什么门道
等保测评报价的差异主要源于以下几点: 服务质量评估标准不同:不同的测评机构在测评过程中所提供的服务范围、深度、细节等方面可能存在差异,因此导致报价有所不同。一些机构可能提供全面且细致的测评服务,致力于提供高质量的等保测…...

MATLAB的rvctools工具箱熟悉运动学【机械臂机器人示例】
1、rvctools下载安装 rvctools下载地址:rvctools下载 截图如下,点击红色箭头指示的“Download Shared Folder” 即可下载 下载之后进行解压,解压到D:\MATLAB\toolbox这个工具箱目录,这个安装路径根据自己的情况来选择,…...

如何精准操作无人机自动停机坪?
无人机自动停机坪通过自主导航和避障功能,实现了无人机的自主降落和起飞,在无人机技术领域起到了至关重要的作用。停机坪不仅仅是无人机的起降平台,还具备自动换电或充电等功能,为无人机的自动化提供了关键支持。为更有效地操作无…...

【蓝桥杯】带分数
带分数 题目要求用一个ab/c的形式得到一个值,而且只能在1~9里面不重复的组合。 可以对1~9进行全排列,然后不断划分区间。 #include<iostream> #include<vector> using namespace std; int st[15]; int num[15]; int res; int n;int calc(i…...
软件工程 课堂测验 选择填空
系统流程图用图形符号表示系统中各个元素,表达了系统中各个元素之间的 信息流动 喷泉模型是一种以用户需求为动力,以 对象 为驱动的模型。 软件生存周期中最长的是 维护 阶段。 变换流的DFD由三部分组成,不属于其中一部分的是 事务中心 软…...

计算机网络的分类
目录 一、按照传输介质进行分类 1、有线网络 2、无线网络 二、按照使用者进行分类 1、公用网 (public network) 2、专用网(private network) 三、按照网络规模和作用范围进行分类 1、PAN 个人局域网 2、LAN 局域网 3、MAN 城域网 4、 WAN 广域网 5、Internet 因特…...

百度收录批量查询工具,免费SEO优化排名工具
拥有一个在搜索引擎中得到良好收录的网站对于个人和企业都至关重要。而百度,作为中国最大的搜索引擎,其收录情况直接影响着网站的曝光度和流量。 百度搜索引擎是中文用户获取信息的重要途径之一。而在这个竞争激烈的网络环境中,了解自己网站…...

select选择框里填充图片,下拉选项带图片
遇到一个需求,选择下拉框选取图标,填充到框里 1、效果展示 2、代码 <el-form-item label"工种图标" class"Form_icon Form_label"><el-select ref"select" :value"formLabelAlign.icon" placeholder&…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...