当前位置: 首页 > news >正文

实体类转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工具类

主要的目标是简化开发人员在有实体类的情况下时做的重复性工作&#xff0c;提高开发效率。 单个实体类的转换工具类 1.EntityToTableConverter工具类 import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; import java.math.BigDecimal…...

高端制造业中的通用性超精密3D光学测量仪器

超精密光学3D测量仪器具有高精度、自动化程度高、实时反馈和范围广等优势。它能够实现微米级别的精确测量&#xff0c;能够精确测量产品的尺寸、形状和表面粗糙度等&#xff0c;具有广泛的应用价值和重要意义。 超精密光学3D测量仪器配备多种传感器、控制器和计算机系统&#…...

微信公众号非静默授权获取头像和昵称

要在Vue前端应用程序中实现微信公众号非静默授权获取头像和昵称&#xff0c;您需要遵循以下步骤&#xff1a; 1.在微信公众平台上注册并创建一个公众号。 2.在Vue项目中安装wechat-js-sdk库&#xff0c;该库提供了与微信JS-SDK的交互功能。 npm install wechat-js-sdk --sav…...

Java项目学生管理系统四编辑学生

编辑学生 欢迎阅读本篇博客&#xff0c;今天我们将继续探索Java项目学生管理系统的功能&#xff0c;重点关注学生信息的修改模块。在学生管理系统中&#xff0c;修改学生信息是一个关键操作&#xff0c;通过该功能可以方便地更新学生的个人信息、成绩以及其他相关数据。通过本…...

不同数据库进行同步和增量数据(SQL server 与MySQL数据库为例)

场景 最近在做的一个项目需要将远程服务器的SQL server数据库中表的数据传输到本机的MySQL数据库中&#xff0c;并且远程的SQL server数据库表的数据会实时进行更新&#xff0c;并且差不多是一分钟内传输18条数据&#xff0c;例如现在是2023-12-4 15:09&#xff0c;在15:08这个…...

国内的几款强大的AI智能—AI语言模型

R5Ai智能助手是一款由百度研发的文心一言&#xff0c;它支持gpt4 / gpt-3.5 / claude&#xff0c;也支持AI绘画&#xff0c;每天提供十次免费使用机会&#xff0c;无需魔法。该智能助手具有以下优点&#xff1a;会画画&#xff0c;没有使用次数限制&#xff0c;可以在界面上找到…...

linux下恶意软件的七种反分析技术

7 类主流的 Linux 恶意软件反分析/检测躲避技术 反调试&#xff08;Anti-Debug&#xff09;: 软件调试是恶意软件分析的常⽤⼿段之⼀&#xff0c;但恶意软件可以通过识别调试器特征&#xff0c;实现⾃⾝恶意⾏为的隐藏&#xff0c;或导致调试失败&#xff0c;从⽽规避分析与检测…...

Spring Security OAuth2 认证服务器自定义异常处理

