全網最全最詳細的Sharding-JDBC入門

前言

在開始以前,不得不吐槽下,全網的Sharding-JDBC的資料太少了,並且大部分資料都是1.X的版本,那是很早的版本,如今Sharding-JDBC已經發展到4.X啦。還有就是大部分都停留在說概念的層面,來回講Sharding-JDBC的一些基礎概念,實戰的demo少之又少,這還有些demo根本跑不起來。我就想問一下,親們到底本身有沒有跑過啊?哎,我真的是太難了。java


因此我就來寫個demo把,拋磚引玉下,但願各位大佬補充。若是有不想看搭建過程的,能夠直接看最後的GitHub地址,拉取代碼測試下。node

需求說明

本demo使用Sharding-JDBC完成對訂單表,訂單明細表的水平分庫水錶,首先咱們須要注意人工建立兩個庫,分別是ds0和ds1,而後再在這兩個庫裏面各新建四個表t_order0,t_order1,t_order_item0,t_order_item1,具體的建表SQL語句參考項目中的sharding-tbl-ms.sql。mysql

環境搭建

數據庫:MySQL 5.1git

JDK:64位jdk1.8github

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

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

分片配置

在application.properties配置文件中,若是不知道每項表明什麼,咱先無論,demo先跑起來再說,各個配置在接下來的文章逐一說明。數據庫

#兩個庫名
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整合的,這部分明白的直接跳過便可。express

定義實體(Order和OrderItem)

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);
    }
} 複製代碼

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);
    }
} 複製代碼

mapper映射(OrderMapper.xml和OrderItemMapper.xml)

<?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> 複製代碼

<?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> 複製代碼

dao(OrderRepository和OrderItemRepository)

@Mapper
public interface OrderRepository {

    Long addOrder(Order order);

    List<Order> list();

    Object get(Long id);

} 複製代碼

@Mapper
public interface OrderItemRepository {

    Integer addOrderItem(OrderItem orderitem);

}複製代碼

service接口(OrderServiceImpl)

@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);
    }
}複製代碼

controller(OrderController)

@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);
    }

}複製代碼

最終測試

咱們打開瀏覽器,輸入localhost:8080/add,便可返回ok,說明咱們數據插入成功啦。apache


那咱們先到數據庫裏面看看,發現數據被髮配在了ds0庫和ds1庫中,可是問題在於爲何都在t_order1表中,沒有在t_order0表中,也就是爲何在庫裏面沒有按order_id分表呢?其實問題不是在這,而是生成的訂單id爲何是都是奇數?哈哈哈,請聽下回分解。易中天上線啦。。



其餘的查詢等方法也都寫了,你們能夠本身試試哈。

GitHub地址

GitHub:

github.com/sunnysabor/…

注意

1.須要本身手動建庫,建表,具體的建表語句在sharding-tbl-ms.sql中。兩個庫都要執行一遍。

2.數據庫的鏈接配置參考本地的數據庫,注意修改配置中的帳號密碼。

結語

關注偶,領取超多學習資料哈。

相關文章
相關標籤/搜索