Java 使用hibernate以编程方式验证架构
在mose项目中,使用模式验证运行Java 使用hibernate以编程方式验证架构,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,在mose项目中,使用模式验证运行java应用程序的方法是使用该配置(使用spring时): 我遇到了一个问题,我需要在运行期间的特定时间验证我的模式,有什么方法可以实现吗 我看到hibernate用, 我将spring与hibernate一起使用,但我没有找到任何关于如何处理它的信息,我找到的唯一信息是,但它已在较旧版本的spring boot <dependency> <groupId>org.springframework.data</groupId&
java应用程序的方法是使用该配置(使用spring时):
我遇到了一个问题,我需要在运行期间的特定时间验证我的模式,有什么方法可以实现吗
我看到hibernate用,
我将spring与hibernate一起使用,但我没有找到任何关于如何处理它的信息,
我找到的唯一信息是,但它已在较旧版本的spring boot
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
org.springframework.data
spring数据jpa
2.0.4.1发布
有什么想法吗?这是解决方案,如果您的用例需要:
- 细粒度&明确控制架构的哪一部分应该是
验证
- 需要验证多个模式
- 需要验证服务未使用的模式,定时验证器正在该服务上运行
- 应用程序使用的db连接不应以任何方式受到验证的影响(也就是说,您不想从主连接池借用连接)
如果以上内容适用于您的需要,则这是如何执行计划架构验证的示例:
来源
application.yml
docker compose.yml
如果希望让SchemaValidator
重用项目中已配置的连接配置和映射信息,而不是再次定义它们以进行模式验证,你应该考虑我的解决方案,使你干燥,不需要将这些配置保持在两个不同的地方。
实际上,SchemaValidator
需要的是Metadata
实例,它只在引导Hibernate时可用。但是我们可以使用Hibernate Integrator API(如中所述)来捕获它,以便稍后进行验证
(1) 创建SchemaValidateService
,该服务实现Hibernate Integrator API以捕获元数据。还要设置一个@Scheduled
方法,以便在所需时间验证架构
@Component
public class SchemaValidateService implements Integrator {
private Metadata metadata;
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
this.metadata = metadata;
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
}
//Adjust the scheduled time here
@Scheduled(cron = "0 0/1 * * * ?")
public void validate() {
try {
System.out.println("Start validating schema");
new SchemaValidator().validate(metadata);
} catch (Exception e) {
//log the validation error here.
}
System.out.println("Finish validating schema....");
}
}
(2) 注册SchemaValidateService以休眠
@SpringBootApplication
@EnableScheduling
public class App {
@Bean
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(SchemaValidateService schemaValidateService) {
return (prop -> {
List<Integrator> integrators = new ArrayList<>();
integrators.add(schemaValidateService);
prop.put("hibernate.integrator_provider", (IntegratorProvider) () -> integrators);
});
}
}
@springboot应用程序
@使能调度
公共类应用程序{
@豆子
公共HibernatePropertiesCustomizer HibernatePropertiesCustomizer(SchemaValidateService SchemaValidateService){
返回(道具->{
列表积分器=新的ArrayList();
integrators.add(schemaValidateService);
prop.put(“hibernate.integrator\u provider”,(IntegratorProvider)(->integrators);
});
}
}
此外,此解决方案应该具有更好的性能,因为它不需要每次都创建新的数据库连接来验证架构,因为它可以从现有连接池中获取连接。这似乎是一个问题。你的用例是什么?我需要每10分钟验证一次我的模式@Turing85我想Turing85想知道为什么你需要每10分钟验证一次模式。哦,这是我们架构中的一个东西@Oresteviron的可能副本我想使用自己的配置获取元数据,但是,当我创建自己的一个时,我得到的是:在名称空间中找到了不止一个表。你的意思是你想自己再次创建元数据
,而不是重复使用hibernate已经构建的现有数据包吗?有没有担心你无法配置自己的数据包,而你想将其作为常用的hibernate实体数据包进行验证这样hibernate就已经为您构建了元数据了?如果您想自己构建元数据,应该参考其他人提出的解决方案。这个解决方案的精神是提出一些与已经提出的不同的东西,因此我们不打算自己去摆弄元数据。非常感谢!
CREATE DATABASE IF NOT EXISTS testdb;
CREATE TABLE IF NOT EXISTS `table1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `table2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
spring:
cache:
type: none
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3309/testdb?useSSL=false&nullNamePatternMatchesAll=true&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: test_user
password: test_password
testWhileIdle: true
validationQuery: SELECT 1
jpa:
show-sql: false
database-platform: org.hibernate.dialect.MySQL8Dialect
hibernate:
ddl-auto: none
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
properties:
hibernate.dialect: org.hibernate.dialect.MySQL8Dialect
hibernate.cache.use_second_level_cache: false
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: false
hibernate.hbm2ddl.auto: validate
schema-validator:
settings:
connection.driver_class: com.mysql.cj.jdbc.Driver
hibernate.dialect: org.hibernate.dialect.MySQL8Dialect
hibernate.connection.url: jdbc:mysql://localhost:3309/testdb?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
hibernate.connection.username: test_user
hibernate.connection.password: test_password
hibernate.default_schema: testdb
version: '3.0'
services:
db:
image: mysql:8.0.14
restart: always
ports:
- 3309:3306
environment:
MYSQL_ROOT_PASSWORD: test_password
MYSQL_DATABASE: testdb
MYSQL_USER: test_user
MYSQL_PASSWORD: test_password
@Component
public class SchemaValidateService implements Integrator {
private Metadata metadata;
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
this.metadata = metadata;
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
}
//Adjust the scheduled time here
@Scheduled(cron = "0 0/1 * * * ?")
public void validate() {
try {
System.out.println("Start validating schema");
new SchemaValidator().validate(metadata);
} catch (Exception e) {
//log the validation error here.
}
System.out.println("Finish validating schema....");
}
}
@SpringBootApplication
@EnableScheduling
public class App {
@Bean
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(SchemaValidateService schemaValidateService) {
return (prop -> {
List<Integrator> integrators = new ArrayList<>();
integrators.add(schemaValidateService);
prop.put("hibernate.integrator_provider", (IntegratorProvider) () -> integrators);
});
}
}