目录 前言WebResponseExceptionTranslator自定义异常处理1、自定义我们响应实体类2、定义响应结果枚举类3、自定义异常转换类4、配置自定义异常转换器5、测试 前言 Spring Security OAuth2 认证失败的格式如下 {"error": "unsupported_grant_type","…...

selenium环境安装

一、下载安装python 下载python安装python设置python环境变量安装selenium &#xff08;1&#xff09;下载python 您可以从Python官方网站&#xff08;https://www.python.org/downloads/&#xff09;下载Python。在页面上&#xff0c;您将看到不同版本的Python供您选择。根…...

(C++)和为s的两个数字--双指针算法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 和为S的两个数字_牛客题霸_牛客网输入一个升序数组 array 和一个数字S&#xff0c;在数组中查找两个数&#xff0c;使得他们的和正好是S&#xff0c;如果。题目来自【牛客题霸】https://www.nowcoder.com/practice/390da4f7a…...

鸿蒙(HarmonyOS)应用开发——构建页面(题目答案)

判断题 1.在Column容器中的子组件默认是按照从上到下的垂直方向布局的&#xff0c;其主轴的方向是垂直方向&#xff0c;在Row容器中的组件默认是按照从左到右的水平方向布局的&#xff0c;其主轴的方向是水平方向。 正确(True) 2.List容器可以沿水平方向排列&#xff0c;也可…...

Python基础快速过一遍

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

等保测评报价相差很大,里面有什么门道

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

MATLAB的rvctools工具箱熟悉运动学【机械臂机器人示例】

1、rvctools下载安装 rvctools下载地址&#xff1a;rvctools下载 截图如下&#xff0c;点击红色箭头指示的“Download Shared Folder” 即可下载 下载之后进行解压&#xff0c;解压到D:\MATLAB\toolbox这个工具箱目录&#xff0c;这个安装路径根据自己的情况来选择&#xff0c…...

如何精准操作无人机自动停机坪?

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

【蓝桥杯】带分数

带分数 题目要求用一个ab/c的形式得到一个值&#xff0c;而且只能在1~9里面不重复的组合。 可以对1~9进行全排列&#xff0c;然后不断划分区间。 #include<iostream> #include<vector> using namespace std; int st[15]; int num[15]; int res; int n;int calc(i…...

软件工程 课堂测验 选择填空

系统流程图用图形符号表示系统中各个元素&#xff0c;表达了系统中各个元素之间的 信息流动 喷泉模型是一种以用户需求为动力&#xff0c;以 对象 为驱动的模型。 软件生存周期中最长的是 维护 阶段。 变换流的DFD由三部分组成&#xff0c;不属于其中一部分的是 事务中心 软…...

计算机网络的分类

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

百度收录批量查询工具,免费SEO优化排名工具

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

select选择框里填充图片,下拉选项带图片

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

利用Taotoken的API兼容性将现有基于OpenAI的应用快速迁移上线

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 利用Taotoken的API兼容性将现有基于OpenAI的应用快速迁移上线 对于已经投入开发并依赖OpenAI官方API的应用&#xff0c;切换到新的…...

模函数激活:挑战ReLU的极致简洁方案,为CV与TinyML带来性能突破

1. 项目概述&#xff1a;为什么我们需要重新审视激活函数&#xff1f;在深度学习的工具箱里&#xff0c;激活函数可能是最不起眼&#xff0c;却又最不可或缺的部件。它就像神经网络中的“开关”或“阀门”&#xff0c;决定了每个神经元是否被激活&#xff0c;以及激活的程度。长…...

打造高效命令行天气查询工具:基于KMI/IRM的比利时天气CLI实践

1. 项目概述&#xff1a;一个为终端而生的比利时天气查询工具 如果你和我一样&#xff0c;是个重度命令行用户&#xff0c;同时又对窗外天气是晴是雨有点在意&#xff0c;那你肯定也烦透了为了看个天气预报还得打开浏览器、点开某个天气网站或者解锁手机。这种打断工作流的感觉…...

量子计算威胁下的密码安全:从后量子密码到密码敏捷性实战解析

1. 量子计算&#xff1a;从实验室概念到国家安全的“灰犀牛”最近几年&#xff0c;每当我和业内的同行、安全专家&#xff0c;甚至是投资圈的朋友聊起前沿技术风险&#xff0c;话题总会在某个时刻滑向量子计算。这感觉很像十几年前大家第一次严肃讨论“云计算安全”时一样——一…...

告别CubeMX代码洁癖:教你如何把main()函数挪到自己的.c文件里(STM32F4实战)

重构STM32工程的艺术&#xff1a;将main()迁移到自定义文件的实战指南 每次打开CubeMX生成的工程&#xff0c;看到那个被各种初始化代码塞满的main.c文件&#xff0c;你是否也感到一丝不适&#xff1f;作为一名有追求的嵌入式开发者&#xff0c;我们渴望对项目结构拥有绝对掌控…...

微信消息自动转发:5分钟实现跨群智能消息同步

微信消息自动转发&#xff1a;5分钟实现跨群智能消息同步 【免费下载链接】wechat-forwarding 在微信群之间转发消息 项目地址: https://gitcode.com/gh_mirrors/we/wechat-forwarding 在微信群管理和团队协作中&#xff0c;你是否经常需要将重要消息手动转发到多个群聊…...

解决 Claude Code 频繁封号问题之转向 Taotoken 稳定服务

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 解决 Claude Code 频繁封号问题之转向 Taotoken 稳定服务 对于依赖 Claude Code 进行开发的工程师而言&#xff0c;账号访问权限的…...

OCR实战三阶段:检测、识别、结构化全流程解析

1. 这不是“把图片变文字”那么简单&#xff1a;OCR背后的真实战场光学字符识别&#xff08;OCR&#xff09;这三个字母&#xff0c;很多人第一反应是“截图转文字”“PDF复制不了&#xff1f;丢给OCR试试”。但如果你真这么想&#xff0c;就等于站在手术室门口说“不就是动刀子…...

gqty:零配置强类型GraphQL客户端,颠覆传统开发体验

1. 项目概述&#xff1a;一个颠覆性的GraphQL客户端方案如果你在过去几年里深度参与过前端开发&#xff0c;尤其是与GraphQL API打交道&#xff0c;那么你一定体会过那种“甜蜜的负担”。GraphQL带来的数据查询自由度和类型安全让人着迷&#xff0c;但随之而来的客户端状态管理…...

5分钟极简安装:免费Ghidra逆向工程工具完整配置指南

5分钟极简安装&#xff1a;免费Ghidra逆向工程工具完整配置指南 【免费下载链接】ghidra_installer Helper scripts to set up OpenJDK 11 and scale Ghidra for 4K on Ubuntu 18.04 / 18.10 项目地址: https://gitcode.com/gh_mirrors/gh/ghidra_installer 你是否曾因复…...