热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用Sharding-JDBC对数据进行分片处理

如何使用Sharding-JDBC对数据进行分片处理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人

如何使用Sharding-JDBC对数据进行分片处理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

前言

Sharding-JDBC是ShardingSphere的第一个产品,也是ShardingSphere的前身。

它定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

  • 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。

  • 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等支持任意实现JDBC规范的数据库。

  • 目前支持MySQL,Oracle,SQLServer和PostgreSQL。

Sharding-JDBC的使用需要我们对项目进行一些调整:结构如下

ShardingSphere文档地址

如何使用Sharding-JDBC对数据进行分片处理

这里使用的是springBoot项目改造

一、加入依赖


    com.alibaba
    druid
    1.1.9



    com.dangdang
    sharding-jdbc-core
    1.5.4



    org.kcsm.common
    kcsm-idgenerator
    3.0.1

二、修改application.yml配置文件

#启动接口
server:
  port: 30009
spring:
  jpa:
    database: mysql
    show-sql: true
    hibernate:
#      修改不自动更新表
      ddl-auto: none
#数据源0定义,这里只是用了一个数据源,各位客官可以根据自己的需求定义多个数据源
database0:
  databaseName: database0
  url: jdbc:mysql://kcsm-pre.mysql.rds.aliyuncs.com:3306/dstest?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezOne=Hongkong
  username: root
  password: kcsm@111
  driverClassName: com.mysql.jdbc.Driver

三、数据源定义

package com.lzx.code.codedemo.config;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
/**
 * 描述:数据源0定义
 *
 * @Auther: lzx
 * @Date: 2019/9/9 15:19
 */
@Data
@ConfigurationProperties(prefix = "database0")
@Component
public class Database0Config {
    private String url;
    private String username;
    private String password;
    private String driverClassName;
    private String databaseName;
    public DataSource createDataSource() {
        DruidDataSource result = new DruidDataSource();
        result.setDriverClassName(getDriverClassName());
        result.setUrl(getUrl());
        result.setUsername(getUsername());
        result.setPassword(getPassword());
        return result;
    }
}

四、数据源分配算法实现

package com.lzx.code.codedemo.config;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
 * 描述:数据源分配算法
 *
 * 这里我们只用了一个数据源,所以所有的都只返回了数据源0
 *
 * @Auther: lzx
 * @Date: 2019/9/9 15:27
 */
@Component
public class DatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm {
    @Autowired
    private Database0Config database0Config;
    /**
     *  = 条件时候返回的数据源
     * @param collection
     * @param shardingValue
     * @return
     */
    @Override
    public String doEqualSharding(Collection collection, ShardingValue shardingValue) {
        return database0Config.getDatabaseName();
    }
    /**
     *  IN 条件返回的数据源
     * @param collection
     * @param shardingValue
     * @return
     */
    @Override
    public Collection doInSharding(Collection collection, ShardingValue shardingValue) {
        List result = new ArrayList();
        result.add(database0Config.getDatabaseName());
        return result;
    }
    /**
     * BETWEEN 条件放回的数据源
     * @param collection
     * @param shardingValue
     * @return
     */
    @Override
    public Collection doBetweenSharding(Collection collection, ShardingValue shardingValue) {
        List result = new ArrayList();
        result.add(database0Config.getDatabaseName());
        return result;
    }
}

五、数据表分配算法

package com.lzx.code.codedemo.config;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.LinkedHashSet;
/**
 * 描述: 数据表分配算法的实现
 *
 * @Auther: lzx
 * @Date: 2019/9/9 16:19
 */
@Component
public class TableShardingAlgorithm implements SingleKeyTableShardingAlgorithm {
    /**
     * = 条件时候返回的数据源
     * @param collection
     * @param shardingValue
     * @return
     */
    @Override
    public String doEqualSharding(Collection collection, ShardingValue shardingValue) {
        for (String eaach:collection) {
            Long value = shardingValue.getValue();
            value = value >> 22;
            if(eaach.endsWith(value%10+"")){
                return eaach;
            }
        }
        throw new IllegalArgumentException();
    }
    /**
     * IN 条件返回的数据源
     * @param tableNames
     * @param shardingValue
     * @return
     */
    @Override
    public Collection doInSharding(Collection tableNames, ShardingValue shardingValue) {
        Collection result = new LinkedHashSet<>(tableNames.size());
        for (Long value : shardingValue.getValues()) {
            for (String tableName : tableNames) {
                value = value >> 22;
                if (tableName.endsWith(value % 10 + "")) {
                    result.add(tableName);
                }
            }
        }
        return result;
    }
    /**
     * BETWEEN 条件放回的数据源
     * @param tableNames
     * @param shardingValue
     * @return
     */
    @Override
    public Collection doBetweenSharding(Collection tableNames, ShardingValue shardingValue) {
        Collection result = new LinkedHashSet<>(tableNames.size());
        Range range = shardingValue.getValueRange();
        for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
            for (String each : tableNames) {
                Long value = i >> 22;
                if (each.endsWith(i % 10 + "")) {
                    result.add(each);
                }
            }
        }
        return result;
    }
}

六、数据源配置

package com.lzx.code.codedemo.config;
import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.keygen.DefaultKeyGenerator;
import com.dangdang.ddframe.rdb.sharding.keygen.KeyGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
 * 描述:数据源配置
 *
 * @Auther: lzx
 * @Date: 2019/9/9 15:21
 */
