前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >全网最全最详细的Sharding-JDBC入门

全网最全最详细的Sharding-JDBC入门

作者头像
陈琛
发布2020-06-12 16:14:33
2K3
发布2020-06-12 16:14:33
举报
文章被收录于专栏:陈琛的Redis文章陈琛的Redis文章

前言

在开始之前,不得不吐槽下,全网的Sharding-JDBC的资料太少了,而且大部分资料都是1.X的版本,那是很早的版本,现在Sharding-JDBC已经发展到4.X啦。还有就是大部分都停留在说概念的层面,来回讲Sharding-JDBC的一些基础概念,实战的demo少之又少,这还有些demo根本跑不起来。我就想问一下,亲们到底自己有没有跑过啊?哎,我真的是太难了。

所以我就来写个demo把,抛砖引玉下,希望各位大佬补充。如果有不想看搭建过程的,可以直接看最后的GitHub地址,拉取代码测试下。

需求说明

本demo使用Sharding-JDBC完成对订单表,订单明细表的水平分库水表,首先我们需要注意人工创建两个库,分别是ds0和ds1,然后再在这两个库里面各新建四个表t_order0,t_order1,t_order_item0,t_order_item1,具体的建表SQL语句参考项目中的sharding-tbl-ms.sql。

环境搭建

数据库:MySQL 5.1

JDK:64位jdk1.8

应用框架:spring-boot-2.0.3 ,Mybatis 3.4

Sharding-JDBC:sharding-jdbc-spring-boot-starter 3.1.0.M1

分片配置

在application.properties配置文件中,如果不知道每项代表什么,咱先不管,demo先跑起来再说,各个配置在接下来的文章逐一说明。

代码语言:javascript
复制
#两个库名
sharding.jdbc.datasource.names=ds0,ds1

#第一个库的配置信息
sharding.jdbc.datasource.ds0.type=org.apache.commons.dbcp.BasicDataSource
sharding.jdbc.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds0.url=jdbc:mysql://localhost:3306/ds0
sharding.jdbc.datasource.ds0.username=root
sharding.jdbc.datasource.ds0.password=root

#第一个库的配置信息
sharding.jdbc.datasource.ds1.type=org.apache.commons.dbcp.BasicDataSourcesharding.jdbc.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds1.url=jdbc:mysql://localhost:3306/ds1
sharding.jdbc.datasource.ds1.username=root
sharding.jdbc.datasource.ds1.password=root

#订单表的配置信息
sharding.jdbc.config.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order$->{0..1}
sharding.jdbc.config.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
sharding.jdbc.config.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order$->{order_id % 2}
sharding.jdbc.config.sharding.tables.t_order.key-generator-column-name=order_id

#订单明细表的配置信息
sharding.jdbc.config.sharding.tables.t_order_item.actual-data-nodes=ds$->{0..1}.t_order_item$->{0..1}
sharding.jdbc.config.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
sharding.jdbc.config.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item$->{order_id % 2}
sharding.jdbc.config.sharding.tables.t_order_item.key-generator-column-name=order_item_id

#订单表和订单明细表的绑定关系
sharding.jdbc.config.sharding.binding-tables=t_order,t_order_item
sharding.jdbc.config.sharding.broadcast-tables=t_config

#默认配置
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=user_id
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds$->{user_id % 2}


代码编写

为了减少篇幅,代码只是简单贴了些,这部分代码其实就是spring-boot和mybatis整合的,这部分明白的直接跳过即可。

01

定义实体(Order和OrderItem)

代码语言:javascript
复制


public class Order implements Serializable {

    private static final long serialVersionUID = 661434701950670670L;

    private long orderId;

    private int userId;

    private String status;

    private List<OrderItem> items=new ArrayList<>();

    //setter和getter方法
     .....
    @Override
    public String toString() {
        return String.format("order_id: %s, user_id: %s, status: %s", orderId, userId, status);
    }
}
代码语言:javascript
复制
public class OrderItem implements Serializable {

    private static final long serialVersionUID = 263434701950670170L;

    private long orderItemId;

    private long orderId;

    private int userId;

    private String status;

     //setter和getter方法
      .....
    @Override
    public String toString() {
        return String.format("order_item_id:%s, order_id: %s, user_id: %s, status: %s", orderItemId, orderId, userId, status);
    }
}
代码语言:javascript
复制

02

mapper映射

