AutoTable, Hibernate自动建立表替代方案

痛点

之前一直使用JPA为主要ORM技术栈,主要是因为Mybatis没有实体逆向建表功能。虽然Mybatis有从数据库建立实体,但是实际应用却没那么美好:当实体变更时,往往不会单独再建立一个数据库重新生成表,然后把表再逆向为实体。最终的结果往往是维护一份数据库SQL,再同时维护一份实体对象,两者没有自动建立关联。

方案

如果能够自动建立表,并自动维护系统初始的数据,该有多方便啊。

笔者实际的经验,十年前已经实现Hibernate自动建表+DBUnit自动初始数据(包括图片和相对数据,可见笔者其它文章)。

然而世界在发展,痛点终究有大牛出来解决,在Mybatis领域,最近出现了一个的替代解决方案:MybatisPlusExt,简称MPE。其中的自动建表已被MPE作者单独一个项目处理,叫做AutoTableAuto Table)自动维护表结构icon-default.png?t=N7T8https://autotable.tangzc.com/

迁移步骤

配置文件

autotable也有springboot starter。重新建表的逻辑,也有JAP类似的参数,因此,很容易可以进行迁移,改动点如下:

JPA

spring:jpa:database-platform: ${app.dataSource.hibernateDialect}generate-ddl: falseshow-sql: falseopen-in-view: falseproperties:hibernate.jdbc.time_zone: ${app.timeZone:GMT+8}

以及config里的配置Bean:

	@Value("${app.init.mode:none}")private String initMode;@Bean@ConfigurationProperties(prefix = "spring.datasource")public JpaVendorAdapter jpaVendorAdapter() {return new HibernateJpaVendorAdapter();}@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){LocalContainerEntityManagerFactoryBean bean=new LocalContainerEntityManagerFactoryBean();      bean.setDataSource(dataSource);bean.setPackagesToScan(new String[] {"org.ccframe.subsys.*.domain.entity"});bean.setJpaVendorAdapter(jpaVendorAdapter);bean.getJpaPropertyMap().put("hibernate.hbm2ddl.auto",initMode);return bean;}

AutoTable

先导入starter依赖:


implementation ("com.tangzc:auto-table-spring-boot-starter:1.7.4") // 自动建表

然后书写格式:

auto-table:show-banner: falsemode: ${app.init.mode}model-package: org.ccframe.subsys.*.domain.entityindex-prefix: IDX_

Entity实体

以一个典型的带普通和Unique索引的实体User为例:

JPA

JPA+Hibernate方案

@Entity
@Table(name = "SYS_USER", indexes = {@Index(columnList = "USER_MOBILE"),@Index(columnList = "USER_EMAIL"),
}, uniqueConstraints = {@UniqueConstraint(columnNames = {"PLATFORM_ID","LOGIN_ID","USER_PSW"}),
})
@Getter
@Setter
@ToString
public class User extends BaseEntity{private static final long serialVersionUID = 6662916002685367792L;public static final String USER_ID = "userId";public static final String PLATFORM_ID = "platformId";public static final String LOGIN_ID = "loginId";public static final String USER_HEAD_PICT_ID = "userHeadPictId";public static final String USER_NAME = "userName";public static final String USER_PSW = "userPsw";public static final String USER_MOBILE = "userMobile";public static final String USER_EMAIL = "userEmail";public static final String USER_STATUS_CODE = "userStatusCode";public static final String IF_ADMIN = "ifAdmin";public static final String ROLE_CODE_STR = "roleCodeStr";@Id@GenericGenerator(name = "userId", strategy = "org.ccframe.commons.base.RedisIDGenerator")@GeneratedValue(generator = "userId")@Column(name = "USER_ID", nullable = false, length = 10)private Integer userId;@Column(name = "PLATFORM_ID", nullable = false, length = 10)private Integer platformId;@Column(name = "LOGIN_ID", nullable = false, length = 38)@Field(type = FieldType.Keyword)private String loginId;@Column(name = "USER_HEAD_PICT_ID", nullable = true, length = 10)private java.lang.Integer userHeadPictId;@Column(name = "USER_NAME", nullable = false, length = 32)private String userName;@Column(name = "USER_PSW", nullable = false, length = 128)private String userPsw;@Column(name = "USER_MOBILE", nullable = true, length = 17)private String userMobile;@Column(name = "USER_EMAIL", nullable = true, length = 70)private String userEmail;@Column(name = "IF_ADMIN", nullable = false, length = 2)@Field(type = FieldType.Keyword)private String ifAdmin;@Column(name = "USER_STATUS_CODE", nullable = false, length = 2)private String userStatusCode;@Column(name = "ROLE_CODE_STR", nullable = false, length = 80)private String roleCodeStr;
}

