实体类转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&…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...