(OrderMapper.xml和OrderItemMapper.xml)

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.forezp.sharedingjdbcmasterslavetables.repository.OrderRepository">
    <resultMap id="baseResultMap" type="com.forezp.sharedingjdbcmasterslavetables.entity.Order">
        <result column="order_id" property="orderId" jdbcType="INTEGER"/>
        <result column="user_id" property="userId" jdbcType="INTEGER"/>
        <result column="status" property="status" jdbcType="VARCHAR"/>
    </resultMap>

    <resultMap type="Order" id="orderMap">
        <id column="order_id" property="orderId"/>
        <result column="user_id" property="userId"/>
        <result column="status" property="status"/>

        <collection property="items" ofType="OrderItem">
            <id column="order_item_id" property="orderItemId"/><!-- 这里的column对应的是下面查询的别名,而不是表字段名 -->
            <result column="user_id" property="userId"/><!-- property对应JavaBean中的属性名 -->
            <result column="status" property="status"/>
        </collection>
    </resultMap>

    <insert id="addOrder" useGeneratedKeys="true" keyProperty="orderId">
        INSERT INTO t_order (user_id, status) VALUES (#{userId,jdbcType=INTEGER}, #{status,jdbcType=VARCHAR});
    </insert>

    <select id="list" resultMap="baseResultMap">
        SELECT * FROM t_order;
    </select>

    <select id="get" resultMap="orderMap">
        SELECT * FROM t_order,t_order_item where t_order.order_id=t_order_item.order_id and t_order.order_id=#{orderId,jdbcType=INTEGER};
    </select>
</mapper>
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.forezp.sharedingjdbcmasterslavetables.repository.OrderItemRepository">
<resultMap id="baseResultMap" type="com.forezp.sharedingjdbcmasterslavetables.entity.OrderItem">
    <result column="order_item_id" property="orderItemId" jdbcType="INTEGER"/>
    <result column="order_id" property="orderId" jdbcType="INTEGER"/>
    <result column="user_id" property="userId" jdbcType="INTEGER"/>
    <result column="status" property="status" jdbcType="VARCHAR"/>
</resultMap>

<insert id="addOrderItem" useGeneratedKeys="true" keyProperty="orderItemId">
        INSERT INTO t_order_item (order_id,user_id, status) VALUES (#{orderId,jdbcType=INTEGER},#{userId,jdbcType=INTEGER}, #{status,jdbcType=VARCHAR});
    </insert>
</mapper>

03

dao(OrderRepository和OrderItemRepository)

代码语言:javascript
复制
@Mapper
public interface OrderRepository {

    Long addOrder(Order order);

    List<Order> list();

    Object get(Long id);

}


代码语言:javascript
复制
@Mapper
public interface OrderItemRepository {

    Integer addOrderItem(OrderItem orderitem);

}


04

service接口(OrderServiceImpl)

代码语言:javascript
复制
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderRepository orderRepository;
    @Autowired
    OrderItemRepository orderItemRepository;

    @Override
    public Long addOrder(Order order) {
        orderRepository.addOrder(order);

        OrderItem orderItem=new OrderItem();
        orderItem.setOrderId(order.getOrderId());
        orderItem.setUserId(order.getUserId());
        orderItem.setStatus("insert");
        orderItemRepository.addOrderItem(orderItem);
        return order.getOrderId();
    }

    @Override
    public List<Order> list() {
        return orderRepository.list();
    }

    @Override
    public Object get(Long id){
        return orderRepository.get(id);
    }
}


05

controller(OrderController)

代码语言:javascript
复制
@RestController
public class OrderController {

    Logger logger= LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private OrderService orderService;

    @GetMapping("/orders")
    public Object list() {
        return orderService.list();
    }

    @GetMapping("/add")
    public Object add() {
        for(int i=100;i<150;i++) {
            Order order = new Order();
            order.setUserId(i);
            order.setStatus("insert");
           long resutl=   orderService.addOrder(order);
            logger.info("insert:"+order.toString()+" result:"+resutl);
        }
        return "ok";
    }

    @GetMapping("/get")
    public Object get() {
        return orderService.get(386632135886241793L);
    }

}
代码语言:javascript
复制

最终测试

我们打开浏览器,输入localhost:8080/add,即可返回ok,说明我们数据插入成功啦。

代码语言:javascript
复制

那我们先到数据库里面看看,发现数据被发配在了ds0库和ds1库中,但是问题在于为什么都在t_order1表中,没有在t_order0表中,也就是为什么在库里面没有按order_id分表呢?其实问题不是在这,而是生成的订单id为什么是都是奇数?哈哈哈,请听下回分解。易中天上线啦。。

其他的查询等方法也都写了,大家可以自己试试哈。

GitHub地址

GitHub:

https://github.com/sunnysabor/script-java/tree/release/sharding_jdbc

注意

1.需要自己手动建库,建表,具体的建表语句在sharding-tbl-ms.sql中。两个库都要执行一遍。

2.数据库的连接配置参考本地的数据库,注意修改配置中的账号密码。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 学习Java的小姐姐 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据库:MySQL 5.1
  • 在application.properties配置文件中,如果不知道每项代表什么,咱先不管,demo先跑起来再说,各个配置在接下来的文章逐一说明。
  • 为了减少篇幅,代码只是简单贴了些,这部分代码其实就是spring-boot和mybatis整合的,这部分明白的直接跳过即可。
    • 定义实体(Order和OrderItem)
      • mapper映射
        • (OrderMapper.xml和OrderItemMapper.xml)
          • dao(OrderRepository和OrderItemRepository)
            • service接口(OrderServiceImpl)
              • controller(OrderController)
              • GitHub地址
              相关产品与服务
              云数据库 MySQL
              腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档