主要内容

Apache ShardingSphere

Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈。Spring集成Apache ShardingSphere 是一套目前比较好的分库分表的方案。

Apache ShardingSphere JDBC 目前只支持同构数据库,本文通用自定义数据源实现异构数据库(spring boot + jpa + oracle + mysql)的分库分表。

版本:

spring boot V2.6.1

Apache ShardingSphere V5.1.0

更新历史

Apache ShardingSphere JDBC 目前只支持同构数据库, 可通用自定义数据源实现异构数据库(oracle + mysql)的分库分表。

以 oracle 数据库 作为 ShardingSphere JDBC 支持的主数据库。

主要步骤:

DataSource
EntityManagerFactory
EntityManager
TransactionManager
JdbcTemplate

源码

pom

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.1</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
        <version>5.1.0</version>
    </dependency>
</dependencies>

Application

@SpringBootApplication(exclude = JtaAutoConfiguration.class) //使用ShardingSphere的分布式管理
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(XgfyBridgeApplication.class, args);
    }

}

DataSource

Apache ShardingSphere 的数据源作为主DataSource

@Configuration
public class DataSourceConfig {

    @Autowired
    @Qualifier("shardingSphereDataSource")
    private DataSource shardingSphereDataSource;  // 使用ShardingSphere 自动装载的 DataSource

    @Bean(name = "primaryDataSource")
    @Primary
    @Qualifier("primaryDataSource")
    public DataSource primaryDatasource() {
        return shardingSphereDataSource;
    }

}

多数据源配置

  • 优先数据源

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryPrimary",
            transactionManagerRef = "transactionManagerPrimary",
            basePackages = {"xxx.xxxx"}) //设置Repository所在位置
    public class PrimaryConfig {
    
        @Autowired
        private JpaProperties jpaProperties;
    
    
        @Autowired
        @Qualifier("primaryDataSource")
        private DataSource primaryDataSource;
    
    
        // 2) EntityManagerFactory
        @Primary
        @Bean(name = "entityManagerFactoryPrimary")
        public EntityManagerFactory entityManagerFactory() {
            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            vendorAdapter.setDatabase(Database.ORACLE);
            vendorAdapter.setGenerateDdl(false);
            vendorAdapter.setShowSql(true);
            LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
            factory.setJpaVendorAdapter(vendorAdapter);
            factory.setPersistenceUnitName("default");
            factory.setPackagesToScan("xxxxxxxxx.entity");
            factory.setDataSource(primaryDataSource);
            factory.setJpaPropertyMap(jpaProperties.getProperties());
            factory.afterPropertiesSet();
            return factory.getObject();
        }
    
        
        // 3) EntityManager
        @Bean(name = "entityManagerPrimary")
        @Primary
        public EntityManager entityManager(@Qualifier("entityManagerFactoryPrimary") EntityManagerFactory entityManagerFactory){
            return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
        }
    
        
        // 4) TransactionManager
        @Bean(name = "transactionManagerPrimary")
        @Primary
        public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactoryPrimary") EntityManagerFactory entityManagerFactory){
            JpaTransactionManager txManager = new JpaTransactionManager();
            txManager.setEntityManagerFactory(entityManagerFactory);
            return txManager;
        }
    
        
        // 5) JdbcTemplate
        @Bean(name = "jdbcTemplateSharding")
        @Primary
        public JdbcTemplate jdbcTemplateSharding() {
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(primaryDataSource);
            return jdbcTemplate;
        }
    }
    
  • 其他数据源

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryYixing",
            transactionManagerRef = "transactionManagerYixing",
            basePackages = {"xx.xxxx"}) //设置Repository所在位置
    public class SecondConfig {
        @Autowired
        private JpaProperties jpaProperties;
    
    
        @Bean(name = "yixingDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.yixing")
        public DataSource yixingDataSource() {
            return DataSourceBuilder.create().build();
        }
    
    
        @Bean(name = "entityManagerYixing")
        public EntityManager entityManager() {
            return entityManagerFactoryyixing().createEntityManager();
        }
    
    
    
        @Bean(name = "entityManagerFactoryYixing")
        public EntityManagerFactory entityManagerFactoryyixing() {
            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            vendorAdapter.setDatabase(Database.MYSQL);
            vendorAdapter.setGenerateDdl(false);
            vendorAdapter.setShowSql(true);
            LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
            factory.setJpaVendorAdapter(vendorAdapter);
            factory.setPersistenceUnitName("yixing");
            factory.setPackagesToScan("xxxx.entity");
            factory.setDataSource(yixingDataSource());
            factory.setJpaPropertyMap(jpaProperties.getProperties());
            factory.afterPropertiesSet();
            return factory.getObject();
        }
    
    
        @Bean(name = "transactionManageryixing")
        public PlatformTransactionManager transactionManageryixing(@Qualifier("entityManagerFactoryYixing") EntityManagerFactory entityManagerFactory){
            JpaTransactionManager txManager = new JpaTransactionManager();
            txManager.setEntityManagerFactory(entityManagerFactory);
            return txManager;
        }
    
        @Bean(name = "jdbcTemplateYixing")
        public JdbcTemplate jdbcTemplateYixing() {
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(yixingDataSource());
            return jdbcTemplate;
        }
    }
    

