src/main/java/com/whyc/controller/BatttestdataInfController.java
@@ -38,6 +38,7 @@ public Map<String, Object> getDevTinfByWeek(@RequestParam Integer uid){ return service.getDevTinfByWeek(uid); } @ApiOperation(value = "获取设备的充放电记录") @GetMapping("getTinfById") public Response getTinfById(@RequestParam Integer devId){ src/main/java/com/whyc/controller/DevalarmDataHisController.java
New file @@ -0,0 +1,33 @@ package com.whyc.controller; import com.whyc.dto.DalmDto; import com.whyc.dto.Response; import com.whyc.service.BatttestdataInfService; import com.whyc.service.DevalarmDataService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.text.ParseException; import java.util.Map; @RestController @Api(tags = "历史告警管理") @RequestMapping("tinf") public class DevalarmDataHisController { @Autowired private DevalarmDataService dataService; @ApiOperation(value = "测试实时告警") @PostMapping("getDAlmInf") public Response getDAlmInf(@RequestParam int uid, @RequestBody DalmDto dto){ return dataService.getDAlmInf(uid,dto); } @ApiOperation(value = "获取历史告警") @PostMapping("getDAlmHis") public Response getDAlmHis( @RequestBody DalmDto dto) throws ParseException { return dataService.getDAlmHis(dto); } } src/main/java/com/whyc/dto/DalmDto.java
New file @@ -0,0 +1,19 @@ package com.whyc.dto; import lombok.Data; import java.util.Date; @Data public class DalmDto { private Integer devType; private Integer almId; private Date startTime; private Date endTime; private int pageNum; private int pageSize; private Integer uid; private String tableName; private Integer limitStart; private Integer limitEnd; } src/main/java/com/whyc/mapper/DevalarmDataMapper.java
New file @@ -0,0 +1,12 @@ package com.whyc.mapper; import com.whyc.dto.DalmDto; import com.whyc.pojo.db_alarm.DevalarmData; import org.apache.ibatis.annotations.Param; import java.util.List; public interface DevalarmDataMapper extends CustomMapper<DevalarmData>{ //获取设备告警信息 List<DevalarmData> getDAlmInf(@Param("dto") DalmDto dto); } src/main/java/com/whyc/pojo/db_alarm/DevalarmData.java
New file @@ -0,0 +1,71 @@ package com.whyc.pojo.db_alarm; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; /** * <p> * 设备实时告警记录表 * </p> * * @author lxw * @since 2024-09-11 */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName(schema = "db_alarm",value ="tb_devalarm_data") @ApiModel(value="DevalarmData对象", description="设备实时告警记录表") public class DevalarmData implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "自增主键") @TableId(value = "num", type = IdType.AUTO) private int num; @ApiModelProperty(value = "设备ID") private Integer devId; @ApiModelProperty(value = "告警ID") private Integer almId; @ApiModelProperty(value = "告警类型【1-上限告警 2-下限告警】") private Integer almSignalId; @ApiModelProperty(value = "告警开始时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date almStarttime; @ApiModelProperty(value = "告警值") private Float almValue; @ApiModelProperty(value = "告警是否确认") private Integer almIsConfirmed; @ApiModelProperty(value = "确认用户ID") private Integer confirmedUid; @ApiModelProperty(value = "确认时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date confirmedTime; @ApiModelProperty(value = "告警结束时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date almEndtime; @ApiModelProperty(value = "告警记录状态[0-实时告警 1-历史告警 2-取消告警]") private Integer almClearedType; } src/main/java/com/whyc/pojo/db_alarm/DevalarmDataYear.java
New file @@ -0,0 +1,71 @@ package com.whyc.pojo.db_alarm; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; /** * <p> * 设备历史告警记录表 * </p> * * @author lxw * @since 2024-09-11 */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName("tb_devalarm_data_Year") @ApiModel(value="DevalarmDataYear对象", description="设备历史告警记录表") public class DevalarmDataYear implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "自增主键") @TableId(value = "num", type = IdType.AUTO) private int num; @ApiModelProperty(value = "设备ID") private Integer devId; @ApiModelProperty(value = "告警ID") private Integer almId; @ApiModelProperty(value = "告警类型【1-上限告警 2-下限告警】") private Integer almSignalId; @ApiModelProperty(value = "告警开始时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date almStarttime; @ApiModelProperty(value = "告警值") private Float almValue; @ApiModelProperty(value = "告警是否确认") private Integer almIsConfirmed; @ApiModelProperty(value = "确认用户ID") private Integer confirmedUid; @ApiModelProperty(value = "确认时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date confirmedTime; @ApiModelProperty(value = "告警结束时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date almEndtime; @ApiModelProperty(value = "告警记录状态[0-实时告警 1-历史告警 2-取消告警]") private Integer almClearedType; } src/main/java/com/whyc/service/DevalarmDataService.java
New file @@ -0,0 +1,44 @@ package com.whyc.service; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.whyc.dto.DalmDto; import com.whyc.dto.Response; import com.whyc.mapper.DevalarmDataMapper; import com.whyc.pojo.db_alarm.DevalarmData; import com.whyc.pojo.db_alarm.DevalarmDataYear; import com.whyc.pojo.db_user.UserInf; import com.whyc.util.ActionUtil; import com.whyc.util.SubTablePageInfoUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.text.ParseException; import java.util.List; @Service public class DevalarmDataService { @Autowired(required = false) private DevalarmDataMapper mapper; @Autowired(required = false) private SubTablePageInfoUtil service; //获取设备告警信息 public Response getDAlmInf(int uid, DalmDto dto) { PageHelper.startPage(dto.getPageNum(),dto.getPageSize()); dto.setUid(uid); List<DevalarmData> list=mapper.getDAlmInf(dto); PageInfo pageInfo=new PageInfo(list); return new Response().setII(1,list!=null,pageInfo,"获取设备告警信息"); } //获取历史告警 public Response getDAlmHis(DalmDto dto) throws ParseException { UserInf uinf= ActionUtil.getUser(); dto.setUid(uinf.getUid()); PageInfo pageInfo=service.getPageInfo(dto.getPageNum(),dto.getPageSize(),dto.getStartTime(),dto.getEndTime() ,"db_alarm", "tb_devalarm_data", dto); return new Response().setII(1,pageInfo!=null,pageInfo,"获取设备告警信息"); } } src/main/java/com/whyc/service/MybatisSqlExecuteService.java
@@ -1,6 +1,7 @@ package com.whyc.service; import com.whyc.mapper.CallBack; import com.whyc.util.ActionUtil; import com.whyc.util.DateUtil; import net.sf.json.JSONArray; import net.sf.json.JSONObject; @@ -39,7 +40,7 @@ Object obj=rs.getObject(i); if(obj instanceof java.util.Date ){ //jsonObject.put(property, ActionUtil.sdf.format(obj)); jsonObject.put(property, DateUtil.format_YYYY_MM_DD_HH_MM_SS((java.util.Date) obj)); jsonObject.put(property, ActionUtil.sdf.format((java.util.Date) obj)); }else{ jsonObject.put(property,obj); } src/main/java/com/whyc/service/SubTablePageInfoService.java
@@ -1,7 +1,11 @@ package com.whyc.service; import com.whyc.dto.DalmDto; import com.whyc.mapper.CallBack; import com.whyc.pojo.db_alarm.DevalarmData; import com.whyc.pojo.db_alarm.DevalarmDataYear; import com.whyc.pojo.db_batt_testdata.BatttestdataId; import com.whyc.util.ThreadLocalUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -57,23 +61,28 @@ } /*//查询DevAlm历史告警数量 public int getCountForDevAlm(DevAlarmHisDto alm) { String sql="select count(distinct num) as number from db_ckpwrdev_alarm." +alm.getRecordYear() //查询DevAlm历史告警数量 public int getCountForDevAlm(DalmDto dto) { String sql="select count(distinct num) as number from db_alarm." +dto.getTableName() +" where 1=1 "; if(alm.getAlmStartTime()!=null){ sql+=" and alm_starttime >='"+ DateUtil.format_YYYY_MM_DD_HH_MM_SS(alm.getAlmStartTime())+"' "; if(dto.getStartTime()!=null){ sql+=" and alm_starttime >='"+ ThreadLocalUtil.format(dto.getStartTime(),1)+"' "; } if(alm.getAlmEndTime()!=null){ sql+=" and alm_endtime <='"+DateUtil.format_YYYY_MM_DD_HH_MM_SS(alm.getAlmEndTime())+"' "; if(dto.getEndTime()!=null){ sql+=" and alm_endtime <='"+ThreadLocalUtil.format(dto.getEndTime(),1)+"' "; } if(alm.getDevType()!=0){ sql+=" and dev_type="+alm.getDevType(); if(dto.getDevType()!=0){ sql+=" and FLOOR(dev_id/100000000)="+dto.getDevType(); } if(alm.getAlmLevel()!=0){ sql+=" and alm_level="+alm.getAlmLevel(); if(dto.getAlmId()!=0){ sql+=" and alm_id="+dto.getAlmId(); } sql+=" and dev_id in (" + " SELECT distinct dev_id from db_user.tb_battgroup_baojigroup,db_user.tb_battgroup_usr" + " where tb_battgroup_baojigroup.baoji_group_id=tb_battgroup_usr.baoji_group_id" + " and uid="+dto.getUid()+ ")"; List list = sqlExecuteService.executeQuery_call(sql, new CallBack() { @Override public List getResults(ResultSet rs) throws SQLException { @@ -94,60 +103,51 @@ return num; } //查询devalm历史告警 public List getListDevAlm(DevAlarmHisDto alm){ String sql="select * from db_ckpwrdev_alarm." +alm.getRecordYear() public List getListDevAlm(DalmDto dto){ String sql="select * from db_alarm." +dto.getTableName() +" where 1=1 "; if(alm.getAlmStartTime()!=null){ sql+=" and alm_starttime >='"+ DateUtil.format_YYYY_MM_DD_HH_MM_SS(alm.getAlmStartTime())+"' "; if(dto.getStartTime()!=null){ sql+=" and alm_starttime >='"+ ThreadLocalUtil.format(dto.getStartTime(),1)+"' "; } if(alm.getAlmEndTime()!=null){ sql+=" and alm_endtime <='"+DateUtil.format_YYYY_MM_DD_HH_MM_SS(alm.getAlmEndTime())+"' "; if(dto.getEndTime()!=null){ sql+=" and alm_endtime <='"+ThreadLocalUtil.format(dto.getEndTime(),1)+"' "; } if(alm.getDevType()!=0){ sql+=" and dev_type="+alm.getDevType(); if(dto.getDevType()!=0){ sql+=" and FLOOR(dev_id/100000000)="+dto.getDevType(); } if(alm.getAlmLevel()!=0){ sql+=" and alm_level="+alm.getAlmLevel(); if(dto.getAlmId()!=0){ sql+=" and alm_id="+dto.getAlmId(); } sql+=" ORDER BY alm_starttime desc limit "+alm.getLimitStart()+","+alm.getLimitEnd()+" "; sql+=" and dev_id in (" + " SELECT distinct dev_id from db_user.tb_battgroup_baojigroup,db_user.tb_battgroup_usr" + " where tb_battgroup_baojigroup.baoji_group_id=tb_battgroup_usr.baoji_group_id" + " and uid="+dto.getUid()+ ")"; sql+=" ORDER BY alm_starttime asc limit "+dto.getLimitStart()+","+dto.getLimitEnd()+" "; List list = sqlExecuteService.executeQuery_call(sql, new CallBack() { @Override public List getResults(ResultSet rs) throws SQLException { List<CKPowerDevAlarmHistory> list=new ArrayList<>(); List<DevalarmDataYear> list=new ArrayList<>(); while (rs.next()){ CKPowerDevAlarmHistory ph=new CKPowerDevAlarmHistory(); ph.setNum(rs.getLong("num")); ph.setPowerDeviceId(rs.getInt("power_device_id")); ph.setAlmId(rs.getInt("alm_id")); ph.setAlmName(rs.getString("alm_name")); ph.setDevType(rs.getInt("dev_type")); ph.setAlmLevel(rs.getInt("alm_level")); ph.setAlmStartTime(rs.getTimestamp("alm_starttime")); ph.setAlmEndTime(rs.getTimestamp("alm_endtime")); ph.setAlmIsConfirmed(rs.getInt("alm_is_confirmed")); ph.setAlmConfirmedTime(rs.getTimestamp("alm_confirmed_time")); ph.setAlmClearedType(rs.getInt("alm_cleared_type")); list.add(ph); DevalarmDataYear dataYear=new DevalarmDataYear(); dataYear.setNum(rs.getInt("num")); dataYear.setDevId(rs.getInt("dev_id")); dataYear.setAlmSignalId(rs.getInt("alm_signal_id")); dataYear.setAlmStarttime(rs.getTimestamp("alm_starttime")); dataYear.setAlmValue(rs.getFloat("alm_value")); dataYear.setAlmIsConfirmed(rs.getInt("alm_is_confirmed")); dataYear.setConfirmedUid(rs.getInt("confirmed_uid")); dataYear.setConfirmedTime(rs.getTimestamp("confirmed_time")); dataYear.setAlmEndtime(rs.getTimestamp("alm_endtime")); dataYear.setAlmClearedType(rs.getInt("alm_cleared_type")); list.add(dataYear); } return list; } }); return list; } //查询所有的历史时间表 public List getDevAlmHisList() { String sql="SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'tb_ckpowerdev_alarm_history_%'"; List list = sqlExecuteService.executeQuery_call(sql, new CallBack() { @Override public List getResults(ResultSet rs) throws SQLException { List<String> list=new ArrayList<>(); while (rs.next()){ list.add(rs.getString("table_name")); } return list; } }); return list; }*/ } src/main/java/com/whyc/util/ActionUtil.java
@@ -203,7 +203,7 @@ UserInf userInf = new UserInf(); if(obj==null){ userInf.setUname("未登录的用户账号"); userInf.setUid(0); userInf.setUid(101); userInf.setUdownloadRole(0); }else{ userInf=(UserInf) session.getAttribute("user"); src/main/java/com/whyc/util/DateUtil.java
@@ -5,135 +5,289 @@ import java.util.*; /** * 日期处理工具类 * @Author xuzhongpei * @Date 2023-11-16 * */ * @Description : 时间工具类 * @date 2020/10/15 **/ public class DateUtil { /**ThreadLocal副本形式避免多线程中 数据安全问题*/ private static ThreadLocal<SimpleDateFormat> YYYY_MM_DD_HH_MM_SS = ThreadLocal.withInitial(()->new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")); private static ThreadLocal<SimpleDateFormat> YYYY_MM_DD_HH_MM_SS2 = ThreadLocal.withInitial(()->new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss")); private static ThreadLocal<SimpleDateFormat> YYYY_MM_DD_HH_MM_SS_UNION = ThreadLocal.withInitial(()->new SimpleDateFormat("yyyyMMddHHmmss")); private static ThreadLocal<SimpleDateFormat> YYYY_MM_DD = ThreadLocal.withInitial(()->new SimpleDateFormat("yyyy-MM-dd")); private static ThreadLocal<SimpleDateFormat> YYYY_MM_DD_UNION = ThreadLocal.withInitial(()->new SimpleDateFormat("yyyyMMdd")); public static SimpleDateFormat YYYY_MM_DD_HH_MM_SS=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static SimpleDateFormat YYYY_MM_DD_HH_MM_SS_UNION=new SimpleDateFormat("yyyyMMddHHmmss"); public static SimpleDateFormat YYYY_MM_DD=new SimpleDateFormat("yyyy-MM-dd"); public static SimpleDateFormat YYYY_MM=new SimpleDateFormat("yyyy-MM"); public static SimpleDateFormat YYYY_MM_TABLE=new SimpleDateFormat("yyyy_MM"); public static String format_YYYY_MM_DD_HH_MM_SS(Date date){ return YYYY_MM_DD_HH_MM_SS.get().format(date); public static int compare(String date1Str,String date2Str) throws ParseException { Date date1 = YYYY_MM_DD_HH_MM_SS.parse(date1Str); Date date2 = YYYY_MM_DD_HH_MM_SS.parse(date2Str); if(date1.compareTo(date2)>0){ return 1; }else if(date1.compareTo(date2) == 0){ return 0; }else{ return -1; } } public static String format_YYYY_MM_DD_HH_MM_SS2(Date date){ return YYYY_MM_DD_HH_MM_SS2.get().format(date); public static Date getMaxTime(String date1Str,String date2Str,String date3Str) { try { Date date1 = YYYY_MM_DD_HH_MM_SS.parse(date1Str); Date date2 = YYYY_MM_DD_HH_MM_SS.parse(date2Str); Date date3 = YYYY_MM_DD_HH_MM_SS.parse(date3Str); Date maxTime = date1; if (maxTime.compareTo(date2) < 0) { maxTime = date2; } if (maxTime.compareTo(date3) < 0) { maxTime = date3; } return maxTime; }catch (ParseException e){ return null; } } public static String format_YYYY_MM_DD_HH_MM_SS_UNION(Date date){ return YYYY_MM_DD_HH_MM_SS_UNION.get().format(date); public static List<List<Date>> getMonthTime(Date startTimeDate,Date endTimeDate) throws ParseException { List<List<Date>> timeList = new LinkedList<>(); Calendar startTimeCalendar = Calendar.getInstance(); startTimeCalendar.setTime(startTimeDate); Calendar endTimeCalendar = Calendar.getInstance(); endTimeCalendar.setTime(endTimeDate); //按月份切分时段 int startY = startTimeCalendar.get(Calendar.YEAR); int startM = startTimeCalendar.get(Calendar.MONTH)+1; int endY = endTimeCalendar.get(Calendar.YEAR); int endM = endTimeCalendar.get(Calendar.MONTH)+1; int Y = endY - startY; int len = Y*12+(endM-startM)+1; Calendar dateTemp = Calendar.getInstance(); for (int i = 0; i < len; i++) { List<Date> SEList = new LinkedList<>(); //dateTemp.setTime(YYYY_MM_DD_HH_MM_SS.parse(startY+"-"+startM+"-01 00:00:00")); dateTemp.setTime(ThreadLocalUtil.parse(startY+"-"+startM+"-01 00:00:00",1)); Date recordTime,recordTime1; dateTemp.add(Calendar.MONTH,i); recordTime = dateTemp.getTime(); int lastDay = dateTemp.getActualMaximum(Calendar.DAY_OF_MONTH); dateTemp.set(Calendar.DAY_OF_MONTH,lastDay); dateTemp.set(Calendar.HOUR_OF_DAY,23); dateTemp.set(Calendar.MINUTE,59); dateTemp.set(Calendar.SECOND,59); recordTime1 = dateTemp.getTime(); if(i==0){ recordTime = startTimeDate; } if(i==len-1){ recordTime1 = endTimeDate; } SEList.add(recordTime); SEList.add(recordTime1); timeList.add(SEList); } return timeList; } public static String YYYY_MM_DD(Date date){ return YYYY_MM_DD.get().format(date); /** * 在分表的情况下使用,按年分表,查询需要切割查询使用 * <p> * 根据传入的起止时间,按照年切割成不同时间段 * * @param startTime 2021-01-01 10:00:00 * @param endTime 2023-05-01 10:10:10 * @return 示例[2021, 2022, 2023] * 使用方法: * 根据返回的第一个数据,如果存在表,则查询筛选条件为>=输入的起始时间;不存在则弃用输入的起始时间 * 根据返回的最后个数据,如果表存在,则查询筛选条件为<=输入的终止时间;不存在则弃用输入的终止时间 * 返回的非第一最后数据,查询全表 */ public static Map<String,List<Date>> getYearList(Date startTime,Date endTime) throws ParseException { Map<String,List<Date>> result = new LinkedHashMap<>(); Calendar startTimeC = Calendar.getInstance(); startTimeC.setTime(startTime); int startYear = startTimeC.get(Calendar.YEAR); Calendar endTimeC = Calendar.getInstance(); endTimeC.setTime(endTime); int endYear = endTimeC.get(Calendar.YEAR); int yearSize = endYear - startYear + 1; for (int i = startYear; i <= endYear; i++) { List<Date> dateList = new LinkedList<>(); if(yearSize == 1){ //起止时间没有跨年 dateList.add(startTime); dateList.add(endTime); } else if(i==startYear){ //第一年 dateList.add(startTime); Calendar instance = Calendar.getInstance(); instance.set(Calendar.YEAR,i); instance.set(Calendar.MONTH,instance.getActualMaximum(Calendar.MONTH)); instance.set(Calendar.DAY_OF_MONTH,instance.getActualMaximum(Calendar.DAY_OF_MONTH)); instance.set(Calendar.HOUR_OF_DAY,instance.getActualMaximum(Calendar.HOUR_OF_DAY)); instance.set(Calendar.MINUTE,instance.getActualMaximum(Calendar.MINUTE)); instance.set(Calendar.SECOND,instance.getActualMaximum(Calendar.SECOND)); dateList.add(instance.getTime()); } else if(i== endYear){ //尾年 Calendar instance = Calendar.getInstance(); instance.set(Calendar.YEAR,i); instance.set(Calendar.MONTH,instance.getActualMinimum(Calendar.MONTH)); instance.set(Calendar.DAY_OF_MONTH,instance.getActualMinimum(Calendar.DAY_OF_MONTH)); instance.set(Calendar.HOUR_OF_DAY,instance.getActualMinimum(Calendar.HOUR_OF_DAY)); instance.set(Calendar.MINUTE,instance.getActualMinimum(Calendar.MINUTE)); instance.set(Calendar.SECOND,instance.getActualMinimum(Calendar.SECOND)); dateList.add(instance.getTime()); dateList.add(endTime); }else{ Calendar instance = Calendar.getInstance(); instance.set(Calendar.YEAR,i); instance.set(Calendar.MONTH,instance.getActualMinimum(Calendar.MONTH)); instance.set(Calendar.DAY_OF_MONTH,instance.getActualMinimum(Calendar.DAY_OF_MONTH)); instance.set(Calendar.HOUR_OF_DAY,instance.getActualMinimum(Calendar.HOUR_OF_DAY)); instance.set(Calendar.MINUTE,instance.getActualMinimum(Calendar.MINUTE)); instance.set(Calendar.SECOND,instance.getActualMinimum(Calendar.SECOND)); dateList.add(instance.getTime()); Calendar instance2 = Calendar.getInstance(); instance2.set(Calendar.YEAR,i); instance2.set(Calendar.MONTH,instance2.getActualMaximum(Calendar.MONTH)); instance2.set(Calendar.DAY_OF_MONTH,instance2.getActualMaximum(Calendar.DAY_OF_MONTH)); instance2.set(Calendar.HOUR_OF_DAY,instance2.getActualMaximum(Calendar.HOUR_OF_DAY)); instance2.set(Calendar.MINUTE,instance2.getActualMaximum(Calendar.MINUTE)); instance2.set(Calendar.SECOND,instance2.getActualMaximum(Calendar.SECOND)); dateList.add(instance2.getTime()); } result.put(String.valueOf(i),dateList); } return result; } public static String format_YYYY_MM_DD_UNION(Date date){ return YYYY_MM_DD_UNION.get().format(date); /** * * 在分表的情况下使用,按月分表,查询需要切割查询使用 * * 根据传入的起止时间,按照月切割成不同时间段 * @param startTimeStr 2022-11-01 10:00:00 * @param endTimeStr 2023-05-01 10:10:10 * @return 示例[2022_12,2023_1,2023_2,2023_3,2023_4,2023_5] TODO 这个返回对象格式 需要根据业务需要进行调整 * 使用方法: * 根据返回的第一个数据,如果存在表,则查询筛选条件为>=输入的起始时间;不存在则弃用输入的起始时间 * 根据返回的最后个数据,如果表存在,则查询筛选条件为<=输入的终止时间;不存在则弃用输入的终止时间 * 返回的非第一最后数据,查询全表 * */ public static List<String> getMonthList(String startTimeStr,String endTimeStr) throws ParseException { Calendar startTimeCalendar = Calendar.getInstance(); //Date startTime = DateUtil.YYYY_MM_DD_HH_MM_SS.parse(startTimeStr); Date startTime = ThreadLocalUtil.parse(startTimeStr,1); startTimeCalendar.setTime(startTime); Calendar endTimeCalendar = Calendar.getInstance(); //Date endTime = DateUtil.YYYY_MM_DD_HH_MM_SS.parse(endTimeStr); Date endTime = ThreadLocalUtil.parse(endTimeStr,1); endTimeCalendar.setTime(endTime); /*String[] startTimeSplit = startTimeStr.split("-"); int startYear = Integer.parseInt(startTimeSplit[0]); int startMonth = Integer.parseInt(startTimeSplit[1]); String[] endTimeSplit = endTimeStr.split("-"); int endYear = Integer.parseInt(endTimeSplit[0]); int endMonth = Integer.parseInt(endTimeSplit[1]);*/ List<String> yearMonthList = new LinkedList<>(); while (!startTimeCalendar.after(endTimeCalendar)){ //起始时间大于终止时间则停止 yearMonthList.add(startTimeCalendar.get(Calendar.YEAR)+"_"+(startTimeCalendar.get(Calendar.MONTH)+1)); startTimeCalendar.add(Calendar.MONTH,1); } return yearMonthList; } /** * 查询使用时,需要处理 默认表查询的问题 * 示例: * <p> * {2020=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020]} * {2021=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021]} * {2022=[Sat Jan 01 00:00:00 CST 2022, Tue Nov 29 09:12:22 CST 2022]} * 或 * {2020=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020]} * {2021=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021]} * {2022=[Sat Jan 01 00:00:00 CST 2022, Thu Dec 29 09:12:22 CST 2022]} * {default=[Wed Dec 14 15:27:13 CST 2022, Thu Dec 29 09:12:22 CST 2022]} * </p> * key为数字,表示年度分表;default为默认表 * @param startTimeDate 起始时间 * @param endTimeDate 终止时间 * @return 需要查询的表及查询时间 * @throws ParseException */ public static Map<String,List<Date>> getQueryTimeForSubTables(Date startTimeDate,Date endTimeDate) throws ParseException { //根据筛选的时间段,查询出符合要求的各分表记录数 //首先,如果当前时间超过7月,默认表中只有本年度的;如果没超过7月,默认表还存在上一年度的记录 Calendar instance = Calendar.getInstance(); if(endTimeDate.compareTo(instance.getTime())>0){ //校验优化最大查询时间 endTimeDate = instance.getTime(); } int nowYear = instance.get(Calendar.YEAR); instance.add(Calendar.MONTH,-6); int beforeYear = instance.get(Calendar.YEAR); Date beforeYearTime = instance.getTime(); instance.setTime(endTimeDate); int endTimeYear = instance.get(Calendar.YEAR); //获取指定年月的天数 public static int getDaysByYearMonth(int year, int month) { Calendar startTime = Calendar.getInstance(); startTime.setTime(startTimeDate); Calendar a = Calendar.getInstance(); a.set(Calendar.YEAR, year); a.set(Calendar.MONTH, month - 1); a.set(Calendar.DATE, 1); a.roll(Calendar.DATE, -1); int maxDate = a.get(Calendar.DATE); return maxDate; Map<String,List<Date>> yearTimeMap = DateUtil.getYearList(startTimeDate, endTimeDate);; if(nowYear == beforeYear){ //默认表只有本年度的(超过了半年,默认表记录全部只有本年度的,同时会生成了当前年度的分表) //如果查询时间范围包含当前年度,则需要查询默认表 if(startTime.get(Calendar.YEAR) >= nowYear && endTimeYear <= nowYear){ //开始时间设置年度初始时间 Calendar defaultTableStartTime = Calendar.getInstance(); defaultTableStartTime.set(Calendar.YEAR,nowYear); defaultTableStartTime.set(Calendar.MONTH,defaultTableStartTime.getActualMinimum(Calendar.MONTH)); defaultTableStartTime.set(Calendar.DAY_OF_MONTH,defaultTableStartTime.getActualMinimum(Calendar.DAY_OF_MONTH)); defaultTableStartTime.set(Calendar.HOUR_OF_DAY,defaultTableStartTime.getActualMinimum(Calendar.HOUR_OF_DAY)); defaultTableStartTime.set(Calendar.MINUTE,defaultTableStartTime.getActualMinimum(Calendar.MINUTE)); defaultTableStartTime.set(Calendar.SECOND,defaultTableStartTime.getActualMinimum(Calendar.SECOND)); //终止时间设置为当前时间 List<Date> defaultDateList = new LinkedList<>(); defaultDateList.add(defaultTableStartTime.getTime()); defaultDateList.add(endTimeDate); yearTimeMap.put("default",defaultDateList); } }else{ //查询时间范围不在当前年度 //默认表中存在上一年度的记录.上一年的最早时间为beforeYearTime-上一年的年末 //判断查询时间范围是否包含默认表中上一年度的时间 if(instance.getTime().compareTo(beforeYearTime)>0){ //查询时间大于默认表中上一年度时间,说明查询记录也包含在默认表中 //起始时间 //终止时间 List<Date> defaultDateList = new LinkedList<>(); defaultDateList.add(beforeYearTime); defaultDateList.add(endTimeDate); yearTimeMap.put("default",defaultDateList); } } return yearTimeMap; } //获取某年某月的起始和结束时间 //需要注意的是:月份是从0开始的,比如说如果输入5的话,实际上显示的是4月份的最后一天,千万不要搞错了哦 public static String getLastDayOfMonth(int year, int month) { Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, month); cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DATE)); return new SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime())+"23:59:59"; } public static String getFirstDayOfMonth(int year, int month) { Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, month); cal.set(Calendar.DAY_OF_MONTH,cal.getMinimum(Calendar.DATE)); return new SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime())+"00:00:00"; } //获取当前时间的年份 public static int getNowYear(){ Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(new Date()); //设置时间为当前时间 int year = ca.get(Calendar.YEAR); //System.out.println(month); return year; } //获取当前时间的月份 public static int getNowMonth(){ Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(new Date()); //设置时间为当前时间 int month = ca.get(Calendar.MONTH) + 1; //System.out.println(month); return month; } //获取当前时间的日期 public static int getNowDay(){ Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(new Date()); //设置时间为当前时间 int day = ca.get(Calendar.DAY_OF_MONTH); //System.out.println(month); return day; } //当前时间加上x小时 public static String getDateAdd(int minute){ Date date = new Date(); Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MINUTE, minute); return new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format(c.getTime()); } //获取时间的年份 public static int getDateYear(Date date){ Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(date); //设置时间为当前时间 int year = ca.get(Calendar.YEAR); //System.out.println(month); return year; } //获取时间的月份 public static int getDateMonth(Date date){ Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(date); //设置时间为当前时间 int month = ca.get(Calendar.MONTH) + 1; //System.out.println(month); return month; } //获取时间的日期 public static int getDateDay(Date date){ Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(date); //设置时间为当前时间 int day = ca.get(Calendar.DAY_OF_MONTH); //System.out.println(month); return day; } //当前时间加上x小时 public static Date getDateAdd(Date date,int minute){ Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MINUTE, minute); return c.getTime(); } /*==========时间切割,按年==========*/ /** * 在分表的情况下使用,按年分表,查询需要切割查询使用 时间倒序 * <p> @@ -147,7 +301,7 @@ * 根据返回的最后个数据,如果表存在,则查询筛选条件为<=输入的终止时间;不存在则弃用输入的终止时间 * 返回的非第一最后数据,查询全表 */ public static Map<String, List<Date>> getYearListDesc(Date startTime, Date endTime) throws ParseException { public static Map<String,List<Date>> getYearListDesc(Date startTime,Date endTime) throws ParseException { Map<String,List<Date>> result = new LinkedHashMap<>(); Calendar startTimeC = Calendar.getInstance(); startTimeC.setTime(startTime); @@ -212,6 +366,94 @@ } /** * 在分表的情况下使用,按月分表,查询需要切割查询使用 时间倒序 * <p> * 根据传入的起止时间,按照年切割成不同时间段 * * @param startTime 2023-01-01 10:00:00 * @param endTime 2023-05-01 10:10:10 * @return 示例 * { * 2023_04=[Fri Dec 25 14:12:22 CST 2020, Thu Dec 31 23:59:59 CST 2020] * 2023_03=[Fri Jan 01 00:00:00 CST 2021, Fri Dec 31 23:59:59 CST 2021], * 2023_02=[Sat Jan 01 00:00:00 CST 2022, Sat Dec 31 23:59:59 CST 2022], * 2023_01=[Sun Jan 01 00:00:00 CST 2023, Tue Jan 24 16:45:22 CST 2023], * * } * 使用方法: * 根据返回的第一个数据,如果存在表,则查询筛选条件为>=输入的起始时间;不存在则弃用输入的起始时间 * 根据返回的最后个数据,如果表存在,则查询筛选条件为<=输入的终止时间;不存在则弃用输入的终止时间 * 返回的非第一最后数据,查询全表 */ public static Map<String,List<Date>> getMonthListDesc(Date startTime,Date endTime) throws ParseException { Map<String,List<Date>> result = new LinkedHashMap<>(); Calendar startTimeC = Calendar.getInstance(); startTimeC.setTime(startTime); int startYear = startTimeC.get(Calendar.YEAR); int startMonth = startTimeC.get(Calendar.MONTH); Calendar endTimeC = Calendar.getInstance(); endTimeC.setTime(endTime); int endYear = endTimeC.get(Calendar.YEAR); int endMonth = endTimeC.get(Calendar.MONTH); //相差的月份 int monthCount = endYear*12+endMonth-(startYear*12+startMonth); for (int i = monthCount; i >= 0; i--) { List<Date> dateList = new LinkedList<>(); if(monthCount == 0 ){ //起止时间没有跨月 dateList.add(startTime); dateList.add(endTime); } else if(i==0){ //第一月 dateList.add(startTime); Calendar instance = Calendar.getInstance(); instance.setTime(startTime); instance.set(Calendar.DAY_OF_MONTH,instance.getActualMaximum(Calendar.DAY_OF_MONTH)); instance.set(Calendar.HOUR_OF_DAY,instance.getActualMaximum(Calendar.HOUR_OF_DAY)); instance.set(Calendar.MINUTE,instance.getActualMaximum(Calendar.MINUTE)); instance.set(Calendar.SECOND,instance.getActualMaximum(Calendar.SECOND)); dateList.add(instance.getTime()); } else if(i== monthCount){ //尾月 Calendar instance = Calendar.getInstance(); instance.setTime(endTime); instance.set(Calendar.DAY_OF_MONTH,instance.getActualMinimum(Calendar.DAY_OF_MONTH)); instance.set(Calendar.HOUR_OF_DAY,instance.getActualMinimum(Calendar.HOUR_OF_DAY)); instance.set(Calendar.MINUTE,instance.getActualMinimum(Calendar.MINUTE)); instance.set(Calendar.SECOND,instance.getActualMinimum(Calendar.SECOND)); dateList.add(instance.getTime()); dateList.add(endTime); }else{ Calendar instance = Calendar.getInstance(); instance.setTime(startTime); instance.add(Calendar.MONTH,i); instance.set(Calendar.DAY_OF_MONTH,instance.getActualMinimum(Calendar.DAY_OF_MONTH)); instance.set(Calendar.HOUR_OF_DAY,instance.getActualMinimum(Calendar.HOUR_OF_DAY)); instance.set(Calendar.MINUTE,instance.getActualMinimum(Calendar.MINUTE)); instance.set(Calendar.SECOND,instance.getActualMinimum(Calendar.SECOND)); dateList.add(instance.getTime()); Calendar instance2 = Calendar.getInstance(); instance2.setTime(startTime); instance2.add(Calendar.MONTH,i); instance2.set(Calendar.DAY_OF_MONTH,instance2.getActualMaximum(Calendar.DAY_OF_MONTH)); instance2.set(Calendar.HOUR_OF_DAY,instance2.getActualMaximum(Calendar.HOUR_OF_DAY)); instance2.set(Calendar.MINUTE,instance2.getActualMaximum(Calendar.MINUTE)); instance2.set(Calendar.SECOND,instance2.getActualMaximum(Calendar.SECOND)); dateList.add(instance2.getTime()); } //result.put(DateUtil.YYYY_MM_TABLE.format(dateList.get(0)),dateList); result.put(ThreadLocalUtil.format(dateList.get(0),2),dateList); } return result; } /** * 查询使用时,需要处理 默认表查询的问题 倒序 * 示例: * <p> @@ -243,6 +485,42 @@ LinkedHashMap<String,List<Date>> yearTimeMap = (LinkedHashMap<String, List<Date>>) DateUtil.getYearListDesc(startTimeDate, endTimeDate); Map<String,List<Date>> yearTimeDescMap = new LinkedHashMap<>(); boolean existDefaultYear = false; /*if(nowYear == beforeYear){ //默认表只有本年度的(超过了半年,默认表记录全部只有本年度的,同时会生成了当前年度的分表) //如果查询时间范围包含当前年度,则需要查询默认表 if(startTime.get(Calendar.YEAR) >= nowYear && endTimeYear <= nowYear){ //开始时间设置年度初始时间 Calendar defaultTableStartTime = Calendar.getInstance(); defaultTableStartTime.set(Calendar.YEAR,nowYear); defaultTableStartTime.set(Calendar.MONTH,defaultTableStartTime.getActualMinimum(Calendar.MONTH)); defaultTableStartTime.set(Calendar.DAY_OF_MONTH,defaultTableStartTime.getActualMinimum(Calendar.DAY_OF_MONTH)); defaultTableStartTime.set(Calendar.HOUR_OF_DAY,defaultTableStartTime.getActualMinimum(Calendar.HOUR_OF_DAY)); defaultTableStartTime.set(Calendar.MINUTE,defaultTableStartTime.getActualMinimum(Calendar.MINUTE)); defaultTableStartTime.set(Calendar.SECOND,defaultTableStartTime.getActualMinimum(Calendar.SECOND)); //终止时间设置为当前时间 List<Date> defaultDateList = new LinkedList<>(); //defaultDateList.add(defaultTableStartTime.getTime()); defaultDateList.add(startTimeDate); defaultDateList.add(endTimeDate); yearTimeMap.put("default",defaultDateList); existDefaultYear = true; } }else{ //查询时间范围不在当前年度 //默认表中存在上一年度的记录.上一年的最早时间为beforeYearTime-上一年的年末 //判断查询时间范围是否包含默认表中上一年度的时间 if(instance.getTime().compareTo(beforeYearTime)>0){ //查询时间大于默认表中上一年度时间,说明查询记录也包含在默认表中 //起始时间 //终止时间 List<Date> defaultDateList = new LinkedList<>(); defaultDateList.add(startTimeDate); defaultDateList.add(endTimeDate); yearTimeMap.put("default",defaultDateList); existDefaultYear = true; } }*/ if(startTimeDate.before(now.getTime()) || endTimeDate.after(timeBefore7Month.getTime())){ List<Date> defaultDateList = new LinkedList<>(); defaultDateList.add(startTimeDate); @@ -266,5 +544,121 @@ return yearTimeDescMap; } /** * 按年划分 * 优化getQueryTimeForSubTablesDesc,待测试 * 更新default表是否查询的逻辑,改||为&& * */ public static Map<String,List<Date>> getQueryTimeForSubTablesDesc2(Date startTimeDate,Date endTimeDate) throws ParseException { //根据筛选的时间段,查询出符合要求的各分表记录数 //首先,如果当前时间超过7月,默认表中只有本年度的;如果没超过7月,默认表还存在上一年度的记录 Calendar now = Calendar.getInstance(); if(endTimeDate.compareTo(now.getTime())>0){ //校验优化最大查询时间 endTimeDate = now.getTime(); } Calendar timeBefore7Month = Calendar.getInstance(); timeBefore7Month.add(Calendar.MONTH,-7); LinkedHashMap<String,List<Date>> yearTimeMap = (LinkedHashMap<String, List<Date>>) DateUtil.getYearListDesc(startTimeDate, endTimeDate); Map<String,List<Date>> yearTimeDescMap = new LinkedHashMap<>(); boolean existDefaultYear = false; //查询的开始时间 小于现在 //查询的结束时间 大于 七个月前 if(startTimeDate.before(now.getTime()) && endTimeDate.after(timeBefore7Month.getTime())){ List<Date> defaultDateList = new LinkedList<>(); defaultDateList.add(startTimeDate); defaultDateList.add(endTimeDate); yearTimeMap.put("default",defaultDateList); existDefaultYear = true; } //调整下顺序,将default调整到首位 if(existDefaultYear){ List<Date> defaultTimeList = yearTimeMap.get("default"); yearTimeDescMap.put("default",defaultTimeList); } Set<String> yearSet = yearTimeMap.keySet(); for (String year : yearSet) { if(!year.equals("default")){ yearTimeDescMap.put(year,yearTimeMap.get(year)); } } return yearTimeDescMap; } /** * 按月划分,时间倒序 * 在原来按起止时间获取月份划分集合的基础上,加入实际子表逻辑,当前月内的,在default表 * */ public static Map<String,List<Date>> getQueryTimeForSubTablesByMonthDesc(Date startTimeDate,Date endTimeDate) throws ParseException { //根据筛选的时间段,查询出符合要求的各分表记录数 //首先,如果当前时间超过7月,默认表中只有本年度的;如果没超过7月,默认表还存在上一年度的记录 Calendar now = Calendar.getInstance(); if(endTimeDate.compareTo(now.getTime())>0){ //校验优化最大查询时间 endTimeDate = now.getTime(); } LinkedHashMap<String,List<Date>> yearTimeMap = (LinkedHashMap<String, List<Date>>) DateUtil.getMonthListDesc(startTimeDate, endTimeDate); Map<String,List<Date>> yearTimeDescMap = new LinkedHashMap<>(); boolean existDefaultYear = false; //查询的结束时间 在当月,则有default表 //同时,抹去月份集合里的当月 //if(DateUtil.YYYY_MM_TABLE.format(endTimeDate).equals(DateUtil.YYYY_MM_TABLE.format(now.getTime()))){ if(ThreadLocalUtil.format(endTimeDate,2).equals(ThreadLocalUtil.format(now.getTime(),2))){ List<Date> defaultDateList = new LinkedList<>(); defaultDateList.add(startTimeDate); defaultDateList.add(endTimeDate); yearTimeMap.put("default",defaultDateList); existDefaultYear = true; //yearTimeMap.remove(DateUtil.YYYY_MM_TABLE.format(endTimeDate)); yearTimeMap.remove(ThreadLocalUtil.format(endTimeDate,2)); } //调整下顺序,将default调整到首位 if(existDefaultYear){ List<Date> defaultTimeList = yearTimeMap.get("default"); yearTimeDescMap.put("default",defaultTimeList); } Set<String> yearSet = yearTimeMap.keySet(); for (String year : yearSet) { if(!year.equals("default")){ yearTimeDescMap.put(year,yearTimeMap.get(year)); } } return yearTimeDescMap; } public static void main(String[] args) throws ParseException { //Date d1 = YYYY_MM_DD_HH_MM_SS.parse("2023-01-22 14:12:22"); //Date d2 = YYYY_MM_DD_HH_MM_SS.parse("2023-08-24 16:45:22"); //Map<String, List<Date>> monthListDesc = getQueryTimeForSubTablesByMonthDesc(d1, d2); // //Set<Map.Entry<String, List<Date>>> entries = monthListDesc.entrySet(); //for (Map.Entry<String, List<Date>> entry : entries) { // System.out.println(entry); //} //Map<String,String> map = new HashMap<>(); //map.put("2022_01",""); //map.put("2022_02",""); //map.put("2022_10",""); //map.put("2022_12",""); //map.put("2021_03",""); //map.put("2023_01",""); //map.put("2023_05",""); //map.put("2021_10",""); //Set<String> keySet = map.keySet(); //List<String> keySetDesc = keySet.stream().sorted(Comparator.comparing(String::hashCode).reversed()).collect(Collectors.toList()); String t1 = "2024-01-25 12:22:29"; String t2 = "2024-01-25 12:32:24"; String t3 = "2024-01-25 12:42:26"; Date maxTime = getMaxTime(t1, t2, t3); System.out.println(maxTime.toString()); } } src/main/java/com/whyc/util/SubTablePageInfoUtil.java
New file @@ -0,0 +1,226 @@ package com.whyc.util; import com.github.pagehelper.PageInfo; import com.whyc.dto.DalmDto; import com.whyc.factory.ThreadPoolExecutorFactory; import com.whyc.mapper.CommonMapper; import com.whyc.service.SubTablePageInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.text.ParseException; import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ThreadPoolExecutor; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 数据量极大的表,按照年份分表,分页查询时获取数据 */ @Component public class SubTablePageInfoUtil { @Autowired(required = false) private CommonMapper commonMapper; @Autowired private SubTablePageInfoService service; /**按年份表分页查询*/ public PageInfo<Object> getPageInfo(int pageNum,int pageSize, Date startTime,Date endTime, String dbName,String tablePrefix, Object pojo) throws ParseException { Map<String, List<Date>> queryTimeForSubTables = DateUtil.getQueryTimeForSubTablesDesc(startTime, endTime); //查询分表是否存在,存在则查询结果 Map<String,Integer> queryCountMap = new LinkedHashMap<>(); Set<String> tableYearKeySet = queryTimeForSubTables.keySet(); for (String tableYear : tableYearKeySet) { List<Date> queryTime = queryTimeForSubTables.get(tableYear); String tableName; if(!tableYear.equals("default")){ //数值 tableName = tablePrefix+"_"+tableYear; String existTableName = commonMapper.existTable(dbName, tableName); if(existTableName == null){ continue; } }else{ tableName = tablePrefix; } //====== 根据不同类型类型对象对应调整 ====== if (pojo instanceof DalmDto) { DalmDto dto = (DalmDto) pojo; dto.setStartTime(queryTime.get(0)); dto.setEndTime(queryTime.get(1)); dto.setTableName(tableName); int currentCount = service.getCountForDevAlm(dto); queryCountMap.put(tableYear, currentCount); } } //分页信息 //确认总页数,总记录数 PageInfo<Object> pageInfo = new PageInfo<>(); int total = 0; Set<String> queryKeySet = queryCountMap.keySet(); for (String queryKey : queryKeySet) { int size = queryCountMap.get(queryKey); total+=size; } int pages = (int) Math.ceil(Float.parseFloat(String.valueOf(total))/pageSize); pageInfo.setTotal(total); pageInfo.setPages(pages); pageInfo.setPageNum(pageNum); pageInfo.setPageSize(pageSize); //根据当前页所需记录,查询当前页记录 int startNum = (pageNum-1)*pageSize+1; int endNum = pageNum*pageSize; //最后一个算法:上面不应该先查询所有记录,应该取count. 这后面定位到哪个表或哪几张表后,采取limit获取当前页记录数; //格式:{表名,[limit 2,20]} Map<String,List<Integer>> tableAndLimitMap = MathUtil.getQueryTableAndLimit(startNum,endNum,pageSize,queryCountMap); Set<String> keySet = tableAndLimitMap.keySet(); List<Object> dataList = new LinkedList<>(); for (String key : keySet) { List<Date> queryTime = queryTimeForSubTables.get(key); //====== 根据不同类型类型对象对应调整 ====== String tableName = key.equals("default") ? tablePrefix : tablePrefix + "_" + key; if (pojo instanceof DalmDto) { DalmDto dto = (DalmDto) pojo; dto.setStartTime(queryTime.get(0)); dto.setEndTime(queryTime.get(1)); List<Integer> limitList = tableAndLimitMap.get(key); dto.setLimitStart(limitList.get(0)); dto.setLimitEnd(limitList.get(1)); dto.setTableName(tableName); List list = service.getListDevAlm(dto); dataList.addAll(list); } } pageInfo.setList(dataList); return pageInfo; } /**按月分表,分页查询*/ public PageInfo<Object> getPageInfoByMonthTable(int pageNum, int pageSize, Date startTime, Date endTime, String dbName, String tablePrefix, Object pojo) throws ParseException, InterruptedException { Map<String, List<Date>> queryTimeForSubTables = DateUtil.getQueryTimeForSubTablesByMonthDesc(startTime, endTime); //查询分表是否存在,存在则查询结果 Map<String,Integer> queryCountMap = new LinkedHashMap<>(); Set<String> tableYearKeySet = queryTimeForSubTables.keySet(); //优化1-查询所有的符合月份规则的表和主表 List<String> tableNameListDB = getTableList(dbName, tablePrefix, tablePrefix + "(_[0-9]{4}_[0-9]{2})?"); List<String> tableYearListInDB = new LinkedList<>(); //查询时间段内的年月分表集合且在数据库中存在 //过滤掉时间段内数据库中不存在的年月分表 for (String tableYear : tableYearKeySet) { String tableName; if(!tableYear.equals("default")){ //数值 tableName = tablePrefix+"_"+tableYear; //String existTableName = commonMapper.existTable(dbName, tableName); if(!tableNameListDB.contains(tableName)){ //优化1-数据库中不存在,去除多次查表,一次查出 continue; } } tableYearListInDB.add(tableYear); } //查询年月分表的记录数 //优化2:多线程读取 ThreadPoolExecutor pool = ThreadPoolExecutorFactory.getPoolExecutor(); CountDownLatch latch = new CountDownLatch(tableYearListInDB.size()); for (String tableYear : tableYearListInDB) { List<Date> queryTime = queryTimeForSubTables.get(tableYear); String tableName; if(!tableYear.equals("default")){ //数值 tableName = tablePrefix+"_"+tableYear; }else{ tableName = tablePrefix; } pool.execute(()-> { //====== 根据不同类型类型对象对应调整 ====== /*if (pojo instanceof BattAlarmHis) { BattAlarmHis battAlarmHis = new BattAlarmHis(); BeanUtils.copyProperties(pojo,battAlarmHis); battAlarmHis.setAlmStartTime(queryTime.get(0)); battAlarmHis.setAlmEndTime(queryTime.get(1)); battAlarmHis.setRecordYear(tableName); int currentCount = service.getBattHisCount(battAlarmHis); queryCountMap.put(tableYear, currentCount); }*/ latch.countDown(); }); } latch.await(); //因为多线程后无序,需要重排序 List<String> keySetDesc = queryCountMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); Map<String,Integer> queryCountMapDesc = new LinkedHashMap<>(); for (String key : keySetDesc) { Integer count = queryCountMap.get(key); queryCountMapDesc.put(key,count); } //分页信息 //确认总页数,总记录数 PageInfo<Object> pageInfo = new PageInfo<>(); int total = 0; Set<String> queryKeySet = queryCountMap.keySet(); for (String queryKey : queryKeySet) { int size = queryCountMap.get(queryKey); total+=size; } int pages = (int) Math.ceil(Float.parseFloat(String.valueOf(total))/pageSize); pageInfo.setTotal(total); pageInfo.setPages(pages); pageInfo.setPageNum(pageNum); pageInfo.setPageSize(pageSize); //根据当前页所需记录,查询当前页记录 int startNum = (pageNum-1)*pageSize+1; int endNum = pageNum*pageSize; //最后一个算法:上面不应该先查询所有记录,应该取count. 这后面定位到哪个表或哪几张表后,采取limit获取当前页记录数; //格式:{表名,[limit 2,20]} Map<String,List<Integer>> tableAndLimitMap = MathUtil.getQueryTableAndLimit(startNum,endNum,pageSize,queryCountMapDesc); Set<String> keySet = tableAndLimitMap.keySet(); List<Object> dataList = new LinkedList<>(); for (String key : keySet) { List<Date> queryTime = queryTimeForSubTables.get(key); //====== 根据不同类型类型对象对应调整 ====== String recordYear = key.equals("default") ? tablePrefix : tablePrefix + "_" + key; /*if(pojo instanceof BattAlarmHis) { BattAlarmHis battAlarmHis = new BattAlarmHis(); BeanUtils.copyProperties(pojo,battAlarmHis); battAlarmHis.setAlmStartTime(queryTime.get(0)); battAlarmHis.setAlmEndTime(queryTime.get(1)); battAlarmHis.setRecordYear(recordYear); List<Integer> limitList = tableAndLimitMap.get(key); battAlarmHis.setLimitStart(limitList.get(0)); battAlarmHis.setLimitEnd(limitList.get(1)); List<BattAlarmHis> list = service.getBattHisList(battAlarmHis); dataList.addAll(list); }*/ } pageInfo.setList(dataList); return pageInfo; } /**查询是否包含特定规则的表,存在,则返回表名*/ public List<String> getTableList(String dbName,String tableLike,String regex){ List<String> resultTableList = new LinkedList<>(); List<String> tableList = commonMapper.getTableListLike(dbName,tableLike); for (String tableName : tableList) { boolean matches = Pattern.matches(regex, tableName); if(matches){ resultTableList.add(tableName); } } return resultTableList; } } src/main/java/com/whyc/util/ThreadLocalUtil.java
New file @@ -0,0 +1,48 @@ package com.whyc.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class ThreadLocalUtil { public static ThreadLocal<SimpleDateFormat> sdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); public static ThreadLocal<SimpleDateFormat> sdfwithOutday = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy_MM")); public static ThreadLocal<SimpleDateFormat> sdfwithday = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); public static ThreadLocal<SimpleDateFormat> sdfwithtime = ThreadLocal.withInitial(() -> new SimpleDateFormat("HH:mm:ss")); public static ThreadLocal<SimpleDateFormat> sdfwithTABLE=ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM")); public static ThreadLocal<SimpleDateFormat> sdfwithtime_yyyyMMdd_HH_mm_ss=ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss")); public static ThreadLocal<SimpleDateFormat> YYYY_MM_DD_HH_MM_SS_UNION=ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss")); /* * flag:1(sdf),2(sdfwithOutday),3(sdfwithday),4(sdfwithtime) * */ public static Date parse(String timeStr,int flag) { Date date=null; try { switch (flag){ case 1:date=sdf.get().parse(timeStr);break; case 2:date=sdfwithOutday.get().parse(timeStr);break; case 3:date=sdfwithday.get().parse(timeStr);break; case 4:date=sdfwithtime.get().parse(timeStr);break; default:date=sdf.get().parse(timeStr); } } catch (ParseException e) { e.printStackTrace(); } return date; } public static String format(Date date,int flag) { String timeStr=""; switch (flag){ case 1:timeStr=sdf.get().format(date);break; case 2:timeStr=sdfwithOutday.get().format(date);break; case 3:timeStr=sdfwithday.get().format(date);break; case 4:timeStr=sdfwithtime.get().format(date);break; case 5:timeStr=sdfwithTABLE.get().format(date);break; case 6:timeStr=sdfwithtime_yyyyMMdd_HH_mm_ss.get().format(date);break; case 7:timeStr=YYYY_MM_DD_HH_MM_SS_UNION.get().format(date);break; default:timeStr=sdf.get().format(date); } return timeStr; } } src/main/java/com/whyc/webSocket/DevalarmSocket.java
New file @@ -0,0 +1,111 @@ package com.whyc.webSocket; import com.whyc.config.WebSocketConfig; import com.whyc.dto.DalmDto; import com.whyc.dto.DevInfDto; import com.whyc.dto.Response; import com.whyc.pojo.db_alarm.DevalarmData; import com.whyc.service.DevInfService; import com.whyc.service.DevalarmDataService; import com.whyc.util.ActionUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.servlet.http.HttpSession; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.util.HashMap; import java.util.Map; /** * 设备实时连接信息 */ @Component @ServerEndpoint(value = "/dalmSocket",encoders = WebSocketEncoder.class,configurator = WebSocketConfig.class) public class DevalarmSocket { private Session session; private Thread thread; private static DevalarmDataService dalmService; private HttpSession httpSession; private volatile boolean runFlag = true; private volatile Map<String, Thread> threadMap = new HashMap<>(); private volatile Map<Long,Boolean> threadFlagMap = new HashMap<>(); @Autowired public void setDevalarmDataService(DevalarmDataService dalmService) { DevalarmSocket.dalmService = dalmService; } @OnOpen public void onOpen(Session session, EndpointConfig config) { this.session = session; this.httpSession = (HttpSession) config.getUserProperties().get("httpSession"); } @OnMessage public void onMessage(Session session, String message) { DalmDto dto = ActionUtil.getGson("yyyy-MM-dd HH:mm:ss").fromJson(message, DalmDto.class); //UserInf user = (UserInf) this.httpSession.getAttribute("user"); //final int userId = user.getUid(); final int userId = 101; thread = new Thread("Thread_DevalarmSocket") { @Override public void run() { while (runFlag && !isInterrupted()) { Thread thread = currentThread(); threadFlagMap.put(thread.getId(), true); try { Response res=dalmService.getDAlmInf(userId, dto); if (session.isOpen()) { //推送信息 synchronized (session) { session.getBasicRemote().sendObject(res); } threadFlagMap.put(thread.getId(), false); } sleep(4000); } catch (Exception e) { interrupt(); } } } }; thread.start(); threadFlagMap.put(thread.getId(),true); //停止老的socket线程 Thread threadBefore = threadMap.get(session.getId()); if(threadBefore !=null && threadBefore.isAlive()){ while (threadFlagMap.get(threadBefore.getId())){ } threadBefore.interrupt(); } //将线程存储,便于调用定位 threadMap.put(session.getId(), this.thread); } @OnClose public void onClose(CloseReason closeReason){ System.err.println("closeReason = " + closeReason); runFlag = false; if (thread != null && thread.isAlive()) { thread.interrupt(); } threadMap.remove(session.getId()); } @OnError public void onError(Throwable error) { error.printStackTrace(); if (thread != null && thread.isAlive()) { thread.interrupt(); } threadMap.remove(session.getId()); } } src/main/resources/mapper/DevalarmDataMapper.xml
New file @@ -0,0 +1,31 @@ <?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.whyc.mapper.DevalarmDataMapper"> <select id="getDAlmInf" resultType="com.whyc.pojo.db_alarm.DevalarmData"> select * from db_alarm.tb_devalarm_data <where> <if test="dto.devType!=null"> and FLOOR(dev_id/100000000) =#{dto.devType} </if> <if test="dto.almId!=null"> and alm_id=#{dto.almId} </if> <if test="dto.startTime!=null"> and alm_starttime>=#{dto.startTime} </if> <if test="dto.endTime!=null"> and alm_starttime<=#{dto.endTime} </if> and dev_id in ( SELECT distinct dev_id from db_user.tb_battgroup_baojigroup,db_user.tb_battgroup_usr <where> tb_battgroup_baojigroup.baoji_group_id=tb_battgroup_usr.baoji_group_id <if test="dto.uid!=null"> and uid=#{dto.uid} </if> </where> ) </where> </select> </mapper>