Hibernate(40)Hibernate的命名策略是什么?

Hibernate的命名策略

Hibernate的命名策略(Naming Strategy)用于定义数据库表和列的命名规则。默认情况下,Hibernate会根据实体类和属性名自动生成表名和列名,但有时候我们需要自定义这些命名规则以符合特定的命名约定或数据库要求。

默认命名策略

Hibernate 5.x及更高版本提供了一些内置的命名策略,如ImplicitNamingStrategyPhysicalNamingStrategy,用于分别处理隐式和物理命名。

  • ImplicitNamingStrategy:用于决定在没有明确指定表名或列名的情况下,如何从实体类名和属性名生成默认的表名和列名。
  • PhysicalNamingStrategy:用于决定最终采用的物理表名和列名,可以用于将隐式命名策略生成的名进行进一步的转换(如大小写转换、添加前缀或后缀等)。

自定义命名策略示例

步骤一:创建自定义命名策略

我们可以通过实现PhysicalNamingStrategy接口来创建自定义的物理命名策略。

java 复制代码
package com.example.naming;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment context) {
        return applyNamingStrategy(name);
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment context) {
        return applyNamingStrategy(name);
    }

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return applyNamingStrategy(name);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) {
        return applyNamingStrategy(name);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return applyNamingStrategy(name);
    }

    private Identifier applyNamingStrategy(Identifier name) {
        if (name == null) {
            return null;
        }

        // 自定义命名规则:将所有命名转换为大写,并加上前缀 "TBL_"
        String newName = "TBL_" + name.getText().toUpperCase();
        return Identifier.toIdentifier(newName);
    }
}

步骤二:配置Hibernate以使用自定义命名策略

在Hibernate配置文件hibernate.cfg.xml中,我们需要配置使用自定义的物理命名策略。

xml 复制代码
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 数据库连接配置 -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
        <property name="hibernate.connection.username">your_username</property>
        <property name="hibernate.connection.password">your_password</property>

        <!-- Hibernate 属性配置 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 配置自定义物理命名策略 -->
        <property name="hibernate.physical_naming_strategy">com.example.naming.CustomPhysicalNamingStrategy</property>

        <!-- 映射类 -->
        <mapping class="com.example.domain.Product"/>
    </session-factory>
</hibernate-configuration>

步骤三:定义实体类

定义一个简单的实体类Product,并观察其在数据库中的表名和列名是如何根据自定义命名策略生成的。

java 复制代码
package com.example.domain;

import javax.persistence.*;

@Entity
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "price")
    private Double price;

    public Product() {}

    public Product(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    // Getters 和 Setters

    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;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

步骤四:测试命名策略

通过一个简单的操作来测试我们的自定义命名策略。

java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.example.domain.Product;

public class HibernateNamingStrategyExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 插入示例数据
        insertSampleData(sessionFactory);

        // 关闭SessionFactory
        sessionFactory.close();
    }

    private static void insertSampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Product product1 = new Product("Laptop", 1000.0);
            Product product2 = new Product("Smartphone", 500.0);
            session.save(product1);
            session.save(product2);
            transaction.commit();
            System.out.println("Inserted sample data");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

详细解释

  1. 自定义命名策略

    • 创建一个名为CustomPhysicalNamingStrategy的类,实现PhysicalNamingStrategy接口,覆盖所需的方法。
    • 在覆盖的方法中,定义一个命名转换的逻辑,例如将所有名字转换为大写并添加前缀"TBL_"
  2. 配置文件

    • hibernate.cfg.xml配置文件中,添加<property name="hibernate.physical_naming_strategy">com.example.naming.CustomPhysicalNamingStrategy</property>来指定自定义命名策略类。
  3. 实体类

    • 定义一个简单的实体类Product,并观察其在数据库中生成的表名和列名。
  4. 测试命名策略

    • 通过一个示例操作(如插入数据)测试自定义命名策略的效果,观察生成的数据库表名和列名是否符合预期。

通过这种方式,我们可以灵活地定义和使用自定义的命名策略,以满足特定的数据库命名规范或个人偏好。

相关推荐
Coder_Boy_8 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
掘金者阿豪9 小时前
关系数据库迁移的“暗礁”:金仓数据库如何规避数据完整性与一致性风险
后端
ServBay9 小时前
一个下午,一台电脑,终结你 90% 的 Symfony 重复劳动
后端·php·symfony
sino爱学习9 小时前
高性能线程池实践:Dubbo EagerThreadPool 设计与应用
java·后端
颜酱10 小时前
从二叉树到衍生结构:5种高频树结构原理+解析
javascript·后端·算法
掘金者阿豪10 小时前
UUID的隐形成本:一个让数据库“慢下来”的陷阱
后端
用户0844652563710 小时前
Docker 部署 MongoDB Atlas 到服务端
后端
Anita_Sun11 小时前
一看就懂的 Haskell 教程 - 类型推断机制
后端·haskell
Anita_Sun11 小时前
一看就懂的 Haskell 教程 - 类型签名
后端·haskell
七八星天11 小时前
C#代码设计与设计模式
后端