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的方案(原来platformId重新命名为规范的tenantId)

@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)private 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.rhkb.cn/news/321161.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matplotlib和pandas与numpy

1.matplotlib介绍 一个2D绘图库; 2.Pandas介绍: Pandas一个分析结构化数据的工具; 3.NumPy 一个处理n纬数组的包; 4.实践:绘图matplotlip figure()生成一个图像实例 %matplotlib inline:图形直接在…

(三)JSP教程——JSP动作标签

JSP动作标签 用户可以使用JSP动作标签向当前输出流输出数据&#xff0c;进行页面定向&#xff0c;也可以通过动作标签使用、修改和创建对象。 <jsp:include>标签 <jsp:include>标签将同一个Web应用中静态或动态资源包含到当前页面中。资源可以是HTML、JSP页面和文…

5月6(信息差)

&#x1f30d;一次预测多个token&#xff0c;Meta新模型推理加速3倍&#xff0c;编程任务提高17% https://hub.baai.ac.cn/view/36857 &#x1f384; LeetCode 周赛超越 80% 人类选手&#xff0c;推理性能超 Llama3-70B。 ✨ 我国量子计算机实现“四算合一” 实现通算、…

鸿蒙OpenHarmony南向:【Hi3516标准系统入门(命令行方式)】

Hi3516标准系统入门&#xff08;命令行方式&#xff09; 注意&#xff1a; 从3.2版本起&#xff0c;标准系统不再针对Hi3516DV300进行适配验证&#xff0c;建议您使用RK3568进行标准系统的设备开发。 如您仍然需要使用Hi3516DV300进行标准系统相关开发操作&#xff0c;则可能会…

一加12/11/10/Ace2/Ace3手机上锁回锁BL无限重启黑屏9008模式救砖

一加12/11/10/Ace2/Ace3手机官方都支持解锁BL&#xff0c;搞机的用户也比较多&#xff0c;相对于其他品牌来说&#xff0c;并没有做出限制&#xff0c;这也可能是搞机党最后的救命稻草。而厌倦了root搞机的用户&#xff0c;就习惯性回锁BL&#xff0c;希望彻底变回官方原来的样…

数字旅游以科技创新为核心:推动旅游服务的智能化、精准化、个性化,为游客提供更加贴心、专业、高效的旅游服务

目录 一、引言 二、数字旅游以科技创新推动旅游服务智能化 1、智能化技术的应用 2、提升旅游服务的效率和质量 三、数字旅游以科技创新推动旅游服务精准化 1、精准化需求的识别与满足 2、精准化营销与推广 四、数字旅游以科技创新推动旅游服务个性化 1、个性化服务的创…

3D相机及应用

无论是2D相机和3D相机&#xff0c;在工业应用中都有着不可或缺的作用。3D相机与2D相机的最大区别在于&#xff0c;3D相机可以获取真实世界尺度下的3D信息&#xff0c;而2D相机只能获取像素尺度下的2D平面图像信息。通过3D相机得到的数据&#xff0c;我们可以还原出被测量物体的…

java线上问题排查之内存分析(三)

java线上问题排查之内存分析 使用top命令 top命令显示的结果列表中&#xff0c;会看到%MEM这一列&#xff0c;这里可以看到你的进程可能对内存的使用率特别高。以查看正在运行的进程和系统负载信息&#xff0c;包括cpu负载、内存使用、各个进程所占系统资源等。 2.用jstat命令…

RapidJSON介绍

1.简介 RapidJSON 是一个 C 的 JSON 解析库&#xff0c;由腾讯开源。 支持 SAX 和 DOM 风格的 API&#xff0c;并且可以解析、生成和查询 JSON 数据。RapidJSON 快。它的性能可与strlen() 相比。可支持 SSE2/SSE4.2 加速。RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至…

从互联网医院源码到搭建:开发视频问诊小程序的技术解析

