PingKai Logo下载

使用 Hibernate 连接 TiDB

TiDB 是一个 MySQL 兼容的数据库,Hibernate 是流行的开源 Java ORM。由于 TiDB 与 MySQL 高度兼容,建议你将 org.hibernate.dialect.MySQLDialect 作为 Hibernate 的 dialect,以获得长期兼容性。或者,你也可以使用 TiDB 专用的 dialect(org.hibernate.community.dialect.TiDBDialect),该 dialect 可在 Hibernate community dialects 中找到,但并非由平凯星辰维护。如果你在使用 MySQLDialect 时遇到任何兼容性问题,可以在 GitHub 上提交 issue。

在本教程中,你可以学习如何使用 TiDB 和 Hibernate 完成以下任务:

  • 搭建你的环境。
  • 使用 Hibernate 连接到你的 TiDB 集群。
  • 构建并运行你的应用程序。你还可以在 示例代码片段 中找到基本 CRUD 操作的代码示例。

前提条件

完成本教程,你需要:

  • Java Development Kit (JDK) 17 或更高版本。你可以根据业务和个人需求选择 OpenJDK 或 Oracle JDK。
  • Maven 3.8 或更高版本。
  • Git。
  • 一个 TiDB 集群。

如果你还没有 TiDB 集群,可以按如下方式创建:

运行示例应用连接 TiDB

本节演示如何运行示例应用代码并连接 TiDB。

步骤 1:克隆示例应用仓库

在终端窗口中运行以下命令,克隆示例代码仓库:

git clone https://github.com/tidb-samples/tidb-java-hibernate-quickstart.git
cd tidb-java-hibernate-quickstart

步骤 2:配置连接信息

根据你选择的 TiDB 部署方式,连接到你的 TiDB 集群。

  1. 进入 Clusters 页面,然后点击目标集群名称,进入其概览页面。

  2. 点击右上角的 Connect,弹出连接对话框。

  3. 确保连接对话框中的配置与你的运行环境一致。

    • Connection Type 设置为 Public
    • Branch 设置为 main
    • Connect With 设置为 General
    • Operating System 与你的环境匹配
  4. 点击 Generate Password 生成随机密码。

  5. 运行以下命令,复制 env.sh.example 并重命名为 env.sh:

    cp env.sh.example env.sh
  6. 将对应的连接字符串复制粘贴到 env.sh 文件中。示例结果如下:

    export TIDB_HOST='{host}'  # e.g. gateway01.ap-northeast-1.prod.aws.tidbcloud.com
    export TIDB_PORT='4000'
    export TIDB_USER='{user}'  # e.g. xxxxxx.root
    export TIDB_PASSWORD='{password}'
    export TIDB_DB_NAME='test'
    export USE_SSL='true'

    请务必将 {} 占位符替换为连接对话框中获得的连接参数。

    平凯数据库云服务 Starter 需要安全连接,因此你需要将 USE_SSL 的值设置为 true。

  7. 保存 env.sh 文件。

步骤 3:运行代码并检查结果

  1. 执行以下命令运行示例代码:

    make
  2. 检查 Expected-Output.txt 文件,确认输出是否一致。

示例代码片段

你可以参考以下示例代码片段,完成你自己的应用开发。

完整示例代码及运行方法请参见 tidb-samples/tidb-java-hibernate-quickstart 仓库。

连接 TiDB

编辑 Hibernate 配置文件 hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.url">${tidb_jdbc_url}</property>
        <property name="hibernate.connection.username">${tidb_user}</property>
        <property name="hibernate.connection.password">${tidb_password}</property>
        <property name="hibernate.connection.autocommit">false</property>

        
        <property name="hibernate.hbm2ddl.auto">create-drop</property>

        
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
    </session-factory>
</hibernate-configuration>

请务必将 ${tidb_jdbc_url}、${tidb_user} 和 ${tidb_password} 替换为你 TiDB 集群的实际值。然后,定义如下函数:

public SessionFactory getSessionFactory() {
    return new Configuration()
            .configure("hibernate.cfg.xml")
            .addAnnotatedClass(${your_entity_class})
            .buildSessionFactory();
}

使用该函数时,你需要将 ${your_entity_class} 替换为你自己的数据实体类。若有多个实体类,需要为每个类添加一条 .addAnnotatedClass(${your_entity_class}) 语句。上述函数只是配置 Hibernate 的一种方式。如果你在配置过程中遇到问题,或想了解更多 Hibernate 相关内容,请参考 Hibernate 官方文档。

插入或更新数据

try (Session session = sessionFactory.openSession()) {
    session.persist(new PlayerBean("id", 1, 1));
}

更多信息参见 插入数据 和 修改数据。

查询数据

try (Session session = sessionFactory.openSession()) {
    PlayerBean player = session.get(PlayerBean.class, "id");
    System.out.println(player);
}

更多信息参见 查询数据。

删除数据

try (Session session = sessionFactory.openSession()) {
    session.remove(new PlayerBean("id", 1, 1));
}

更多信息参见 删除数据。

与 MySQLDialect 的兼容性

当你在 TiDB 中使用 MySQLDialect 时,请注意以下行为:

SERIALIZABLE 隔离级别

应用程序如果尝试设置 SERIALIZABLE 事务隔离级别,在 TiDB 中会遇到如下错误:

The isolation level 'SERIALIZABLE' is not supported. Set tidb_skip_isolation_level_check=1 to skip this error

为避免该错误,请在服务器端设置如下 TiDB 系统变量:

SET GLOBAL tidb_skip_isolation_level_check=1;

启用该变量后,TiDB 会接受指定 SERIALIZABLE 的请求而不返回错误。内部实际仍采用 REPEATABLE-READ,这是 TiDB 的最强隔离级别。更多信息参见 tidb_skip_isolation_level_check。

CHECK 约束

Hibernate 的 @Check 注解会生成 DDL CHECK 约束。MySQL 8.0.16 及以上版本 默认会强制执行这些约束,但 TiDB 默认不会强制执行,除非你显式开启。

如需在 TiDB 中启用 CHECK 约束强制执行,请设置如下系统变量:

SET GLOBAL tidb_enable_check_constraint=ON;

如果未设置该变量,TiDB 会接受 CHECK 约束语法但不会强制执行,可能导致数据完整性问题。更多信息参见 CHECK 约束。

后续步骤

需要帮助?

在 Discord 或 Slack 社区提问,或 提交支持工单。