简化开发流程:如何通过 JDBC 自动生成符合 Java 命名规范的实体类
在这篇博客中,我分享了如何通过 Java 和 JDBC 自动生成数据库实体类的过程。通常,手动编写实体类代码既繁琐又容易出错,尤其是在数据库表结构发生变化时,手动更新代码的工作量非常大。为了提高开发效率,我利用 JDBC 连接到数据库,通过 DatabaseMetaData 获取表的元数据,自动化获取表的字段信息(如列名、列类型和列注释)。接着,将数据库中的字段名转换为 Java 的驼峰命名法,并根据字段的类型生成合适的 Java 类型(如 String, Long, Integer 等)。此外,我还将数据库字段的注释转化为 Java 类的 Javadoc 注释,使得生成的实体类更加易于理解和维护。生成的实体类会被保存到指定的包路径中,确保项目结构的整洁。通过这种方式,我们能够轻松地为数据库中的每一张表生成相应的实体类,避免了手动编写实体类的繁琐过程,提高了开发效率,也保证了代码的一致性。文章中还提供了完整的代码示例,方便大家理解并应用到自己的项目中。
public class EntityGenerator {
public static void main(String[] args) {String dbUrl = "jdbc:mysql://:/?useUnicode=true&characterEncoding=utf-8";String dbUsername = "";String dbPassword = "";
// List<String> tableNames = Arrays.asList("kdb_store_profile_info", "kdb_task_factor"); // 要生成实体类的表名List<String> tableNames = Arrays.asList(); // 为空生成该数据库下所有表结构String packageName = "com.***.base"; // 生成实体类的包名generateEntityClasses(dbUrl, dbUsername, dbPassword, tableNames, packageName);}public static void generateEntityClasses(String dbUrl, String dbUsername, String dbPassword, List<String> tableNames, String packageName) {try (Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword)) {// 获取数据库元数据DatabaseMetaData metaData = connection.getMetaData();// 如果tableNames为空,获取数据库 "ymkdb" 中的所有表if (tableNames == null || tableNames.isEmpty()) {tableNames = getTableNamesFromDatabase(metaData, "ymkdb");}// 生成每个表的实体类int generatedTableCount = 0;for (String tableName : tableNames) {generateEntityClass(metaData, tableName, packageName);generatedTableCount++;}// 打印日志,显示总共生成了多少张表System.out.println("总共生成了 " + generatedTableCount + " 张表的实体类。");} catch (SQLException | IOException e) {e.printStackTrace();}
}// 获取 "ymkdb" 数据库中的所有表名
private static List<String> getTableNamesFromDatabase(DatabaseMetaData metaData, String databaseName) throws SQLException {List<String> tableNames = new ArrayList<>();ResultSet resultSet = metaData.getTables(databaseName, null, null, new String[] { "TABLE" });while (resultSet.next()) {String tableName = resultSet.getString("TABLE_NAME");tableNames.add(tableName);}return tableNames;
}// 根据表名生成实体类
public static void generateEntityClass(DatabaseMetaData metaData, String tableName, String packageName) throws SQLException, IOException {ResultSet columns = metaData.getColumns(null, null, tableName, null);// 获取表的注释String tableComment = getTableComment(metaData, tableName);StringBuilder classContent = new StringBuilder();// // 类名转换为首字母大写String className = toClassName(tableName);// 包名和类名classContent.append("package ").append(packageName).append(";\n\n");// 导入语句classContent.append("import lombok.Data;\n");classContent.append("import java.io.Serializable;\n");classContent.append("import java.util.Date;\n\n");// 类定义前添加表名的注释classContent.append("/**\n").append(" * ").append(tableComment != null ? tableComment : tableName).append("\n").append(" */\n");// 类注解和定义classContent.append("@Data\n");classContent.append("public class ").append(className).append(" implements Serializable {\n");// 读取表字段信息while (columns.next()) {String columnName = columns.getString("COLUMN_NAME");String columnType = columns.getString("TYPE_NAME");String columnComment = columns.getString("REMARKS"); // 获取字段的注释// 将数据库字段名转换为驼峰式命名String fieldName = toCamelCase(columnName);String fieldType = getJavaType(columnType);// 添加字段声明classContent.append("\n /**\n").append(" * ").append(columnComment != null ? columnComment : columnName).append("\n").append(" */\n").append(" private ").append(fieldType).append(" ").append(fieldName).append(";\n");}// 结束类定义classContent.append("\n}");// 保存文件String filePath = "src/main/java/" + packageName.replace('.', '/') + "/" + className + ".java";File file = new File(filePath);file.getParentFile().mkdirs();try (FileWriter writer = new FileWriter(file)) {writer.write(classContent.toString());System.out.println("Java 文件生成成功: " + filePath);}
}// 获取表的注释
private static String getTableComment(DatabaseMetaData metaData, String tableName) throws SQLException {ResultSet resultSet = metaData.getTables(null, null, tableName, new String[] { "TABLE" });if (resultSet.next()) {return resultSet.getString("REMARKS");}return null; // 默认返回null
}// 将数据库字段名转换为驼峰命名
private static String toCamelCase(String columnName) {StringBuilder camelCaseString = new StringBuilder();String[] parts = columnName.split("_");for (String part : parts) {if (camelCaseString.length() == 0) {camelCaseString.append(part.toLowerCase());} else {camelCaseString.append(part.substring(0, 1).toUpperCase()).append(part.substring(1).toLowerCase());}}return camelCaseString.toString();
}// 将表名转换为类名
private static String toClassName(String tableName) {StringBuilder className = new StringBuilder();String[] parts = tableName.split("_");for (String part : parts) {className.append(part.substring(0, 1).toUpperCase()).append(part.substring(1).toLowerCase());}return className.toString();
}// 根据数据库字段类型映射到 Java 类型
private static String getJavaType(String sqlType) {switch (sqlType) {case "BIGINT":return "Long";case "VARCHAR":return "String";case "TINYINT":return "Integer";case "INT":return "Integer";case "DATETIME":return "Date";default:return "String"; // 默认返回 String 类型}
}
}
相关文章:
简化开发流程:如何通过 JDBC 自动生成符合 Java 命名规范的实体类
在这篇博客中,我分享了如何通过 Java 和 JDBC 自动生成数据库实体类的过程。通常,手动编写实体类代码既繁琐又容易出错,尤其是在数据库表结构发生变化时,手动更新代码的工作量非常大。为了提高开发效率,我利用 JDBC 连…...
W25Q128存储器详解
可能有很多小伙伴对 W25Q128 感到陌生,说白了它就是一个存储芯片。它是一款高性能、容量较大的闪存存储器芯片,通过 SPI 接口进行通信,适用于各种需要高速、大容量数据存储的场合。常用于嵌入式系统中,作为程序代码存储器或配置数…...
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
11. Vite 配置文件中 CSS 配置(Modules 模块化篇) 由于课程讲的是 vite2 版本,所以我阅读了 vite6 中的文档,下面将结合 css.modules 的接口进行讲解 CSSModulesOptions 接口文档 interface CSSModulesOptions {/*** 用户可以自…...
Everspin代理MR25H10CDFR存储MRAM
RAMSUN提供的MR25H10CDFR是一款具备1,048,576位存储容量的磁阻随机存取存储器(MRAM)设备,由131,072个8位字构成。该设备提供与串行EEPROM和串行闪存兼容的读/写时序,无写延迟,并且其读/写寿命是不受限制的。 与其它串…...
cesium小知识:使用 EntityCollection的方法
EntityCollection 是 Cesium 中用于管理一组 Entity 的集合对象。它提供了一种高效的方式来批量添加、移除和操作多个实体,同时支持事件监听,以便在集合中的实体发生变化时执行特定的逻辑。 下面是如何使用 EntityCollection 的一些基本指导: 创建 EntityCollection 当你…...
Java 日志类库
Java 日志库是最能体现 Java 库在进化中的渊源关系的,在理解时重点理解日志框架本身和日志门面,以及比较好的时间等。要关注其历史渊源和设计(比如桥接),而具体在使用时查询接口即可,否则会陷入 JUL&#x…...
【Unity3D】Particle粒子特效或3D物体显示在UGUI上的方案
目录 一、RawImage Camera RenderTexture方式 (1)扩展知识:实现射线检测RawImage内的3D物体 (2)扩展知识:实现粒子特效显示RawImage上 二、UI摄像机 Canvas(Screen Space - Camera模式)方式 &#…...
有没有检测吸烟的软件 ai视频检测分析厂区抽烟报警#Python
在现代厂区管理中,安全与规范是重中之重,而吸烟行为的管控则是其中关键一环。传统的禁烟管理方式往往依赖人工巡逻,效率低且存在监管死角,难以满足当下复杂多变的厂区环境需求。此时,AI视频检测技术应运而生࿰…...
《鸣潮》游戏运行时弹出“xinput1_3.dll文件缺失”错误的处理方法,“xinput1_3.dll文件缺失”详解!
一、xinput1_3.dll文件的重要性 xinput1_3.dll是DirectX组件中的一个重要文件,它负责处理与Xbox 360控制器相关的输入功能。尽管《鸣潮》可能并不直接依赖于Xbox控制器,但许多现代游戏和应用程序都会调用这个DLL文件来处理各种输入设备的功能。因此&…...
大模型应用—HivisionIDPhotos 证件照在线制作!支持离线、换装、美颜等
HivisionIDPhotos 证件照在线制作!支持离线、换装、美颜等 ivisionIDPhotos 是一款功能强大的开源证件照生成工具。用户只需上传一张人像照片,它就能智能裁剪为一寸、两寸等标准尺寸,同时自动去除背景并渲染新的背景颜色,例如蓝色、白色、红色,还支持渐变色和自定义颜色。…...
解决Ubuntu下无法装载 Windows D盘的问题
电脑安装了 Windows 和 Ubuntu 24.04 后,在Ubuntu系统上装载 D盘,发现无法装载错误如下: Error mounting /dev/nvme0n1p4 at /media/jackeysong/Data: wrong fs type, bad option, bad superblock on /dev/nvme0n1p4, missing codepage or h…...
一体成型电感
一体成型电感是通过铁粉模压成型而成的同封装条件下实现更大的额定电流,且更适合批量自动化生产,较传统绕线电感有成本优势。同时,一体成型电感与磁封胶结构电感相比具有更好的磁屏蔽效果,适合EMI无法调试通过的项目使用。 但一体…...
Reed-Muller(RM)码之编码
点个关注吧! 看了一些中文的博客,RM码没有很详细的资料,所以本文尝试给出推导原理。 推导 RM码由 ( r , m ) ( r , m ) (r,m...
【蓝桥杯——物联网设计与开发】基础模块8 - RTC
目录 一、RTC (1)资源介绍 🔅简介 🔅时钟与分频(十分重要‼️) (2)STM32CubeMX 软件配置 (3)代码编写 (4)实验现象 二、RTC接口…...
聚类算法DBSCAN 改进总结
目录 DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 1. HDBSCAN (Hierarchical DBSCAN) 优点: 安装: 使用实例1 效果失败 使用实例2 3. DBSCAN++ (DBSCAN with Preprocessing) 4. DBSCAN with k-distance 5. Density Peaks Clustering (DP…...
uniapp开发微信小程序实现获取“我的位置”
1. 创建GetLocation项目 使用HBuilder X创建一个项目GetLocation,使用Vue3。 2. 在腾讯地图开放平台中创建应用 要获取位置,在小程序中需要使用腾讯地图或是高德地图。下面以腾讯地图为例。 (1)打开腾讯地图开放平台官方网址:腾讯位置服务 - 立足生态,连接未来 (2)注册…...
java中两个系统进行非对称加密,两个系统的公私钥可以用一套吗?
在非对称加密中,每个参与方应该拥有自己独立的一套公钥和私钥。非对称加密的基础在于公钥和私钥的配对使用:一个密钥用于加密信息,则另一个对应的密钥用于解密信息。具体来说: 如果A要发送一条保密消息给B,那么A会使用…...
无人设备遥控器之定向天线篇
一、定义与功能 定向天线,顾名思义,是通过改变天线的辐射方向,实现信号发射、接收和增强的天线。它可以让信号以更高的功率、更远的距离传输到指定区域,同时也能够降低与周围天线之间的干扰。在无人设备遥控器中,定向天…...
【电路笔记 信号】Metastability 平均故障间隔时间(MTBF)公式推导:进入亚稳态+退出亚稳态+同步器的可靠性计算
这是一个简化的电路分析模型。图2中的典型触发器包括主锁存器、从锁存器和去耦反相器(这个结构类似 主从边沿触发器)。 在亚稳态中,主锁存器的节点A、B的电压电平大致在逻辑“1”(VDD)和“0”(GND)之间。确切的电压电平…...
计算机视觉:原理、分类与应用
计算机视觉是当今科技领域中一个至关重要的分支,它赋予了计算机通过视觉感知和理解世界的能力。简单来说,计算机视觉实现了对图像、视频等视觉数据的分析、处理、识别和理解。这是一个跨学科的研究领域,涉及计算机科学、信息工程、数学、物理…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