如今&#xff0c;视频问诊小程序作为医疗服务的一种新形式&#xff0c;正逐渐受到人们的关注和青睐。今天&#xff0c;小编将为您详解视频问诊小程序的开发流程。 一、背景介绍 互联网医院源码是视频问诊小程序开发的基础&#xff0c;它提供了一套完整的医疗服务系统框架&…

Windows PC上从零开始部署ChatGML-6B-int4量化模型

引言 ChatGLM-6B是清华大学知识工程和数据挖掘小组&#xff08;Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University&#xff09;发布的一个开源的对话机器人。6B表示这是ChatGLM模型的60亿参数的小规模版本&#xff0c;约60亿参数。 ChatGML-6B-in…

spring高级篇(七)

1、异常处理 在DispatcherServlet中&#xff0c;doDispatch(HttpServletRequest request, HttpServletResponse response) 方法用于进行任务处理&#xff1a; 在捕获到异常后没有立刻进行处理&#xff0c;而是先用一个局部变量dispatchException进行记录&#xff0c;然后统一由…

文心一言 VS 讯飞星火 VS chatgpt (253)-- 算法导论18.2 6题

六、假设 B-TREE-SEARCH 的实现是在每个结点内采用二分查找&#xff0c;而不是线性查找。证明&#xff1a;无论怎样选择 t ( t 为 n 的函数)&#xff0c;这种实现所需的 CPU 时间都为 O(lgn)。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 首先&#xff0c;我…

ChatGPT理论分析

ChatGPT "ChatGPT"是一个基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;架构的对话系统。GPT 是一个由OpenAI 开发的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;它使用深度学习来生成文本。以下是对ChatGPT进行理论分析的几个主…

PTA|小字辈

题目 本题给定一个庞大家族的家谱&#xff0c;要请你给出最小一辈的名单。 输入格式&#xff1a; 输入在第一行给出家族人口总数 N&#xff08;不超过 100 000 的正整数&#xff09; —— 简单起见&#xff0c;我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号&#x…

c#数据库: 10.调用存储过程查询信息,并显示在窗体上

查询女生信息&#xff0c;并将信息显示在窗体上: 原数据表//右键数据库名,新建查询 ------------- 新建查询窗口,添加新建存储过程Procedure_GetGirls1和查询代码如下 : CREATE PROCEDURE dbo.Procedure_GetGirls1 /*存储过程名称*/ AS SELECT * f…

《设计一款蓝牙热敏打印机》

主控芯片用易兆威蓝牙ic&#xff0c;通讯接口&#xff1a;蓝牙、串口、usb 安卓apk用java kotlin编写、上位机用Qt编写。

STM32F4xx开发学习_SysTick

SysTick系统定时器 SysTick属于CM4内核外设&#xff0c;有关寄存器的定义和部分库函数都在core_cm4.h这个头文件中实现&#xff0c;可用于操作系统&#xff0c;提供必要的时钟节拍 SysTick简介 SysTick是一个 24 位向下定时器&#xff0c;属于CM4内核中的一个外设&#xff0c;…

套管外径测量仪 多尺寸型号 规格全可定制

套管&#xff08;bushing&#xff09;是一种将带电导体引入电气设备或穿过墙壁的一种绝缘装置。前者称为电器套管&#xff0c;后者称为穿墙套管。套管通常用在建筑地下室&#xff0c;是用来保护管道或者方便管道安装的铁圈。套管的分类有刚性套管、柔性防水套管、钢管套管及铁皮…

python+flask+ldap3搭建简易版IDaaS系统(前端站点)

Python工具开源专栏 Py0006 pythonflaskldap3搭建简易版IDaaS系统&#xff08;前端站点&#xff09; Python工具开源专栏前言目录结构前端网站的部分演示首页查询数据数据同步数据关联查询系统日志 完整代码已在GitHub上开源 前言 pythonflaskldap3搭建简易版IDaaS系统的前端站…