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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 巧用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。文章代码库位置:

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
24天前
|
SQL 数据库 索引
关于 SAP ABAP REPOSRC 数据库表在 HANA 中的 DDL Definition
关于 SAP ABAP REPOSRC 数据库表在 HANA 中的 DDL Definition
19 1
关于 SAP ABAP REPOSRC 数据库表在 HANA 中的 DDL Definition
|
1月前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——TestStu.java
hibernate正向生成数据库表以及配置——TestStu.java
18 1
|
1月前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——Teacher.java
hibernate正向生成数据库表以及配置——Teacher.java
11 0
|
3月前
|
数据库 数据安全/隐私保护 Python
写一个定时备份数据库的脚本,且只保留最近3天
写一个定时备份数据库的脚本,且只保留最近3天
68 3
|
1月前
|
SQL 存储 关系型数据库
【MySQL 数据库】1、MySQL 的 DDL、DML、DQL 语句
【MySQL 数据库】1、MySQL 的 DDL、DML、DQL 语句
52 0
|
10天前
|
SQL 数据库 HIVE
Hive【基础知识 05】常用DDL操作(数据库操作+创建表+修改表+清空删除表+其他命令)
【4月更文挑战第8天】Hive【基础知识 05】常用DDL操作(数据库操作+创建表+修改表+清空删除表+其他命令)
21 0
|
1月前
|
SQL 编解码 数据库
MyKtv点歌系统前台主要功能实现,内附数据库脚本,可以直接运行
MyKtv点歌系统前台主要功能实现,内附数据库脚本,可以直接运行
14 1
MyKtv点歌系统前台主要功能实现,内附数据库脚本,可以直接运行
|
1月前
|
Java 关系型数据库 MySQL
Java调用shell脚本实现数据库备份功能
本篇文章主要介绍怎样使用Java程序,执行服务器上的数据库备份Shell脚本进行MySQL数据库的备份功能。
|
1月前
|
SQL 关系型数据库 MySQL
Flink 提供了一种名为 Flink SQL 的查询语言,它支持多种数据库之间的 DDL 语句转换
【2月更文挑战第18天】Flink 提供了一种名为 Flink SQL 的查询语言,它支持多种数据库之间的 DDL 语句转换
171 2
|
3月前
|
SQL 关系型数据库 MySQL
MySQL数据库——DDL基本操作
MySQL数据库——DDL基本操作