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

yizhihongxing

那我就来详细讲解一下“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日

相关文章

  • 五分钟带你了解Java的接口数据校验

    介绍Java中的接口数据校验,通常使用的是验证框架Hibernate Validator。我们可以使用它来验证javabean实例的数据是否合法。 安装 Hibernate Validator 在Maven中,我们可以使用以下代码引入Hibernate Validator: <dependency> <groupId>org.hibe…

    Java 2023年6月1日
    00
  • springboot登陆过滤功能的实现代码

    下面我会详细讲解如何在Spring Boot中实现登陆过滤功能,并提供两条示例。 1. Spring Security实现登陆过滤 Spring Security是Spring官方推出的安全框架,能够实现用户认证(登陆)和授权(权限管理)功能。下面将通过一个示例来演示Spring Security实现登陆过滤的具体步骤。 添加Maven依赖 <depe…

    Java 2023年5月20日
    00
  • 详解MyBatis的Dao层实现和配置文件深入

    详解MyBatis的Dao层实现和配置文件深入 MyBatis是一款非常流行的ORM框架,在Java开发中被广泛应用。Dao层是MyBatis的核心层之一,负责实现与数据库的交互。本文将详解MyBatis的Dao层实现和配置文件的深入,包括Dao层的实现、配置文件的解析和使用等方面。 一、Dao层实现 在MyBatis的Dao层实现中,我们主要依赖以下三个方…

    Java 2023年5月20日
    00
  • 启用springboot security后登录web页面需要用户名和密码的解决方法

    启用 SpringBoot Security 后登录 Web 页面需要用户名和密码的解决方法主要涉及到如何添加用户和授权认证的过程。 添加用户 可以通过在 application.yml 文件中配置用户名和密码来添加用户: spring: security: user: name: admin # 用户名 password: password # 密码 ro…

    Java 2023年5月20日
    00
  • 基于SpringBoot实现上传2种方法工程代码实例

    下面是关于“基于SpringBoot实现上传2种方法工程代码实例”的攻略: 1. 概述 SpringBoot提供了很多方便开发的功能,其中之一就是文件上传。文件上传需要前端页面和后端接口配合实现。前端页面负责UI界面展示和获取用户输入,后端接口负责接收上传的文件并保存在服务器上。 2. 文件上传方法 2.1. 前端表单上传 前端表单上传是指用户在页面上填写表…

    Java 2023年5月20日
    00
  • Java 关键字static详解及实例代码

    Java关键字static详解及实例代码 什么是Java的关键字static Java的关键字static用于声明类、方法和变量,它可以用来标识一个类、方法和变量是否为静态的。 当我们把一个成员变量或成员方法定义为静态时,它可以被所有对象所共享,无需实例化对象就可以直接访问它们。而非静态的成员变量和成员方法必须通过实例化后才能进行访问。 Java关键字sta…

    Java 2023年5月30日
    00
  • 你知道将Bean交给Spring容器管理有几种方式(推荐)

    将Bean交给Spring容器管理的方式 在Spring中,我们可以将Bean交给Spring容器管理,从而实现依赖注入和控制反转。下面是将Bean交给Spring容器管理的几种方式。 1. 使用@Component注解 @Component是Spring中最常用的注解之一,用于将一个类声明为Bean,并交给Spring容器管理。下面是一个简单的示例: @C…

    Java 2023年5月18日
    00
  • Java实现一个简单的长轮询的示例代码

    下面是Java实现一个简单的长轮询的示例代码的攻略。 什么是长轮询? 长轮询指的是在客户端发起请求后,服务器会一直等待直到有数据更新或超时才返回。相较于短轮询,长轮询可以减少客户端和服务器之间的请求次数,提高网络传输效率。 实现长轮询的步骤 在Java中实现长轮询的步骤如下: 客户端发起一个GET请求,服务器接收请求并判断是否有新的数据更新; 如果有新的数据…

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