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. 测试命名策略

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

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

相关推荐
野犬寒鸦12 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
我爱娃哈哈12 小时前
SpringBoot + Flowable + 自定义节点:可视化工作流引擎,支持请假、报销、审批全场景
java·spring boot·后端
李梨同学丶14 小时前
0201好虫子周刊
后端
思想在飞肢体在追14 小时前
Springboot项目配置Nacos
java·spring boot·后端·nacos
Loo国昌17 小时前
【垂类模型数据工程】第四阶段:高性能 Embedding 实战:从双编码器架构到 InfoNCE 损失函数详解
人工智能·后端·深度学习·自然语言处理·架构·transformer·embedding
ONE_PUNCH_Ge17 小时前
Go 语言泛型
开发语言·后端·golang
良许Linux18 小时前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式
不光头强18 小时前
spring boot项目欢迎页设置方式
java·spring boot·后端
怪兽毕设18 小时前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统
学IT的周星星18 小时前
Spring Boot Web 开发实战:第二天,从零搭个“会卖萌”的小项目
spring boot·后端·tomcat