跳过创建特定表 [Spring] [Hibernate]

Posted

技术标签:

【中文标题】跳过创建特定表 [Spring] [Hibernate]【英文标题】:Skipping creation of a specific table [Spring] [Hibernate] 【发布时间】:2020-12-18 07:46:12 【问题描述】:

我正在创建一些简单的 spring 项目(spring security),其中的配置文件确定了一些简单的值,例如表名等。我在那里定义了一个布尔字段 REQUIRED_ACTIVATION 来确定新用户是否必须通过发送的激活链接激活他的帐户例如通过邮件。

public static final boolean REQUIRED_ACTIVATION = true;

如果我将 REQUIRED_ACTIVATION 值设置为 false,则用户在注册后立即处于活动状态。我已经定义了包含激活链接数据的实体:

@Entity
@Table(name = 'user_activation_link')
public class UserActivationLink 
   [...]

当 REQUIRED_ACTIVATION 设置为 false 时,我不会在任何地方使用此类,而是在数据库中创建表。是否有任何解决方案可以确定是否会根据 REQUIRED_ACTIVATION 的值创建表?

【问题讨论】:

【参考方案1】:

您需要执行this 之类的操作来排除您不想在数据库中创建的表。

实现 SchemaFilterProvider 和 SchemaFilter 接口 在 SchemaFilter 实现中,向 includeTable 添加一个 if 条件,以便它为您不使用的表返回 false 想创作 将 hibernate.properties 添加到类路径并定义 hibernate.hbm2ddl.schema_filter_provider 指向 SchemaFilterProvider 实现
hibernate.hbm2ddl.schema_filter_provider=com.your.package.Provider

还有:

package com.your.package;

import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.Sequence;
import org.hibernate.mapping.Table;
import org.hibernate.tool.schema.spi.SchemaFilter;
import org.hibernate.tool.schema.spi.SchemaFilterProvider;

public class Provider implements SchemaFilterProvider 

    @Override
    public SchemaFilter getCreateFilter() 
        return MySchemaFilter.INSTANCE;
    

    @Override
    public SchemaFilter getDropFilter() 
        return MySchemaFilter.INSTANCE;
    

    @Override
    public SchemaFilter getMigrateFilter() 
        return MySchemaFilter.INSTANCE;
    

    @Override
    public SchemaFilter getValidateFilter() 
        return MySchemaFilter.INSTANCE;
    


class MySchemaFilter implements SchemaFilter 

    public static final MySchemaFilter INSTANCE = new MySchemaFilter();

    @Override
    public boolean includeNamespace(Namespace namespace) 
        return true;
    

    @Override
    public boolean includeTable(Table table) 
        if (//REQUIRED_ACTIVATION==true && table.getName() is the table you want to exclude)
            return false;
        
        return true;
    

    @Override
    public boolean includeSequence(Sequence sequence) 
        return true;
    

【讨论】:

【参考方案2】:

如果您使用带有spring.jpa.hibernate.ddl-auto = create / create-drop的Hibernate,那么它会在每次启动时尝试创建一个表如果不存在,如果您使用更新它创建一次如果不存在,并且只在每次启动时更新表。

作为替代尝试在 Spring 中使用应用程序侦听器:

@Value("$required.activation")
private Boolean isActivationRequired;

@PersistenceContext   
private EntityManager em;

@EventListener
public void handleContextRefreshEvent(ContextRefreshedEvent ctxRefreshedEvent) 
    if (!isActivationRequired) 
        em.createNativeQuery("drop table user_activation_link").executeUpdate();
    

注意这里使用@Value 代替public static final 字段,您可以在application.properties 中添加名为required.activation 的字段。它会自动注入到私有字段中。

【讨论】:

以上是关于跳过创建特定表 [Spring] [Hibernate]的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法只为特定作业跳过 Spring Batch 的持久元数据?

在使用 mysqldump 命令进行表备份时,我们可以跳过特定列吗?

具有特定表角色的spring security UserDetailsS​​ervice

Actionscript 3.0:如何在不跳过特定帧上编写的任何代码的情况下创建快进按钮?

Spring Boot - 我的单元测试被跳过

SQL Query 显示带风的结果,但它跳过某些行