java master slave数据库配置不工作

new9mtju  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(108)

我想在我的Spring Boot 应用程序中实现主从DB artitechure,我只是使用2个正常的DB示例,Havent在DB级别配置了一些东西,我已经在下面列出了我的配置和错误,有人可以帮助吗?做一些配置需要在数据库级别做,因为我只是测试。请告诉我。
下面是我的DataSourceConfig:

@Configuration
public class DataSourceConfig extends HikariConfig {

    @Value("${spring.entity.scan.packages}")
    private String packageToScan;

    @Value("${spring.datasource.master.url}")
    private String masterDbUrl;

    @Value("${spring.datasource.master.username}")
    private String masterDbUserName;

    @Value("${spring.datasource.master.password}")
    private String masterDbPassword;

    @Value("${master.database.maxconnection}")
    private int masterDbMaxConnection;

    @Value("${spring.datasource.slave.url}")
    private String slaveDbUrl;

    @Value("${spring.datasource.slave.username}")
    private String slaveDbUserName;

    @Value("${spring.datasource.slave.password}")
    private String slaveDbPassword;

    @Value("${master.database.maxconnection}")
    private int slaveDbMaxConnection;


    @Primary
    @Bean(name = "masterDataSource")
    public DataSource masterDataSource() {
        HikariConfig masterConfig = new HikariConfig();
        masterConfig.setPoolName(DataSourceConfig.class.getName()+"_master");
        System.out.println(masterDbUrl);
        System.out.println(masterDbUserName);
        System.out.println(masterDbPassword);
        System.out.println(masterDbMaxConnection);
        masterConfig.setJdbcUrl(masterDbUrl);
        masterConfig.setUsername(masterDbUserName);
        masterConfig.setPassword(masterDbPassword);
        masterConfig.setMaximumPoolSize(masterDbMaxConnection);
        return new HikariDataSource(masterConfig);
    }

    @Bean(name = "slaveDataSource")
    public DataSource slaveDataSource() {
        HikariConfig slaveConfig = new HikariConfig();
        slaveConfig.setPoolName(DataSourceConfig.class.getName()+"_slave");
        System.out.println(slaveDbUrl);
        System.out.println(slaveDbUserName);
        System.out.println(slaveDbPassword);
        System.out.println(slaveDbMaxConnection);
        slaveConfig.setJdbcUrl(slaveDbUrl);
        slaveConfig.setUsername(slaveDbUserName);
        slaveConfig.setMaximumPoolSize(slaveDbMaxConnection);
        slaveConfig.setPassword(slaveDbPassword);
        return new HikariDataSource(slaveConfig);
    }

    @Bean
    public DataSource routingDataSource() {
        Map<Object, Object> targetDataSources = new LinkedHashMap<>();
        RoutingDataSourceConfiguration routingDataSourceConfiguration = new RoutingDataSourceConfiguration();
        DataSource master = this.masterDataSource();
        targetDataSources.put(DataSourceTypes.MASTER, master);
        DataSource slave = this.slaveDataSource();
        targetDataSources.put(DataSourceTypes.SLAVE, slave);
        routingDataSourceConfiguration.setTargetDataSources(targetDataSources);
        routingDataSourceConfiguration.setDefaultTargetDataSource(master);
        return routingDataSourceConfiguration;
    }

    @Bean
    public DataSource dataSource() {
        return new LazyConnectionDataSourceProxy(routingDataSource());
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource());
        factory.setPackagesToScan(packageToScan);
        JpaVendorAdapter vendor = new HibernateJpaVendorAdapter();
        factory.setJpaVendorAdapter(vendor);

        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        properties.setProperty("hibernate.show_sql", "true");

        factory.setJpaProperties(properties);
        return factory;
    }

    @Bean
    @Primary
    public PlatformTransactionManager transactionManager
            (EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(entityManagerFactory);
        return tm;
    }

}

下面是我的RoutingDataSourceConfiguration:

