巧用Hibernate 完成多数据库的DDL脚本创建

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 巧用Hibernate 完成多数据库的DDL脚本创建

巧用Hibernate 完成多数据库的DDL脚本创建

spring boot jpa 默认的orm框架就是Hibernate。 由hibernate完成数据库的读写也是主流的方式之一。但是不同数据库之间,建表、建索引的方言语句都有较多差别,很难做到一套SQL在所有数据库上进行执行。

那么Hibernate可以做到DML等语句通用,DDL可以吗? 当然,是可以的。

Hibernate兼容全靠org.hibernate.dialect.Dialect下的具体实现类。

下面我们来简单演示如何基于hibernate的注解,来生成DDL语句。

定义一个Entity

使用hibernate的注解描述一个Entity,我们定义了其表名,id,name属性,并指定id为主键列。

// hibernate 6.x 开始,注解移动到了jakarta.persistence包下
import jakarta.persistence.*;
@Entity
@Table(name = "my_entity")
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;
    @Column(name = "name", nullable = true, length = 256)
    private String name;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

期待生成的SQL

我们在建表的时候,还要创建序列,指定执行引擎。要知道,MYSQL如果使用MyISAM将无法使用会话。

oracle

create sequence my_entity_SEQ start with 1 increment by 50;
create table my_entity (id number(19,0) not null, name varchar2(256 char), primary key (id));

mysql

create table my_entity (id bigint not null, name varchar(256), primary key (id)) engine=InnoDB;
create table my_entity_SEQ (next_val bigint) engine=InnoDB;
insert into my_entity_SEQ values ( 1 );

具体实现

具体实现并不难,主要是调用org.hibernate.tool.hbm2ddl.SchemaExport进行导出,主要方法如下:

/**
     * 导出
     *
     * @param classes    导出的类
     * @param dialect    数据库方言
     * @param action     导出动作
     * @param targetType 导出方式
     * @param scriptPath 脚本位置
     */
  public static void export0(List<Class> classes,
        Class<? extends Dialect> dialect,
        SchemaExport.Action action,
        TargetType targetType,
        String scriptPath) {
        Properties p = new Properties();
        // 数据库方言,最终输出的方言
        p.put("hibernate.dialect", dialect.getName());
        // 自动执行的动作
        p.put("hibernate.hbm2dll.auto", action.name());
        // 分隔符,默认为空
        p.put("hibernate.hbm2ddl.delimiter", ";");
        // 是否展示SQL
        p.put("show_sql", true);
        // 是否使用默认的jdbc元数据,默认为true,读取项目自身的元数据
        p.put("hibernate.temp.use_jdbc_metadata_defaults", false);
        ConfigurationHelper.resolvePlaceHolders(p);
        ServiceRegistry registry = new StandardServiceRegistryBuilder()
            .applySettings(p)
            .build();
        // org.dark.migration.demo
        MetadataSources metadataSources = new MetadataSources(registry);
        classes.forEach(metadataSources::addAnnotatedClass);
        Metadata metadata = metadataSources.buildMetadata();
        SchemaExport export = new SchemaExport();
        export.setOverrideOutputFileContent();
        export.setOutputFile(scriptPath);
        export.execute(EnumSet.of(targetType), action, metadata);
    }

调用方法如下:

public static void main(String[] args) {
        List<Class> classes = new ArrayList<>();
        classes.add(MyEntity.class);
//        export0(classes, Oracle12cDialect.class,
        export0(classes, MySQL8Dialect.class,
            SchemaExport.Action.CREATE,
            TargetType.SCRIPT, "test-output2.txt");
    }

最终就会在"test-output2.txt"中生成我们期待的SQL。

支持的数据库方言

通过查看Dialect的子类,可以看到除了主流的mysql、Oracle、postgre、DB2等,像TIDB、CockroachDB等等数据库等均有方言支持。

总结

利用好hibernate的多数据源方言兼容性,我们仅维护一套注解即可创建多数据源DDL。文章代码库位置:

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
前端开发 数据库
会议室管理系统源码(含数据库脚本)
会议室管理系统源码(含数据库脚本)
67 0
|
3月前
|
SQL 人工智能 数据可视化
16.1k star! 只需要DDL就能一键生成数据库关系图!开源神器ChartDB让你的数据结构"看得见"
ChartDB是一款开源的数据库可视化神器,通过一句智能查询就能自动生成专业的数据库关系图。无需安装客户端、不用暴露数据库密码,打开网页就能完成从数据建模到迁移的全流程操作,堪称开发者的"数据库透视镜"。
532 67
|
2月前
|
关系型数据库 MySQL Linux
实现MySQL数据库的定时自动备份脚本。
拿走,不谢,这个脚本配方(指引)保证你的数据库数据像蛋糕店一样地天天更新,还能确保老旧的蛋糕(数据)不会堆积满仓库。这下可好,数据安全有保障,数据库管理员也能轻松一点,偶尔闲下来的时候,煮杯咖啡,看个剧岂不美哉?别忘了偶尔检查一下你的自动备份是否正常工作,以防万一蛋糕机器出了点小差错。
121 20
|
1月前
|
SQL 存储 关系型数据库
一、数据库和表的基本操作 DDL
在使用 MySQL 做项目或写业务逻辑时,离不开对数据库和数据表的基本操作。我们这次从创建数据库讲起,一步步带你掌握如何新建表、查看表结构、修改字段、重命名、删除等常用命令。每一个知识点都有示例代码可直接上手,还准备了一套完整的动手练习,帮助你把概念变成熟练技能。如果你刚入门 SQL,或者想系统梳理一遍 DDL 基础,这篇会是不错的起点。
117 0
|
3月前
|
Java 数据库
jsp CRM客户管理系统(含数据库脚本以及文档)
jsp CRM客户管理系统(含数据库脚本以及文档)
85 10
|
3月前
|
Java 关系型数据库 MySQL
Java汽车租赁系统源码(含数据库脚本)
Java汽车租赁系统源码(含数据库脚本)
69 4
|
4月前
|
关系型数据库 Shell 网络安全
定期备份数据库:基于 Shell 脚本的自动化方案
本篇文章分享一个简单的 Shell 脚本,用于定期备份 MySQL 数据库,并自动将备份传输到远程服务器,帮助防止数据丢失。
|
4月前
|
SQL 关系型数据库 数据库连接
|
8月前
|
关系型数据库 MySQL 数据库连接
python脚本:连接数据库,检查直播流是否可用
【10月更文挑战第13天】本脚本使用 `mysql-connector-python` 连接MySQL数据库,检查 `live_streams` 表中每个直播流URL的可用性。通过 `requests` 库发送HTTP请求,输出每个URL的检查结果。需安装 `mysql-connector-python` 和 `requests` 库,并配置数据库连接参数。
185 68
|
9月前
|
SQL 关系型数据库 MySQL