gpt4 book ai didi

java - 即使数据库不存在,也可以使用 Hibernate 即时创建 PostgreSQL 数据库

转载 作者:太空狗 更新时间:2023-10-30 01:59:09 25 4
gpt4 key购买 nike

使用 H2,

Environment.HBM2DDL_AUTO, "create"

如果数据库不存在则创建数据库。

但是,在 Postgres 中,不创建不存在的数据库,因此会抛出一个异常,表示“数据库不存在”。有没有办法配置 Postgres 按需创建一个不存在的数据库?

可以使用以下配置文件来重现该问题:

使用 H2 工作正常:

package test.postgressql;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.cfg.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@PropertySource("file:C:/springconfig/qpmlib.properties")
@ComponentScan(basePackages = {"test.postgressql"})
@EnableJpaRepositories(basePackages = { "test.postgressql" })
@EnableTransactionManagement
public abstract class H2DBConfig {

@Autowired
org.springframework.core.env.Environment env;

public static final String DB_NAME = getNewDBName();

@Bean
public DataSource dataSource() {
DriverManagerDataSource dmds = new DriverManagerDataSource();
dmds.setDriverClassName("org.h2.Driver");
dmds.setUrl("jdbc:h2:tcp://localhost/~/" + DB_NAME );
dmds.setUsername(env.getProperty("h2user"));
dmds.setPassword(env.getProperty("h2pw"));
return dmds;
}

private static String getNewDBName() {
return "H2DBTest";
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setPersistenceUnitName(DB_NAME);
factory.setPackagesToScan("test.postgressql");
factory.setJpaVendorAdapter(jpaAdapter());
factory.setJpaProperties(jpaProperties());
factory.afterPropertiesSet();
return factory;
}

@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txm = new JpaTransactionManager(
entityManagerFactory().getObject());
return txm;
}

@Bean
public JpaVendorAdapter jpaAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.H2);
adapter.setGenerateDdl(true);
adapter.setShowSql(true);
return adapter;
}

@Bean
public HibernateExceptionTranslator exceptionTranslator() {
return new HibernateExceptionTranslator();
}

public Properties jpaProperties() {
Properties properties = new Properties();
properties.put(Environment.SHOW_SQL, "true");
properties.put(Environment.HBM2DDL_AUTO, "create");
properties.put(Environment.DIALECT,"org.hibernate.dialect.H2Dialect");
return properties;
}

}

使用 Postgres 失败

package test.postgressql;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.cfg.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@PropertySource("file:C:/springconfig/qpmlib.properties")
@ComponentScan(basePackages = {"test.postgressql"})
@EnableJpaRepositories(basePackages = { "test.postgressql" })
@EnableTransactionManagement
public abstract class PGDBConfig {

@Autowired
org.springframework.core.env.Environment env;

public static final String DB_NAME = getNewDBName();

@Bean
public DataSource dataSource() {
DriverManagerDataSource dmds = new DriverManagerDataSource();
dmds.setDriverClassName("org.postgresql.Driver");
dmds.setUrl("jdbc:postgresql://localhost:5432/" + DB_NAME);
dmds.setUsername(env.getProperty("postgresuser"));
dmds.setPassword(env.getProperty("postgrespw"));
return dmds;
}

private static String getNewDBName() {
return "PostgresDBTest";
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setPersistenceUnitName(DB_NAME);
factory.setPackagesToScan("test.postgressql");
factory.setJpaVendorAdapter(jpaAdapter());
factory.setJpaProperties(jpaProperties());
factory.afterPropertiesSet();
return factory;
}

@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txm = new JpaTransactionManager(
entityManagerFactory().getObject());
return txm;
}

@Bean
public JpaVendorAdapter jpaAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.POSTGRESQL);
adapter.setGenerateDdl(true);
adapter.setShowSql(true);
return adapter;
}

@Bean
public HibernateExceptionTranslator exceptionTranslator() {
return new HibernateExceptionTranslator();
}

public Properties jpaProperties() {
Properties properties = new Properties();
properties.put(Environment.SHOW_SQL, "true");
properties.put(Environment.HBM2DDL_AUTO, "create");
properties.put(Environment.DIALECT,"org.hibernate.dialect.PostgreSQL9Dialect");
return properties;
}
}

最佳答案

hbmddl工具只能为现有模式创建表,而不能为您创建模式。在运行该工具之前,数据库必须存在。这是因为数据库必须由管理员创建,并且应该为其分配所有者。

因为在大多数应用程序中,应用程序只能访问具有限制权限的数据库角色,因此不需要这样的功能。

PostgreSQL 不支持从连接 URL 即时创建数据库。您可以在应用程序启动时添加一个 InitializingBean,使用管理员帐户和默认 PostgreSQL 数据库连接到数据库服务器,如果应用程序数据库不存在,则发出一个 CREATE DATABASE

或者使用 Testcontainers 在 Docker 中引导数据库,like this .

关于java - 即使数据库不存在,也可以使用 Hibernate 即时创建 PostgreSQL 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30280683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com