前提
有些小伙伴询问我。然后我重新审视了我的代码,发现我的解法是真的垃圾(不过是适用于其他一些场景,请依据场景而定),因为我的业务是当天的数据插入当天的表,每天一张表。这我用个毛的sharding-jdbc啊,直接用户给数据我用个拼接sql(根据日期拼接表名后缀,无关用户输入的拼接)插入到表不就好了。然后我就重构了我的屎山代码。
以下查询仍然是:按天分表,按create_time字段查询
正文
配置(依赖和application.properties)依旧是上篇sharding-jdbc的中展示的配置。有所区别的是指定分表算法策略的DateAlgorithm类(自定义的类)中多实现了一个RangeShardingAlgorithm重写doSharding以进行范围查询返回要查询表的集合。
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
// 拿到范围
Range<String> range = rangeShardingValue.getValueRange();
String lowerEndpoint = range.lowerEndpoint();
String upperEndpoint = range.upperEndpoint();
ArrayList<String> list = new ArrayList<>();
long betweendays = betweendays(lowerEndpoint, upperEndpoint);
// 算出需要查询哪些表
yesterday(new SimpleDateFormat("yyyy-MM-dd").parse(range.upperEndpoint()).getTime(),betweendays,list);
return list;
}
public void yesterday(long date, long times, Collection<String> collection){
DateFormat dateFormat=new SimpleDateFormat("yyyyMMdd");
Calendar calendar = Calendar.getInstance();
// 设置指定日期,月份需要减一
calendar.setTime(new Date(date));
String yesterdayDate=dateFormat.format(calendar.getTime());
collection.add(logicTableName+yesterdayDate);
calendar.set(Calendar.HOUR_OF_DAY,-24);
if(times>0){
times = times - 1;
yesterday(calendar.getTimeInMillis(),times,collection);
}
}
public long betweendays(String start,String end) throws Exception {
//设置转换的日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//开始时间
Date startDate = sdf.parse(start);
//结束时间
Date endDate = sdf.parse(end);
//得到相差的天数 betweenDate
return (endDate.getTime() - startDate.getTime())/(60*60*24*1000);
}
以上计算代码可以优化,留给你们啦!
到这里,我们相当于把自定义路由表的逻辑写完了。我们只需要这样用。注意,要有sharding-column的条件,本例中是create_time字段
QueryWrapper<Communication> wrapper = new QueryWrapper<>();
wrapper.between("create_time",start,end);
List<Communication> list;
list = mapper.selectList(wrapper);
使用时可能会踩的坑
不要在自己写的mapper_sql的入参中使用@Param("xxx")注解。否则会出现sharding-jdbc识别不到入参的情况。