一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓!”算法吧~其中数据库查询分页算法是每个后端开发者必备的算法技能。
一、前言
昨天复用了以前的分页代码,发现分页居然失效了。原因是我之前用的是pg数据库,现在用的是mysql数据库,我也不知道是不是数据库的原因引起的。但是我直觉感觉不是。pg可以分页,mysql就变成了全量查询。有点奇怪。所以在网上查找方法解决。
二、我使用的分页工具
1、mapper
@Repository
public interface MerchantMapper extends BaseMapper<Merchant>{
}
2、service
/**
* 查询商户列表
* @param param
* @return
*/
public PageUtils queryPage(Map<String, Object> param) {
QueryWrapper<Merchant> qw = new QueryWrapper<Merchant>();
Page<Merchant> page = new Page<>(Integer.parseInt(param.get("pageNo").toString()), Integer.parseInt(param.get("pageSize").toString()));
if (param.containsKey("orgOuName")) {
qw.like("org_ou_name", param.get("orgOuName").toString());
}
qw.orderByAsc("create_Time");
IPage<Merchant> merchantIPage = merchantMapper.selectPage(page, qw);
return new PageUtils(merchantIPage);
}
3、controller
@ApiOperation(value = "查询所有商户列表", notes = "查询所有商户列表")
@PostMapping("pageList")
public ResponseData<PageUtils> queryPage(@RequestBody Map<String, Object> param) {
PageUtils pageUtils = merchantService.queryPage(param);
return ResponseData.success(pageUtils);
}
4、实体
@Data
@EqualsAndHashCode(callSuper=false)
@TableName(value = "base_etp_merchant", schema = "库名")
public class Merchant implements Serializable{
}
5、分页工具:PageUtils
public class PageUtils implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private int totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int currPage;
/**
* 列表数据
*/
private List<?> list;
/**
* 分页
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
}
/**
* 分页
*/
public PageUtils(IPage<?> page) {
this.list = page.getRecords();
this.totalCount = (int)page.getTotal();
this.pageSize = (int)page.getSize();
this.currPage = (int)page.getCurrent();
this.totalPage = (int)page.getPages();
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrPage() {
return currPage;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
}
6、分页设置MybatisPlusConfig
@Configuration
@MapperScan("cn.xxx.blockchain.dao")
public class MybatisPlusConfig {
/**
* 分页插件
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
改造前后的区别就是
改造前的page
改造后的page
还有就是增加了 MybatisPlusConfig 这个类。居然就好了,虽然不知道为什么,但是在这里记录下来。
Java分库分表方案和实现方式
一、引言
随着互联网的快速发展,海量数据和高并发访问成为了许多应用面临的挑战。传统的单一数据库和单表架构已经无法满足大规模数据处理和存储的需求。为了解决这个问题,分库分表(Sharding)技术应运而生。分库分表是一种将数据分散到多个数据库或表中的技术,以提高系统的扩展性和性能。本文将详细介绍Java分库分表的方案和实现方式。
二、分库分表方案
- 分库策略
分库策略是将数据分散到多个数据库中,以提高数据库的读写能力和扩展性。常见的分库策略有:
(1)基于范围的分库策略:根据数据的范围(如时间、ID等)将数据分配到不同的数据库中。例如,根据时间范围将不同月份的数据分配到不同的数据库中。
(2)基于哈希的分库策略:通过哈希函数将数据的关键字哈希成固定长度的哈希值,然后根据哈希值的大小决定数据存储在哪个数据库中。这种策略可以保证数据的均匀分布和负载均衡。
(3)基于目录的分库策略:建立一个中心化的目录服务,记录每个数据项的存储位置信息。客户端通过查询目录服务获取数据存储的具体位置,然后直接与相应的数据库进行交互。
- 分表策略
分表策略是将一个大表分散到多个小表中,以提高单表查询的性能和并发处理能力。常见的分表策略有:
(1)垂直分表:将一个大表的列进行拆分,形成多个小表。每个小表只包含原表的部分列,从而降低了单次查询的数据量。垂直分表适用于列存储的数据库系统,如HBase等。
(2)水平分表:将一个大表的行进行拆分,形成多个小表。每个小表包含原表的一部分行。水平分表适用于行存储的数据库系统,如MySQL等。
三、Java实现方式
- 手动实现
手动实现分库分表需要开发者根据具体的业务场景和数据量大小自行设计和实现数据路由、数据同步和事务管理等逻辑。这种方式灵活度高,但开发难度较大,需要具备一定的分布式系统开发经验。常见的开源框架有MyCAT、ShardingSphere等,它们提供了丰富的分库分表功能和扩展点,可以方便地与Java应用集成。
- 使用中间件实现
使用中间件实现分库分表可以简化开发过程,提高开发效率。常见的中间件有ShardingSphere-JDBC、MyCAT-JDBC等。这些中间件提供了SQL解析、数据路由、数据同步等功能,开发者只需要在配置文件中指定数据源和规则,就可以快速实现分库分表的功能。同时,这些中间件还支持动态调整数据源和规则,方便系统扩展和维护。
四、总结与展望
分库分表是解决大规模数据处理和存储的有效手段之一。根据具体的业务场景和数据量大小选择合适的分库分表方案和实现方式可以提高系统的扩展性和性能。随着分布式系统的不断发展,未来会有更多优秀的分库分表技术和中间件涌现出来,为开发者提供更加便捷和高效的解决方案。同时,随着云计算和大数据技术的普及,云原生和湖仓一体的架构也将成为新的发展趋势,它们将进一步推动分库分表技术的演进和应用。