AutoTable

mybatis-plus + autotable的方案

@TableName("SYS_USER")
@AutoTable("SYS_USER")
@TableIndex(name = "UK66q7srks5eylhocxej5gs68mb", type= IndexTypeEnum.UNIQUE, fields = {"tenantId","loginId","userPsw"})
@TableIndex(name = "IDXbby41q9neesp2i6hatmlud01b", fields = "userMobile")
@TableIndex(name = "IDXhjkdbn8wxvwcdp7ohh7dch6i1", fields = "userEmail")
@Getter
@Setter
@ToString
public class User extends BaseEntity{private static final long serialVersionUID = 6662916002685367792L;public static final String USER_ID = "userId";public static final String TENANT_ID = "tenantId";public static final String LOGIN_ID = "loginId";public static final String USER_AVATAR = "userAvatar";public static final String USER_NAME = "userName";public static final String USER_PSW = "userPsw";public static final String USER_MOBILE = "userMobile";public static final String USER_EMAIL = "userEmail";public static final String USER_STATUS_CODE = "userStatusCode";public static final String IF_ADMIN = "ifAdmin";public static final String ROLE_CODE_STR = "roleCodeStr";@TableId(type = IdType.ASSIGN_ID)@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 120) @ColumnNotNullprivate Long userId;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 38) @ColumnNotNull@Field(type = FieldType.Keyword)private String loginId;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 48) @ColumnNotNullprivate String userAvatar;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 32) @ColumnNotNullprivate String userName;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 128) @ColumnNotNullprivate String userPsw;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 17)private String userMobile;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 70)private String userEmail;@Field(type = FieldType.Keyword)@ColumnType(value = MysqlTypeConstant.CHAR, length = 1)private String ifAdmin;@ColumnType(value = MysqlTypeConstant.CHAR, length = 1)private String userStatusCode;@ColumnType(value = MysqlTypeConstant.VARCHAR, length = 80)private String roleCodeStr;}

总结

AutoTable能够很好的兼容JPA的格式,实现自动建表的迁移。

但是有几个注意点:

1)索引需要进行命名,hibernate的是采用自动前缀+25位字符来自动实现索引的命名,我们不用去关心索引的名称。而迁移到AutoTable需要去起个不重复的名字。这个问题不大

2)hibernate采用方言的模式,可以兼容大部分数据库。而AutoTable的字段类型,需要指定数据库类型,如果要切换数据库,需要做实体代码定义的改动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1412827.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

一分钱不花从HTTP升级到HTTPS

