[英]Spring boot data r2dbc auto create tables
I have a simple question, is it possible to auto-generate tables using spring boot data r2dbc for MySQL or other databases?我有一个简单的问题,是否可以使用 spring 引导数据 r2dbc 为 MySQL 或其他数据库自动生成表? in JPA I added spring.jpa.hibernate.ddl-auto=update and created tables
在 JPA 我添加了 spring.jpa.hibernate.ddl-auto=update 并创建了表
This is my pom:这是我的 pom:
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-test-autoconfigure-r2dbc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.43.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
I know that this is not the exact answer but the only way to create tables in R2DBC is to utilize databasePopulator
:我知道这不是确切的答案,但在 R2DBC 中创建表的唯一方法是利用
databasePopulator
:
@Bean
fun initializer(connectionFactory: ConnectionFactory) =
ConnectionFactoryInitializer().apply {
setConnectionFactory(connectionFactory)
setDatabasePopulator(CompositeDatabasePopulator()
.apply {
addPopulators(ResourceDatabasePopulator(FileSystemResource("src/test/resources/sql/init.sql")))
})
}
It can come in handy during tests.它可以在测试期间派上用场。
In order for r2dbc to auto create tables on app startup all you need is a config java class annotated with the @Configuration eg:为了让 r2dbc 在应用程序启动时自动创建表,您只需要一个带有 @Configuration 注释的配置 java class 例如:
import io.r2dbc.spi.ConnectionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator;
@Configuration
public class DbSchemaInitOnStartup {
@Bean
ConnectionFactoryInitializer initializer(@Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
ResourceDatabasePopulator resource = new ResourceDatabasePopulator(new ClassPathResource("schema.sql"));
initializer.setDatabasePopulator(resource);
return initializer;
}
}
The schema.sql
file must be placed in /resources
folder for above to work. schema.sql
文件必须放在/resources
文件夹中才能正常工作。
For testing purpose, I tried this scenario by creating two datasources that point to the same database.出于测试目的,我通过创建两个指向同一数据库的数据源来尝试这种情况。 One is for JDBC and the other one is for R2DBC.
一个用于 JDBC,另一个用于 R2DBC。
JDBC Datasource JDBC 数据源
@Configuration
@EnableJpaRepositories( basePackages = "com.ns.reactivetest.repository.jdbc", entityManagerFactoryRef = "jdbcEntityManager", transactionManagerRef = "jdbcTransactionManager" )
@EnableTransactionManagement
public class JdbcConfiguration {
@Autowired
Environment env;
@Bean( name = "jdbcDataSource" )
@Primary
public DataSource jdbcDataSource( ) {
DriverManagerDataSource dataSource = new DriverManagerDataSource( );
dataSource.setUrl( env.getProperty( "spring.datasource.url" ) );
dataSource.setUsername( env.getProperty( "spring.datasource.username" ) );
dataSource.setPassword( env.getProperty( "spring.datasource.password" ) );
HikariDataSource hikariDataSource = new HikariDataSource( );
hikariDataSource.setDataSource( dataSource );
hikariDataSource.setMinimumIdle( Integer.valueOf( env.getProperty( "spring.datasource.hikari.minimum-idle" ) ) );
hikariDataSource.setMaximumPoolSize( Integer.valueOf( env.getProperty( "spring.datasource.hikari.maximum-pool-size" ) ) );
hikariDataSource.setSchema( env.getProperty( "spring.datasource.hikari.schema" ) );
return hikariDataSource;
}
@Bean( name = "jdbcEntityManager" )
@Primary
public LocalContainerEntityManagerFactoryBean jdbcEntityManager( @Qualifier( "jdbcDataSource" ) DataSource dataSource ) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean( );
em.setDataSource( dataSource );
em.setPackagesToScan( new String[]{ "com.ns.reactivetest.domain" } );
em.setPersistenceUnitName( "jdbc_persistence_Unit_Name" );
JpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter( );
em.setJpaVendorAdapter( jpaVendorAdapter );
Properties properties = new Properties( );
properties.setProperty( "hibernate.hbm2ddl.auto", env.getProperty( "spring.jpa.hibernate.ddl-auto" ) );
properties.setProperty( "hibernate.dialect", env.getProperty( "spring.jpa.properties.hibernate.dialect" ) );
em.setJpaProperties( properties );
return em;
}
@Bean( name = "jdbcTransactionManager" )
@Primary
public PlatformTransactionManager jdbcTransactionManager( @Qualifier( "jdbcDataSource" ) DataSource dataSource ) {
JpaTransactionManager transactionManager = new JpaTransactionManager( );
transactionManager.setDataSource( dataSource );
transactionManager.setPersistenceUnitName( "jdbc_persistence_Unit_Name" );
return transactionManager;
}
}
R2DBC Datasource R2DBC 数据源
@Configuration
@EnableR2dbcRepositories( basePackages = "com.ns.reactivetest.repository.reactive" )
@EnableTransactionManagement
public class R2DbcConfiguration {
@Autowired
private Environment env;
@Bean
public ConnectionFactory connectionFactory( ) {
ConnectionFactory connectionFactory = new PostgresqlConnectionFactory(
PostgresqlConnectionConfiguration.builder( )
.host( env.getProperty( "spring.r2dbc.properties.hostname", "localhost" ) )
.database( env.getProperty( "spring.r2dbc.name", "postgres" ) )
.username( env.getProperty( "spring.r2dbc.username", "postgres" ) )
.password( env.getProperty( "spring.r2dbc.password", "password" ) )
.schema( env.getProperty( "spring.r2dbc.properties.schema", "public" ) )
.port( Integer.valueOf( env.getProperty( "spring.r2dbc.properties.port", "5432" ) ) )
//.options( options )
.build( )
);
if ( env.getProperty( "spring.r2dbc.pool.enabled", Boolean.class, false ) ) {
ConnectionPoolConfiguration connectionPoolConfiguration = ConnectionPoolConfiguration.builder( connectionFactory )
.maxIdleTime( Duration.ofSeconds( env.getProperty( "spring.r2dbc.pool.max-idle-time", Long.class, 1800L ) ) ) // 30 Minutes
.initialSize( env.getProperty( "spring.r2dbc.pool.initial-size", Integer.class, 10 ) )
.maxSize( env.getProperty( "spring.r2dbc.pool.max-size", Integer.class, 25 ) )
.validationQuery( env.getProperty( "spring.r2dbc.validation-query", String.class, "SELECT 1" ) )
.build( );
return new ConnectionPool( connectionPoolConfiguration );
} else {
return connectionFactory;
}
}
@Bean
ReactiveTransactionManager transactionManager( ConnectionFactory connectionFactory ) {
return new R2dbcTransactionManager( connectionFactory );
}
}
Note: Here I have used two pacakges for JDBC and R2DBC Repositoties.注意:这里我为 JDBC 和 R2DBC Repositoties 使用了两个包。
So far it is working fine.到目前为止它工作正常。 But I don't know how will this work for the complex scenarios and requirements.
但我不知道这将如何适用于复杂的场景和要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.