java - liquibase 前置条件 sqlCheck 获取数据库名称

标签 java mysql sql liquibase

我有以下变更集:

<changeSet author="test" id="1517488978218-28">
    <addUniqueConstraint columnNames="name_" constraintName="UK_52q0nm9af3039btfxjt8q6ahj" tableName="settings_table"/>
</changeSet>

我想检查唯一约束是否已经存在:

<preConditions onFail="MARK_RAN">
    <sqlCheck expectedResult="0">select distinct CONSTRAINT_NAME from information_schema.TABLE_CONSTRAINTS where constraint_type = 'UNIQUE' AND  CONSTRAINT_NAME ='UK_52q0nm9af3039btfxjt8q6ahj' AND table_schema = '${databasename}'</sqlCheck>
</preConditions>

但它不会工作,因为我不知道数据库名称。 我需要在 SQL 查询中获取数据库名称,如何获取? 我的数据源初始化代码:

@Configuration
public class DataSourceConfig {

    private static final Logger logger = Logger.getLogger(DataSourceConfig.class);

    @Bean(destroyMethod = "")
    public DataSource dataSource() {

        DataSource dataSource = null;
        JndiTemplate jndi = new JndiTemplate();
        while (true)
            try {
                logger.info("Try to initialize datasource");
                dataSource = (DataSource) jndi.lookup("java:comp/env/jdbc/macmonitor_liquibase_mysql");
                break;
            } catch (NamingException e) {
                logger.error("Error while initializing datasource", e);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    logger.error("Interupted exception in sleep method in datasource initialisation loop", e1);
                    return null;
                }
                continue;
            }
        logger.info("Datasource initialization success");
        return dataSource;
    }

    @Bean
    @Autowired
    public SpringLiquibase liquibase(DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setChangeLog("classpath:liquibase/db-changelog-master.xml");
        liquibase.setDataSource(dataSource);
        return liquibase;
        }
}

最佳答案

我写了以下 CustomPrecondition:

public class UniqueConstraintExists implements CustomPrecondition {

    private String constraintName;
    private String tableName;

    public void setConstraintName(String constraintName) {
        this.constraintName = constraintName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    @Override
    public void check(Database database) throws CustomPreconditionFailedException, CustomPreconditionErrorException {

        if(database instanceof MySQLDatabase){

            String defaultCatalogName = database.getDefaultCatalogName();

            String sql = String.format("select count(distinct CONSTRAINT_NAME) " +
                            "from information_schema.TABLE_CONSTRAINTS " +
                            "where constraint_type = 'UNIQUE' AND CONSTRAINT_NAME ='%s' AND TABLE_NAME='%s' AND table_schema = '%s'",
                    constraintName, tableName, defaultCatalogName);

            RawSqlStatement statement = new RawSqlStatement(sql);

            int count = 0;

            try {
                count = ExecutorService.getInstance().getExecutor(database).queryForInt(statement);
            } catch (DatabaseException e) {
                throw new CustomPreconditionErrorException("Unique constraint " + constraintName + " get count exception",e);
            }

            if(count == 1){
                //exists
                return;
            }else if(count == 0){
                //not exists
                throw new CustomPreconditionFailedException(String.format("Unique constraint %s not exists", constraintName));
            }else{
                //impossible
                throw new CustomPreconditionErrorException("Count of constraint instances " + constraintName + " more than 1 or less than 0, count: " + count);
            }

        }

        throw new CustomPreconditionErrorException("Unsupported database for UniqueConstraintExists precondition: " + database.getDatabaseProductName() + ", mysql and mariadb are only supported");
    }
}

变更集:

<changeSet author="macmonitor.by" id="1517488978218-28">
        <preConditions onFail="MARK_RAN">
            <not>
                <customPrecondition className="by.macmonitor.liquibase.UniqueConstraintExists">
                    <param name="constraintName" value="UK_52q0nm9af3039btfxjt8q6ahj"/>
                    <param name="tableName" value="settings_table"/>
                </customPrecondition>
            </not>
        </preConditions>
        <addUniqueConstraint columnNames="name_" constraintName="UK_52q0nm9af3039btfxjt8q6ahj"
                             tableName="settings_table"/>
</changeSet>

关于java - liquibase 前置条件 sqlCheck 获取数据库名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48582467/

相关文章:

c# - 在存储过程中添加一条到多条记录

php - 我应该使用哪种 SQL 类型来输入值 4.865472349

java - 使用 java 写入文件时输出无效

java - Flux.buffer() 不适用于 switchIfEmpty

javascript - 如何使用函数绘制高位图?

mysql - 我应该为 CRM 使用什么版本的 MySQL?

mysql - MySQLTuner 中的建议

java - 有人可以理解G1垃圾收集器的输出吗?

java - 改造返回一个空的响应主体

mysql - SQL 无法创建表(错误号 : 150)