在开始以前,不得不吐槽下,全网的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
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);
}
} 复制代码
<?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> 复制代码
@Mapper
public interface OrderRepository {
Long addOrder(Order order);
List<Order> list();
Object get(Long id);
} 复制代码
@Mapper
public interface OrderItemRepository {
Integer addOrderItem(OrderItem orderitem);
}复制代码
@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);
}
}复制代码
@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:
注意
:
1.须要本身手动建库,建表,具体的建表语句在sharding-tbl-ms.sql中。两个库都要执行一遍。
2.数据库的链接配置参考本地的数据库,注意修改配置中的帐号密码。
关注偶,领取超多学习资料哈。