跳过创建特定表的操作[春季] [休眠]

时间:2020-08-29 17:01:10

标签: java spring hibernate spring-security spring-jdbc

我正在使用配置文件创建一些简单的spring项目(spring安全性),该配置文件确定一些简单的值,例如表名等。我在其中定义了一个布尔字段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的值创建表?

2 个答案:

答案 0 :(得分:3)

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

  • 实现SchemaFilterProvider和SchemaFilter接口
  • 在SchemaFilter实现中,将if条件添加到includeTable中,以便它为您不使用的表返回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;
    }
}

答案 1 :(得分:0)

如果将Hibernate与spring.jpa.hibernate.ddl-auto = create / create-drop一起使用,那么它将在每次启动时尝试创建表(如果不存在),如果使用update则创建一次(如果不存在),并且仅在每次启动时更新表。

或者尝试在Spring中使用Application Listener:

@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的字段。它将自动注入到私有字段中。

相关问题