springboot jpa分库分表项目实现过程详解

那我就来详细讲解一下“springboot jpa分库分表项目实现过程详解”的完整攻略。

1. 什么是分库分表

分库分表是一种水平扩展数据库的方式。 在一个分库分表的架构中,一个应用的数据被分为多个库或表。 这些库或表通常基于某个可配置的关键字划分数据。 比如用户ID可以作为划分关键字,用户的数据会根据关键字散列到多个库或表中。

2. 分库分表的优缺点

2.1 优点

  • 提高扩展性:分库分表可以解决大容量数据存储的问题。采用分布式架构后,系统的处理能力可以通过水平扩展来提高。
  • 提升性能:分库分表通过分散数据来大大节省了查询的时间。每个节点都可以独立完成自己所分配的任务,从而大大降低了数据集中式管理所带来的性能瓶颈。

2.2 缺点

  • 数据一致性难以保证:当系统采用分库分表后,需要面对跨多库查询(Join)、数据分散到不同业务系统的问题,由此带来的数据一致性难题。
  • 分散维护:在一个分布式系统中,系统的维护会是一个十分复杂的问题,为此,需要引入一些新的机制来保证分布式系统的正常运行。

3. jpa分库分表的实现

3.1 概述

JPA是Java Persistence API的简称,是Java规范定义的ORM框架,可以通过对象关系映射技术将Java类映射到关系数据库的表中,并通过JPA提供的API来进行操作。JPA分库分表实现是基于sharding-jdbc的分库分表插件完成。

3.2 实现过程

  1. 在pom.xml文件中引入sharding-jdbc相关的依赖。
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>5.0.0-alpha</version>
</dependency>
  1. 配置数据源,分库、分表策略,以及分库、分表数据源的映射关系。
spring:
  shardingsphere:
    datasource:
      names: ds0, ds1
      ds0:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/database0?useSSL=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
      ds1:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/database1?useSSL=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    sharding:
      tables:
        order_item:
          actual-data-nodes: ds$->{0..1}.order_item$->{0..1}
          table-strategy:
            inline:
              sharding-column: order_id
              algorithm-expression: order_item$->{order_id % 2}
          key-generator:
            type: SNOWFLAKE
          key-generator-column-name: id
      binding-tables:
        - order_item
      default-database-strategy:
        standard:
          sharding-column: user_id
          precise-algorithm-class-name: com.example.shardingjpa.config.PreciseShardingAlgorithm
      default-table-strategy:
        standard:
          sharding-column: order_id
          precise-algorithm-class-name: com.example.shardingjpa.config.PreciseShardingAlgorithm
  1. 在Spring Boot项目中配置sharding-jdbc的数据源、事务管理器等,以及扫描JPA实体类所在的包,启用sharding-jdbc的应用程序上下文(ApplicationContext)。
@Configuration
@EnableTransactionManagement
@EnableConfigurationProperties(ShardingJdbcProperties.class)
@MapperScan(basePackages = "com.example.shardingjpa.mapper")
public class DataSourceConfig {

    @Autowired(required = false)
    private List<DataSource> dataSources;

    @Autowired
    private ShardingJdbcProperties shardingJdbcProperties;

    @Bean
    public DataSource dataSource() throws SQLException {
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(dataSources)) {
            for (DataSource dataSource : dataSources) {
                dataSourceMap.put(dataSource.getClass().getName(), dataSource);
            }
        }
        ShardingRuleConfiguration shardingRuleConfiguration = shardingJdbcProperties.getShardingRule().getShardingRuleConfiguration(dataSourceMap);
        return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfiguration, new Properties());
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws SQLException {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(dataSource());
        entityManagerFactory.setPackagesToScan("com.example.shardingjpa.domain");
        entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        entityManagerFactory.setJpaProperties(jpaProperties());
        return entityManagerFactory;
    }

    @Bean
    public JpaTransactionManager jpaTransactionManager() throws SQLException {
        return new JpaTransactionManager(entityManagerFactory().getObject());
    }

    private Properties jpaProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "true");
        return properties;
    }

    @Bean
    public ShardingJdbcTemplate shardingJdbcTemplate(DataSource dataSource) {
        return new ShardingJdbcTemplate(dataSource);
    }

}
  1. 创建JPA实体类,并在实体类上添加ShardingSphere的分库分表注解。
@Entity
@Table(name = "t_order_item")
@org.apache.shardingsphere.shardingjdbc.api.ShardingSphereTable(logicTable = "order_item",
        actualDataNodes = "ds${0..1}.order_item${0..1}",
        tableStrategy =
        @org.apache.shardingsphere.shardingjdbc.api.ShardingSphereStrategy(
                standard = @org.apache.shardingsphere.shardingjdbc.api.ShardingSphereStandardStrategy(
                        shardingColumn = "order_id",
                        preciseAlgorithm = "com.example.shardingjpa.config.PreciseOrderShardingAlgorithm",
                        rangeAlgorithm = "com.example.shardingjpa.config.RangeOrderShardingAlgorithm"
                )
        ))
