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日

相关文章

  • Spring Data JPA系列JpaSpecificationExecutor用法详解

    Spring Data JPA系列JpaSpecificationExecutor用法详解 什么是 JpaSpecificationExecutor JpaSpecificationExecutor 是 Spring Data JPA 提供的一个接口,它提供了使用 JPA Criteria API 进行查询、分页、排序等操作的方法。在 Repository …

    Java 2023年6月2日
    00
  • Spring Boot如何配置内置Tomcat的maxPostSize值

    在Spring Boot中,我们可以通过配置内置Tomcat的maxPostSize值来控制POST请求的最大允许大小。下面我将详细讲解如何实现此功能。 方法一:通过配置application.properties文件 我们可以在Spring Boot项目的application.properties文件中添加以下配置: # 设置内置Tomcat的maxPo…

    Java 2023年5月20日
    00
  • Java 反射(Reflect)详解

    Java 反射(Reflect)详解 什么是反射? 反射是指Java程序可以检查自身的能力,并且在运行时获取和操作自身的类、接口、方法和属性等信息。Java反射提供了一种机制使得一个程序在运行期间可以获取自身的信息并且可以操作该类的内部属性、方法和构造方法。 反射的作用 反射主要有如下应用场景: 动态创建对象或获取已有对象的信息; 调用对象的方法; 访问和修…

    Java 2023年5月26日
    00
  • Springmvc和ajax如何实现前后端交互

    在 Web 开发中,前后端交互是非常重要的。Spring MVC 和 Ajax 可以很好地实现前后端交互。本文将详细讲解 Spring MVC 和 Ajax 如何实现前后端交互的完整攻略,并提供两个示例说明。 1. Spring MVC 和 Ajax 简介 Spring MVC 是一个基于 Java 的 Web 框架,它可以帮助我们构建 Web 应用程序。A…

    Java 2023年5月18日
    00
  • springmvc学习笔记-返回json的日期格式问题的解决方法

    下面是“springmvc学习笔记-返回json的日期格式问题的解决方法”的完整攻略: Spring MVC 返回JSON的日期格式问题的解决方法 Spring MVC框架中,我们通常会使用JSON作为数据返回格式,但是在返回JSON数据的时候,日期格式往往会出现一些问题,本文将详细介绍如何解决Spring MVC返回JSON的日期格式问题。 问题描述 在S…

    Java 2023年5月26日
    00
  • 解析Tomcat的启动脚本–startup.bat

    解析Tomcat的启动脚本–startup.bat 什么是startup.bat文件 startup.bat是Tomcat服务器的启动脚本之一,通常在Windows操作系统中使用。该脚本文件位于Tomcat的bin目录下,用于启动Tomcat服务器及其Web应用程序。 启动流程 startup.bat启动Tomcat服务器的流程如下: 检查JAVA_HOM…

    Java 2023年5月19日
    00
  • Spring security如何重写Filter实现json登录

    下面是详细讲解“Spring security如何重写Filter实现json登录”的完整攻略。 什么是Spring Security? Spring Security 是一个基于 Spring 的安全框架,提供了完善的安全管理功能,能够有效地帮助我们实现安全的身份认证、授权、攻击防护等。在使用 Spring Security 的过程中,通常需要进行配置和扩…

    Java 2023年5月20日
    00
  • Java通俗易懂讲解泛型

    以下是《Java通俗易懂讲解泛型》的完整攻略。 什么是泛型? 泛型是一种让类或方法在定义时,可以指定一些类型参数,以增加代码的灵活性和复用性的机制。Java引入泛型的目的是为了让程序员写出更加安全且健壮的代码,同时减少代码的冗余。 泛型的语法 下面是泛型的语法: class Class_Name<T, U, V…> { // 类定义中使用泛型…

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