Mqsql使用Sharding-JDBC案例实战 2

简介: Mqsql使用Sharding-JDBC案例实战

5.3 添加商品

实体类,参考基础工程:

DAO实现

@Mapper
@Component
public interface ProductDao {
  //添加商品基本信息    
     @Insert("insert into product_info(store_info_id,product_name,spec,region_code,price)
value(#{storeInfoId},#{productName},#{spec},#{regionCode},#{price})")
    @Options(useGeneratedKeys = true,keyProperty = "productInfoId",keyColumn = "id")
    int insertProductInfo(ProductInfo productInfo);
//添加商品描述信息    
    @Insert("insert into product_descript(product_info_id,descript,store_info_id) value(#
{productInfoId},#{descript},#{storeInfoId})")
    @Options(useGeneratedKeys = true,keyProperty = "id",keyColumn = "id")
    int insertProductDescript(ProductDescript productDescript);
}

service实现,针对垂直分库的两个库,分别实现店铺服务、商品服务

@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductDao productDao;
    @Override
    @Transactional
    public void createProduct(ProductInfo product) {
        ProductDescript productDescript = new ProductDescript();
        productDescript.setDescript(product.getDescript());
        productDao.insertProductInfo(product);//新增商品基本信息
        productDescript.setProductInfoId(product.getProductInfoId());
        productDescript.setStoreInfoId(product.getStoreInfoId()); //冗余店铺信息
        productDao.insertProductDescript(productDescript);//新增商品描述信息
    }
}

controller 实现:

/**
 * 卖家商品展示
 */
@RestController
public class SellerController {
    @Autowired
    private ProductService productService;
    @PostMapping("/products")
    public String createProject(@RequestBody ProductInfo productInfo) {
        productService.createProduct(productInfo);
        return "创建成功!";
    }

单元测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ShardingJdbcDemoBootstrap.class)
public class ShardingTest {
    @Autowired
    ProductService productService;
    @Test
    public void testCreateProduct(){
        for(long i=1;i<10;i++){
            //store_info_id,product_name,spec,region_code,price,image_url
            ProductInfo productInfo = new ProductInfo();
            productInfo.setProductName("Java编程思想"+i);
            productInfo.setDescript("Java编程思想是一本非常好的Java教程"+i);
            productInfo.setRegionCode("110000");
            productInfo.setStoreInfoId(1);
            productInfo.setPrice(new BigDecimal(i));
            productService.createProduct(productInfo);
        }
    }
    ...

这里使用了sharding-jdbc所提供的全局主键生成方式之一雪花算法,来生成全局业务唯一主键。

通过添加商品接口新增商品进行分库验证,store_info_id为偶数的数据在product_db_1,为奇数的数据在

product_db_2。

通过 添加商品接口新增商品进行分表验证,product_id为偶数的数据在product_info_1、product_descript_1,为奇数的数据在product_info_2、product_descript_2。

5.4 查询商品

Dao实现:

在ProductDao中定义商品查询方法:

@Select("select i.*, d.descript, r.region_name placeOfOrigin " +
        "from product_info i join product_descript d on i.id = d.product_info_id " +
        "join region r on r.region_code = i.region_code order by i.id desc limit #{start},#
{pageSize}")
List<ProductInfo> selectProductList(@Param("start")int start,@Param("pageSize") int pageSize);

Service实现:

在ProductServiceImpl定义商品查询方法:

@Override
public List<ProductInfo> queryProduct(int page,int pageSize) {
    int start = (page‐1)*pageSize;
    return productDao.selectProductList(start,pageSize);
}

Controller实现:

@GetMapping(value = "/products/{page}/{pageSize}")
public List<ProductInfo> queryProduct(@PathVariable("page")int page,@PathVariable("pageSize")int
pageSize){
    return productService.queryProduct(page,pageSize);
}

单元 测试:

@Test
public void testSelectProductList(){
    List<ProductInfo> productInfos = productService.queryProduct(1,10);
    System.out.println(productInfos);
}

通过查询商品列表接口,能够查询到所有分片的商品信息,关联的地理区域,店铺信息正确。


总结:

分页查询是业务中最常见的场景,Sharding-jdbc支持常用关系数据库的分页查询,不过Sharding-jdbc的分页功能比较容易让使用者误解,用户通常认为分页归并会占用大量内存。 在分布式的场景中,将 LIMIT 10000000 , 10改写为 LIMIT 0, 10000010 ,才能保证其数据的正确性。 用户非常容易产生ShardingSphere会将大量无意义的数据加载至内存中,造成内存溢出风险的错觉。 其实大部分情况都通过流式归并获取数据结果集,因此ShardingSphere 会通过结果集的next方法将无需取出的数据全部跳过,并不会将其存入内存。但同时需要注意的是,由于排序的需要,大量的数据仍然需要传输到Sharding-Jdbc的内存空间。 因此,采用LIMIT

这种方式分页,并非最佳实践。 由于LIMIT并不能通过索引查询数据,因此如果可以保证ID的连续性,通过ID进行分页是比较好的解决方案,例如:

SELECT * FROM t_order WHERE id > 100000 AND id <= 100010 ORDER BY id;

或通过记录上次查询结果的最后一条记录的ID进行下一页的查询,例如:

SELECT * FROM t_order WHERE id > 10000000 LIMIT 10;

排序功能是由Sharding-jdbc的排序归并来完成,由于在SQL中存在 ORDER BY 语句,因此每个数据结果集自身是有序的,因此只需要将数据结果集当前游标指向的数据值进行排序即可。 这相当于对多个有序的数组进行排序,归并排序是最适合此场景的排序算法。

5.5 统计商品

本小节实现商品总数统计,商品分组统计

Dao实现,在ProductDao中定义:

//总数统计
@Select("select count(1) from product_info")
int selectCount();
//分组统计
@Select("select count(1) as num from product_info group by region_code having num>1 ORDER BY
region_code ASC")
List<Map> selectProductGroupList();

单元测试:

@Test
public void testSelectCount(){
    int i = productDao.selectCount();
    System.out.println(i);
}
@Test
public void testSelectGroupList(){
    List<Map> maps = productDao.selectProductGroupList();
    System.out.println(maps);
}

总结:

分组统计

分组统计也是业务中常见的场景,分组功能的实现由Sharding-jdbc分组归并完成。分组归并的情况最为复杂,它分为流式分组归并和内存分组归并。 流式分组归并要求SQL的排序项与分组项的字段必须保持一致,否则只能通过内存归并才能保证其数据的正确性。

举例说明,假设根据科目分片,表结构中包含考生的姓名(为了简单起见,不考虑重名的情况)和分数。通过SQL

获取每位考生的总分,可通过如下SQL:

SELECT name, SUM(score) FROM t_score GROUP BY name ORDER BY name;

在分组项与排序项完全一致的情况下,取得的数据是连续的,分组所需的数据全数存在于各个数据结果集的当前游标所指向的数据值,因此可以采用流式归并。如下图所示。

进行归并时,逻辑与排序归并类似。 下图展现了进行next调用的时候,流式分组归并是如何进行的。

通过图中我们可以看到,当进行第一次next调用时,排在队列首位的t_score_java将会被弹出队列,并且将分组值同为“Jetty”的其他结果集中的数据一同弹出队列。 在获取了所有的姓名为“Jetty”的同学的分数之后,进行累加操作,那么,在第一次next调用结束后,取出的结果集是“Jetty”的分数总和。 与此同时,所有的数据结果集中的游标都将下移至数据值“Jetty”的下一个不同的数据值,并且根据数据结果集当前游标指向的值进行重排序。 因此,包含名字顺着第二位的“John”的相关数据结果集则排在的队列的前列。

目录
相关文章
|
SQL Java 大数据
Hive实战(03)-深入了解Hive JDBC:在大数据世界中实现数据交互
Hive实战(03)-深入了解Hive JDBC:在大数据世界中实现数据交互
639 1
|
算法 Java 关系型数据库
Mqsql使用Sharding-JDBC案例实战 1
Mqsql使用Sharding-JDBC案例实战
63 0
|
Java 关系型数据库 MySQL
Java Web实战 | JDBC案例:实现图书管理
在项目开发中,应用程序需要的数据基本都是存放在数据库中的。对数据的管理过程离不开数据库。本文将运用JDBC API编写一个实现基本数据库操作(添加、修改、删除、查询)的应用程序,实现对图书信息的管理。 完成此项目的具体步骤如下。
355 0
Java Web实战 | JDBC案例:实现图书管理
|
SQL 算法 Java
springboot中sharding jdbc绑定表配置实战
springboot中sharding jdbc绑定表配置实战
|
SQL 算法 Java
基于springboot的sharding jdbc广播表配置实战
基于springboot的sharding jdbc广播表配置实战
|
SQL 消息中间件 自然语言处理
看完这一篇,ShardingSphere-jdbc 实战再也不怕了
谈到分库分表中间件时,我们自然而然的会想到 ShardingSphere-JDBC 。 这篇文章,我们聊聊 ShardingSphere-JDBC 相关知识点,并实战演示一番。
2086 0
|
canal 监控 关系型数据库
Elastic实战:通过logstash-input-jdbc实现mysql8.0全量/增量同步至ES7.x
上一期我们讲解了如何通过canal实现增量/全量同步但因为canal本身基于binlog。所以在binlog开启之前的历史数据是不会同步的。 因此要实现真正的全量同步,还需要针对binlog开启之前的历史数据进行全量同步。
1041 2
Elastic实战:通过logstash-input-jdbc实现mysql8.0全量/增量同步至ES7.x
|
JavaScript 小程序 Oracle
Sharding JDBC 实战:分布式事务处理
Sharding JDBC 实战:分布式事务处理
|
Java 数据库连接 数据库
【JDBC实战】水果库存系统 [设计阶段]
学习水果库存系统 [设计阶段]。
242 0
【JDBC实战】水果库存系统 [设计阶段]
|
SQL Oracle 关系型数据库
JDBC 实战 MYSQL 和 JSP 网站开发| 学习笔记
快速学习 JDBC 实战 MYSQL 和 JSP 网站开发
252 0
JDBC 实战 MYSQL 和 JSP 网站开发| 学习笔记