public class RoutingDataSourceConfiguration extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        boolean isReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
        logger.info(isReadOnly);
        if(isReadOnly) {
            return DataSourceTypes.SLAVE;
        } else {
            return DataSourceTypes.MASTER;
        }
    }
}

这是我的 www.example.com

database.db.name=db_delivery
spring.datasource.master.url=jdbc:mysql://171.46.7.224/${database.db.name}?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.master.username=user
spring.datasource.master.password=pass
spring.datasource.master.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.slave.url=jdbc:mysql://171.43.7.214/${database.db.name}?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.slave.username=user
spring.datasource.slave.password=pass
spring.datasource.slave.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = update
spring.datasource.maximum-pool-size=10
spring.jpa.properties.hibernate.jdbc.batch_size=30
master.database.maxconnection=100
spring.entity.scan.packages=com.project

server.port=8080

spring.security.user.name=System
spring.security.user.password=pass

以下是我的repo:

@Repository
public interface JobsCycleCountRepo extends JpaRepository<JobsCycleCount,Long>  {

  @Transactional(readOnly = true)
  List<WarehouseJobsCycleCount> findAllByJobId(Long jobId);
}

以下是我的实体WarehouseJobsCycleCount:

@Entity
@Table(name = "warehouse_jobs_cycle_count")
@Data
public class WarehouseJobsCycleCount {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Column(name = "job_id")
  private Long jobId;

  @Column(name = "sku_id")
  private String skuId;

  @Column(name = "location_id")
  private Long locationId;

  @Enumerated(EnumType.STRING)
  private WarehouseJobCycleCountStatus status;

}

现在,当我通过控制器通过任何服务方法调用这个repo方法时,我会得到这样的错误:

SQL Error: 1054, SQLState: 42S22
2023-04-27 14:53:40.919 ERROR 10375 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Unknown column 'warehousej0_.jobId' in 'field list'
2023-04-27 14:53:41.060 ERROR 10375 --- [nio-8080-exec-1] c.d.w.exceptions.ControllerAdvisor       : Custom Exception: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
2023-04-27 14:53:42.256  WARN 10375 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet]

如何解决这个问题?我已经被困在这两天,但没有任何工作。

wnvonmuf

wnvonmuf1#

根据您提供的代码和错误消息,您面临的问题似乎与SQL错误有关。错误消息表明存在未知列“warehousej0_”。字段列表中的jobId'。
以下是一些建议,可帮助您调试和解决此问题:
1.验证列名:仔细检查数据库表中对应于'jobId'字段的列名。确保列名拼写正确,并且与代码中使用的列名匹配。列名和字段名之间可能存在打字错误或不匹配。
1.检查表和列Map:确保实体类(JobsCycleCount)中的表和列Map是准确的。确保实体类属性用适当的JPA注解(@Column@Table等)正确注解。)。请特别注意'jobId'字段的Map。
1.验证数据库架构:确认数据库模式是最新的,并且与实体类中定义的预期结构相匹配。确保数据库表中存在所需的列及其对应的数据类型。
1.检查数据库连接:确保应用程序可以成功连接到主数据库和从数据库。验证www.example中两个数据库的连接详细信息(URL、用户名、密码)是否正确 www.example.com 文件。
1.验证数据访问逻辑:检查存储库和服务类中的逻辑。确保正确定义查询和联接以检索所需的数据。请注意查询中可能使用的任何命名约定或别名。
1.启用SQL日志记录:在应用程序中启用SQL日志记录,以查看Hibernate正在执行的实际SQL查询。这可以帮助您识别生成的SQL语句的任何问题。您可以将以下行添加到您的www.example中 www.example.com 文件以启用SQL日志记录:

spring.jpa.show-sql=true

使用此配置,您将看到在控制台或日志文件中记录的SQL查询。
通过仔细检查这些方面,您应该能够识别并解决您遇到的SQL错误。如果问题仍然存在,提供实体类代码(JobsCycleCount)和任何相关的实体Map将有助于进一步调查问题。

相关问题