yml文件

spring:
  thymeleaf:
    cache: false
  jpa:
    hibernate:
      ddl-auto: none
      database-platform: org.hibernate.dialect.Oracle12cDialect
    open-in-view: false
    show-sql: true

  datasource:
    yixing:
      database-platform: org.hibernate.dialect.MySQL8Dialect
      type: com.zaxxer.hikari.HikariDataSource
      jdbc-url: jdbc:mysql://192.168.1.x:3306/qz?serverTimezone=UTC&useSSL=false
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: "xxx"
      password: "xxx"
      hikari:
        maximumPoolSize: 50
        poolName: yixing_HikariPool

  shardingsphere:
    enabled: true
    datasource:
      names: ds-master, ds-dr
      ds-master:
        type: com.zaxxer.hikari.HikariDataSource
        jdbc-url: jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.x)(PORT = 1521) )  (CONNECT_DATA =(SERVICE_NAME = orcl)) )
        driver-class-name: oracle.jdbc.OracleDriver
        username: xxx
        password: xxx
        hikari:
          maximumPoolSize: 50
          poolName: master_HikariPool
      ds-dr:
        type: com.zaxxer.hikari.HikariDataSource
        jdbc-url: jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.x)(PORT = 1521) )  (CONNECT_DATA =(SERVICE_NAME = ORCL)) )
        driver-class-name: oracle.jdbc.OracleDriver
        username: "xxx"
        password: "xxx"
        hikari:
          maximumPoolSize: 50
          poolName: dr_HikariPool
    rules:
      sharding:
        # tables -----------------------------------------------------
        tables:
          t_acid_result_dr:
            actual-data-nodes: ds-master.t_acid_result_dr_$->{0..31}
            table-strategy:
              standard:
                sharding-column: id_card_hash
                sharding-algorithm-name: acid-inline
            key-generate-strategy:
              column: id
              key-generator-name: mysnowflake
          t_acid_result_yx:
            actual-data-nodes: ds-master.t_acid_result_yx_$->{0..31}
            table-strategy:
              standard:
                sharding-column: id_card_hash
                sharding-algorithm-name: acid-yx-inline
            key-generate-strategy:
              column: id
              key-generator-name: yxsnowflake
          t_machan_check_dr:
            actual-data-nodes: ds-master.t_machan_check_dr


        # key-generators ------------------------
        key-generators:
          mysnowflake:
            type: SNOWFLAKE
            props:
              worker-id: 11
          yxsnowflake:
            type: SNOWFLAKE
            props:
              worker-id: 12
        # sharding-algorithms ------------------------------------------------
        sharding-algorithms:
          acid-inline:
            type: INLINE
            props:
              algorithm-expression: t_acid_result_dr_$->{id_card_hash % 32}
          acid-yx-inline:
            type: INLINE
            props:
              algorithm-expression: t_acid_result_yx_$->{id_card_hash % 32}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