public class OrderItem {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "order_id")
    private Long orderId;

    @Column(name = "user_id")
    private Long userId;

    private String status;

    // getter/setter

}
  1. 编写JPA Repository接口。
@Repository
public interface OrderItemRepository extends JpaRepository<OrderItem, Long>,
        JpaSpecificationExecutor<OrderItem> {

    List<OrderItem> findByOrderId(Long orderId);

}

3.3 示例1:根据订单ID查询订单明细

@Service
public class OrderService {

    @Autowired
    private OrderItemRepository orderItemRepository;

    public List<OrderItem> getOrderItemsByOrderId(Long orderId) {
        return orderItemRepository.findByOrderId(orderId);
    }

}

3.4 示例2:根据分片键查询订单明细

@Service
public class OrderService {

    @Autowired
    private ShardingJdbcTemplate shardingJdbcTemplate;

    public List<OrderItem> getOrderItemsByUserId(Long userId) {
        String sql = "select * from t_order_item where user_id = ?";
        return shardingJdbcTemplate.query(sql, new Object[]{userId},
                BeanPropertyRowMapper.newInstance(OrderItem.class));
    }

}

以上就是“springboot jpa分库分表项目实现过程详解”的完整攻略,希望能帮助到您。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot jpa分库分表项目实现过程详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 创造世界上最简单的 PHP 开发模式第1/5页

    下面我将详细讲解如何创造世界上最简单的 PHP 开发模式。 步骤1:准备工作 在开始之前,需要确保已经安装了PHP环境和开发工具,例如使用xampp,wampserver或者直接安装PHP和Apache。如果你还没有安装,请先进行安装。 步骤2:创建项目文件夹 首先,我们需要创建一个新的项目文件夹,并将其命名为“myproject”。可以按照以下步骤进行操作…

    Java 2023年6月15日
    00
  • 使用kafka-console-consumer.sh不停报WARN的问题及解决

    下面是使用kafka-console-consumer.sh不停报WARN的问题及解决的完整攻略: 问题描述 在使用kafka-console-consumer.sh脚本消费kafka消息时,可能会出现不停报WARN的问题,警告信息如下: WARN [Consumer clientId=consumer-1, groupId=my-group] Connec…

    Java 2023年5月20日
    00
  • springboot与springmvc基础入门讲解

    让我来为您详细讲解“springboot与springmvc基础入门讲解”的完整攻略。 简介 Spring Boot是Spring Framework的一个扩展框架,它为Spring开发者提供了更快的开发体验。Spring MVC是一个经典的MVC框架,负责接收HTTP请求并将其转换为相应的处理程序,通常由Controller和Model组成。 本文将对Sp…

    Java 2023年5月15日
    00
  • Java图形化界面设计之容器(JFrame)详解

    Java图形化界面设计之容器(JFrame)详解 1. 容器的概念 在Java图形化界面设计中,容器指的是能够包含其他可视组件(如按钮、文本框等)的组件。容器可以是顶层容器(如JFrame、JDialog等)或内部容器(如JPanel、JTabbedPane等)。 JFrame是一个非常常用的顶层容器,它是Java AWT中的Frame类的一个子类,在Swi…

    Java 2023年5月23日
    00
  • 构建Maven多模块项目的方法

    构建Maven多模块项目的方法可以分为以下步骤: 创建Maven父项目 在命令行下进入项目文件夹,执行以下命令: mvn archetype:generate -DgroupId=com.example -DartifactId=my-parent-project -DarchetypeArtifactId=maven-archetype-quickstar…

    Java 2023年5月19日
    00
  • Spring Boot如何使用Undertow代替Tomcat

    使用Undertow代替Tomcat是Spring Boot提高应用性能以及减少内存消耗的一种方式。下面是Spring Boot如何使用Undertow代替Tomcat的完整攻略: 1. 添加Undertow依赖 在Spring Boot项目的pom.xml文件中添加以下依赖: <dependency> <groupId>org.sp…

    Java 2023年6月2日
    00
  • 浅析Java.IO输入输出流 过滤流 buffer流和data流

    浅析Java.IO输入输出流 过滤流 Buffer流和Data流 什么是Java IO Java IO 是针对输入和输出数据的流处理 API。Java IO 库中包含了一组类和接口,提供了对标准输入、输出和文件系统的访问。 在 Java IO 中,数据承载的载体为流(stream)。流是指在数据源和数据目的地之间建立起的一条虚拟的传输通道,数据按照字节的方式…

    Java 2023年5月26日
    00
  • 订单30分钟未支付自动取消怎么实现?

    目录 了解需求 方案 1:数据库轮询 方案 2:JDK 的延迟队列 方案 3:时间轮算法 方案 4:redis 缓存 方案 5:使用消息队列 了解需求 在开发中,往往会遇到一些关于延时任务的需求。最全面的Java面试网站 例如 生成订单 30 分钟未支付,则自动取消 生成订单 60 秒后,给用户发短信 对上述的任务,我们给一个专业的名字来形容,那就是延时任务…

    Java 2023年4月28日
    00
合作推广
合作推广
分享本页
返回顶部