首页 > 其他分享 >springboot~shardingsphere在非spring框架中的使用

springboot~shardingsphere在非spring框架中的使用

时间:2024-01-16 16:36:39浏览次数:28  
标签:springboot spring 数据源 ds0 public shardingsphere id new order

shardingsphere已经很方便的被springboot集成了,你只要引入sharding-jdbc-spring-boot-starter这个包就可以了,而如果是原生java的话,你就需要自己去实现了,主要是重新定义数据源,定义规则等问题,本文主要介绍原生环境下的shardingsphere的使用。

依赖引用

<dependencies>
        <!-- mysql 数据源 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <!-- HikariCP连接池 -->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>4.0.3</version>
        </dependency>

        <!-- shardingsphere分库分表 -->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-core</artifactId>
            <version>4.1.1</version> <!-- 替换成最新版本 -->
        </dependency>

        <!-- ORM -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.15.Final</version>
        </dependency>

        <!-- 生产力工具 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>

建立DataSource数据源

  • 添加了数据源,确定了mysql数据库,支持同时设置多个数据源
  • 定义了分库分表的规则
  public static DataSource createDataSource() throws SQLException {
    // 配置真实数据源
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    // 配置第一个 MySQL 数据源
    HikariDataSource ds0 = new HikariDataSource();
    ds0.setDriverClassName("com.mysql.jdbc.Driver");
    ds0.setJdbcUrl("jdbc:mysql://192.168.xx.xx:3306/sharding0");
    ds0.setUsername("root");
    ds0.setPassword("123456");
    dataSourceMap.put("ds0", ds0);

    // 配置分片规则
    TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration("t_order", "ds0.t_order_${0..2}");
    ShardingStrategyConfiguration shardingStrategyConfiguration = new StandardShardingStrategyConfiguration("order_id", new ModuloShardingAlgorithm());
    tableRuleConfig.setTableShardingStrategyConfig(shardingStrategyConfiguration);

    ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
    shardingRuleConfig.getTableRuleConfigs().add(tableRuleConfig);

    // 创建 ShardingSphere 数据源
    return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());
}

建立分表规则

/**
 * 分表算法
 */
public class ModuloShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        for (String each : availableTargetNames) {
            if (each.endsWith(String.valueOf(shardingValue.getValue() % 2))) {
                return each;
            }
        }
        throw new UnsupportedOperationException();
    }
}

源生SQL方式读取数据

static void select() throws SQLException {
    // 创建数据源
    DataSource dataSource = createDataSource();

    // 执行SQL
    try (Connection conn = dataSource.getConnection()) {
        String sql = "SELECT * FROM t_order WHERE order_id = ?";
        try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
            preparedStatement.setLong(1, 11L);
            try (ResultSet resultSet = preparedStatement.executeQuery()) {
                while (resultSet.next()) {
                    System.out.println(resultSet.getString("order_id"));
                }
            }
        }
    }
}

Hibernate方式,写入,读取数据

定义实体

@Entity
@Data
@Table(name = "t_order")
@NamedQueries({
        @NamedQuery(
                name = "findById",
                query = "FROM Order t WHERE t.orderId = :orderId"
        )
})
public class Order {
    @Id
    @Column(name = "order_id", nullable = false)
    private Long orderId;
    @Column(name = "user_id", nullable = false)
    private Long userId;
    @Column(name = "amount", nullable = false)
    private Double amount;
}

定义数据仓库

public class OrderRepository {
    // 创建EntityManagerFactory
    EntityManagerFactory entityManagerFactory;

    // 创建EntityManager
    EntityManager entityManager;

    public OrderRepository() throws SQLException {
        this.entityManagerFactory = Persistence.createEntityManagerFactory("lindDb", getProperties(Main.createDataSource()));
        this.entityManager = entityManagerFactory.createEntityManager();
    }

    private static Map<String, Object> getProperties(DataSource dataSource) {
        Map<String, Object> properties = new HashMap<>();
        properties.put("javax.persistence.nonJtaDataSource", dataSource);
        return properties;
    }

    public List<Order> findById(Long id) {
        return entityManager.createQuery("findById", Order.class).setParameter("orderId", id).getResultList();
    }

    public void save(Order order) {
        entityManager.getTransaction().begin();
        entityManager.persist(order);
        entityManager.getTransaction().commit();
        entityManager.close();
        entityManagerFactory.close();
    }
}

