实体类转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&…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