HTTP升级到HTTPS是一个涉及安全性和技术实施的过程,主要目的是为了提升网站数据传输的安全性,防止数据被窃取或篡改。以下是一些关于从HTTP升级到HTTPS的技术性要点和步骤概述,结合上述信息资源: 一、理解HTTPS的重要性 HTTPS (…

【ONE·基础算法 || 回溯和剪枝(暴搜/深搜)】

总言 主要内容:编程题举例,熟悉理解回溯剪枝类题型(如何画决策树,如何使用深搜进行递归,如何运用剪枝,如何在一维数组/二维数组中使用)。 文章目录 总言1、回溯和剪枝2、全排列(med…

学习Rust的第29天: cat in Rust

今天即将是这个系列的最后一次内容,我们正在catRust 中从 GNU 核心实用程序进行重建。cat用于将文件内容打印到STDOUT.听起来很容易构建,所以让我们开始吧。 GitHub 存储库:GitHub - shafinmurani/gnu-core-utils-rust 伪代码 function read(…

【MySQL】第一次作业

【MySQL】第一次作业 1、在官网下载安装包2、解压安装包,创建一个dev_soft文件夹,解压到里面。3、创建一个数据库db_classes4、创建一行表db_hero5、将四大名著中的常见人物插入这个英雄表 写一篇博客,在window系统安装MySQL将本机的MySQL一定…

词法分析、语法分析

词法分析器 词法分析的任务是:从左往右逐个字符地扫描源程序,产生一个个的单词符号。也就是说,它会对输入的字符流进行处理,再输出单词流。执行词法分析的程序即词法分析器,或者说扫描器。 词法分析的成果就是由一系…

【AI】openai-quickstart 运行Jupyter Lab

openai-quickstart/openai_api /README-CN.md 【AI】指定python3.10安装Jupyter Lab 可以安装3.10版本的jupyter lab 但是直接输入命令无法启动 突然发现自己电脑2023年安装过anaconda3 C:\ProgramData\anaconda3\python.exe C:\ProgramData\anaconda3\cwp.py C:\ProgramData…

【软件测试理论003】软件开发与测试模型

目录 1 软件开发模型 1.1 瀑布模型 测试的切入点及其挑战 瀑布模型的优点 瀑布模型的缺点 1.2 快速原型模型 实施步骤 快速原型模型优点 快速原型模型缺点 1.3 螺旋模型 螺旋模型的优点 螺旋模型的缺点 1.4 敏捷开发模型 价值观 敏捷原则 认识敏捷开发Scrum S…

【深度优先搜索 图论 树】2872. 可以被 K 整除连通块的最大数目

本文涉及知识点 深度优先搜索 图论 树 图论知识汇总 LeetCode 2872. 可以被 K 整除连通块的最大数目 给你一棵 n 个节点的无向树,节点编号为 0 到 n - 1 。给你整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] [ai, bi] 表示树中节点…

【微服务】配置管理

Nacos配置管理 配置管理配置共享配置热更新 配置管理 将微服务集群中常用,经常变化的配置都写到一个独立的配置文件微服务中进行统一管理 配置共享 在Nacos的界面当中进行配置管理,在配置列表中添加配置 比如各个服务中的jdbc的连接配置: …

并发-线程停止、中断之最佳实践

目录 前言 原理介绍(使用interrupt进行通知,而不是强制停止) Thread.interrupt() 最佳实践 小结(如何停止线程?) 前言 Java 中的线程中断是一种线程间的协作模式通过设置线程的中断标志并不能直接终止该线程的执行&#xff…

如何在交换机上重置密码而不丢失配置?如何配置SSH远程登录?

在网络设备管理中,保持设备的安全性是至关重要的,所以console密码是必须设置的,绝对不能偷懒。 但是,如果习惯不好,或者离职时交接不好,就会导致密码丢失,此时想要修改网络设置的配置就麻烦了。…

星辰考古:TiDB v1.0 再回首

“ 1.0 版本只是个开始,是新的起点,愿我们一路相扶,不负远途。 前言 TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库。 近日,TiDB v8.0.0 DMR 发布,详细发版说明戳这里: https://docs.pingca…

学习和“劳动”相关的谚语,柯桥俄语培训

1. Бог труды́ лю́бит. 天道酬勤。 2. В ми́ре нет тру́дных дел, ну́жно лишь усе́рдие. 世上无难事,只怕有心人。 3. У́тро вечера мудренее. 一日之计在于晨。 4. Что посе́ешь,…

OSEK的设计哲学与架构

1 前言 OSEK是为单核分布式嵌入式控制单元量身定制的实时系统,对事件驱动(event driven)的硬实时控制系统具有良好的适配性。OSEK没有强求不同软件模块间的完全兼容性,而是将重心放到了软件的可移植性上来。简单来说,与…

java-io流 超详细!

一、概念 io流用来读写文件中的数据 i:input o:output 二、分类 1、按流的方法分为:输入流、输出流 2、按操作文件的类型分为:字节流、字符流 其中字节流能处理所有类型的文件 字符流只能处理纯文本文件 纯文本文件可以通过windows自带的记事本能打…

写爬虫代码抓取Asterank中小行星数据

2024年5月4日 问题来源 解决方案 回顾2023年7月14日自己写的爬虫代码 import requests import re import pandas as pd texts[] def getData(page):#每页评论的网址urlhttps://item.jd.com/51963318622.html#comment#添加headers,伪装成浏览器headers{User-Agent:…

用户中心(优化)

文章目录 功能扩充管理员修改用户信息管理员删除用户管理员添加用户添加个人主页,可以完善个人信息(上传头像没有实现)添加默认头像打造一个所有用户可发帖的页面前端页面,√后端建表,接口,√前后端联调√ …

【精品毕设推荐】基于JSP物流信息网的设计与实现

点击免费下载原文及代码、PPT 摘要 本文讲述了基于JSP物流信息网的设计与实现。该系统使用java语言开发,使系统具有更好的平台性和可扩展性。 该系统实现了用户登录、注册、查询快递信息、快递公司注册成为合作伙伴以及系统管理员对信息进行管理等功能。系统的主…

文件系统和磁盘的关系

ext4文件系统注册 通过register_filesystem函数将ext4_fs_type结构体挂载到file_systems全局链表中。 ext4文件系统mout挂载 1.struct file_system_type *fs_type:指向 file_system_type 结构的指针,表示要挂载的文件系统类型。在这里,它指向…

Linux文件类型及目录和文件的权限

一、Linux 文件类型 1、Windows文件类型 2、Linux文件类型 1普通文件类型 Linux 中最多的一种文件类型, 包括 纯文本文件(ASCII);二进制文件(binary);数据 格式的文件(data);各种压缩文件.第一个属性为 - 2目录文件 就是目录, 能用 # cd 命…