定义添加逻辑及测试

static void HihernateInsert() throws SQLException {
    OrderRepository orderRepository = new OrderRepository();
    Order order = new Order();
    order.setAmount(100d);
    order.setOrderId(11L);
    order.setUserId(6L);
    orderRepository.save(order);
}

根据分表的规则,这条数据会被写到t_order_1这张数据表里。

注意:当采用分表规则之后,如果你的记录主键没有按着规则存储,是无法获取到时数据的,如order_id为1的记录被存储到了t_order_0里,那这条数据将无法被找到。

标签:springboot,spring,数据源,ds0,public,shardingsphere,id,new,order
From: https://www.cnblogs.com/lori/p/17967957

相关文章

  • [spring] spring学习笔记(2): 通过xml实现依赖注入 - 特殊注入类型
    实际应用中,我们的对象可能会引用很多不同类型的东西,不单单只是几个数值对象类型在前一篇文章中,已经使用引用对象作为例子,关键在于使用ref<!--注意引用的对象要先创建Bean,id为weapon1--><beanid="player1"class="com.demo.player"> <!--通过setter注入,注意ref的......
  • springboot第48集:【思维导图】地图,面向对象,异常,功能代码
    在SpringBoot中,可以通过编写拦截器(Interceptor)来对请求进行拦截与处理。下面是一个简单的拦截器实现示例:创建一个类并实现HandlerInterceptor接口publicclassAuthInterceptorimplementsHandlerInterceptor{@OverridepublicbooleanpreHandle(HttpServletRequest......
  • Springboot上传文件大小限制处理
    今天在开发过程中遇到一个文件上传的问题io.undertow.server.RequestTooBigException:UT000020:Connectionterminatedasrequestwaslargerthan10485760Servlet容器使用的是undertow,看异常信息应该是默认存在10MB的文件大小限制。百度了一下,找到如下配置,问题得以解决,记......
  • Spring Cloud整体架构解析
    SpringCloud整体架构SpringCloud的中文名我们就暂且称呼它为“春云”吧,听上去是多么朴实无华的名字,不过呢一般名字起的低调的都是厉害角色,我们就看看SpringCloud都提供了哪些靠谱功能吧。SpringCloud是一款微服务架构的一站式解决方案,你在微服务化过程中碰到的任何问题,都可......
  • SpringSecurity表单认证(二)
    用户名+密码系统默认登录用户名:user密码每次服务启动后随机生成密码用户信息获取原理(数据库获取)实现该接口,security默认自动生成密码关闭。框架源码:packageorg.springframework.security.core.userdetails;publicinterfaceUserDetailsService{UserDetailsloa......
  • [spring] spring学习笔记(1): 通过xml实现依赖注入(1)
    依赖注入是spring框架中一个重要思想-InversionofControl(IoC)-的实现,大体上来说,就是通过配置Bean对象,让spring内置的方法来为主对象创建需要的依赖对象;打个比方,在java中,当我们想要使用某个类时,应当通过new关键字来指定,i.e.//在这里创建一个类,他需要使......
  • Spring 工具:DigestUtils md5 摘要工具
    工具类:org.springframework.util.DigestUtils作用:计算字节数组、输入流的md5摘要所在模块:spring-core方法描述Stringmd5DigestAsHex(byte[]bytes)返回字节数组的md5摘要(计算字符串)Stringmd5DigestAsHex(InputStreaminputStream)返回输入流的md5......
  • Spring 工具:StopWatch 计时器
    工具类:org.springframework.util.StopWatch作用:记录方法执行耗时,统计每个方法的耗时占比所在模块:spring-core方法描述voidstart(StringtaskName)开始一个新的监测任务,可设置任务名称。记录当前时间和任务名称voidstop()结束当前监测任务。记录任务执行......
  • 聊聊如何实现动态加载spring拦截器
    前言之前写过一篇文章聊聊如何实现热插拔AOP,今天我们继续整一个类似的话题,聊聊如何实现spring拦截器的动态加载实现核心思路groovy热加载java+事件监听变更拦截器实现步骤1、在项目的pom引入groovyGAV<dependency><groupId>org.codehaus.groovy</groupI......
  • SpringBoot自定义注解实现操作日志记录
    1、增加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>${spring-version}</version>......