@Configuration
public class DataSourceConfig {
    @Autowired
    private Database0Config database0Config;
    @Autowired
    private DatabaseShardingAlgorithm databaseShardingAlgorithm;
    @Autowired
    private TableShardingAlgorithm tableShardingAlgorithm;
    @Bean
    public DataSource getDataSource() throws SQLException {
        return buildDataSource();
    }
    private DataSource buildDataSource() throws SQLException {
        //分库设置
        Map dataSourceMap = new HashMap<>(2);
        //添加两个数据库database0和database1
        dataSourceMap.put(database0Config.getDatabaseName(), database0Config.createDataSource());
        //设置默认数据库
        DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap, database0Config.getDatabaseName());
        //分表设置,大致思想就是将查询虚拟表Goods根据一定规则映射到真实表中去
        TableRule orderTableRule = TableRule.builder("user")
                .actualTables(Arrays.asList("user_0", "user_1", "user_2", "user_3", "user_4", "user_5", "user_6", "user_7", "user_8", "user_9"))
                .dataSourceRule(dataSourceRule)
                .build();
        //分库分表策略
        ShardingRule shardingRule = ShardingRule.builder()
                .dataSourceRule(dataSourceRule)
                .tableRules(Arrays.asList(orderTableRule))
                .databaseShardingStrategy(new DatabaseShardingStrategy("ID", databaseShardingAlgorithm))
                .tableShardingStrategy(new TableShardingStrategy("ID", tableShardingAlgorithm)).build();
        DataSource dataSource = ShardingDataSourceFactory.createDataSource(shardingRule);
        return dataSource;
    }
    @Bean
    public KeyGenerator keyGenerator() {
        return new DefaultKeyGenerator();
    }
}

七、开始测试

定义一个实体

package com.lzx.code.codedemo.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
/**
 * 描述: 用户
 *
 * @Auther: lzx
 * @Date: 2019/7/11 15:39
 */
@Entity(name = "USER")
@Getter
@Setter
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public class User {
    /**
     * 主键
     */
    @Id
    @GeneratedValue(generator = "idUserConfig")
    @GenericGenerator(name ="idUserConfig" ,strategy="org.kcsm.common.ids.SerialIdGeneratorSnowflakeId")
    @Column(name = "ID", unique = true,nullable=false)
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    /**
     * 用户名
     */
    @Column(name = "USER_NAME",length = 100)
    private String userName;
    /**
     * 密码
     */
    @Column(name = "PASSWORD",length = 100)
    private String password;
}

定义实体DAO

package com.lzx.code.codedemo.dao;
import com.lzx.code.codedemo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
/**
 * 描述: 用户dao接口
 *
 * @Auther: lzx
 * @Date: 2019/7/11 15:52
 */
@RepositoryRestResource(path = "user")
public interface UserDao extends JpaRepository,JpaSpecificationExecutor {
}

测试类,插入1000条user数据

package com.lzx.code.codedemo;
import com.lzx.code.codedemo.dao.RolesDao;
import com.lzx.code.codedemo.dao.UserDao;
import com.lzx.code.codedemo.entity.Roles;
import com.lzx.code.codedemo.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CodeDemoApplicationTests {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RolesDao rolesDao;
    @Test
    public void contextLoads() {
        User user = null;
        Roles roles = null;
        for(int i=0;i<1000;i++){
            user = new User(
                    null,
                    "lzx"+i,
                    "123456"
            );
            roles = new Roles(
                    null,
                    "角色"+i
            );
            rolesDao.save(roles);
            userDao.save(user);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

效果:数据被分片存储到0~9的数据表中

如何使用Sharding-JDBC对数据进行分片处理 

如何使用Sharding-JDBC对数据进行分片处理

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程笔记行业资讯频道,感谢您对编程笔记的支持。


推荐阅读
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 本文介绍了在 Spring Boot 中使用 JPA 进行数据删除操作时遇到的 SQL 错误及其解决方法。错误表现为:删除操作失败,原因是无法打开 JPA EntityManager 以进行事务处理。 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • C# 中 SQLite 报错:在 "\\s\\" 附近出现语法错误,如何解决? ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 在处理数据库中所有用户表的彻底清除时,目前尚未发现单一命令能够实现这一目标。因此,需要采用一种较为繁琐的方法来逐个删除相关表及其结构。具体操作可以通过编写PL/SQL脚本来实现,该脚本将动态生成并执行删除表的SQL语句。尽管这种方法相对复杂,但在缺乏更简便手段的情况下,仍是一种有效的解决方案。未来或许可以通过数据库管理工具或更高版本的数据库系统提供更简洁的处理方式。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 为了确保数据库的高效运行,本文介绍了一种方法,通过编写定时任务脚本来自动清理 `order` 表中状态为 0 或为空的无效订单记录。该脚本使用 PHP 编写,并设置时区为中国标准时间,每 10 分钟执行一次,以保持数据库的整洁和性能优化。此外,还详细介绍了如何配置定时任务以及脚本的具体实现步骤。 ... [详细]
  • 在Linux系统中避免安装MySQL的简易指南
    在Linux系统中避免安装MySQL的简易指南 ... [详细]
  • 在使用 Cacti 进行监控时,发现已运行的转码机未产生流量,导致 Cacti 监控界面显示该转码机处于宕机状态。进一步检查 Cacti 日志,发现数据库中存在 SQL 查询失败的问题,错误代码为 145。此问题可能是由于数据库表损坏或索引失效所致,建议对相关表进行修复操作以恢复监控功能。 ... [详细]
author-avatar
如痴如醉as_961
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有