Java 工作中常用案例

1. LocalDateTime获取某月的第一天开始时间和最后一天的结束时间

	/**
	 * 获取指定年和月的第一天和最后一天
     * 应用:数据库同步,本地库和其他库按照月份分组统计后,两两比对后,得到不相同的月份,
     *      根据月份的第一天和最后一天,查询两个库具体值,做交集或差集,然后得到未同步
     *      的数据后同步数据 
     *      2022-12  xx
     *      2022-11  xx  
     * @param month 2022-12
	 * @return
	 */
	public static Map<String, LocalDateTime> getDateOfMonth(String month){
		Map<String,LocalDateTime>  map = new HashMap<String, LocalDateTime>(2);


		LocalDate date = LocalDate.parse(month +"-10", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		//根据月份的随便一天获取这个月的第一天以及最后一天
		LocalDate first = date.with(TemporalAdjusters.firstDayOfMonth());
		LocalDate last = date.with(TemporalAdjusters.lastDayOfMonth());
		//获取一天的第一秒和最后一秒
		LocalTime beginTime = LocalTime.MIN;
		LocalTime endTime = LocalTime.MAX;
		//某月的第一天的第一秒
		LocalDateTime beginDatetime = LocalDateTime.of(first, beginTime);
		//某月的最后一天的最后一秒
		LocalDateTime endDatetime = LocalDateTime.of(last, endTime);

		map.put("firstDay", beginDatetime);
		map.put("lastDay", endDatetime);
		return map;
	}

}

2.List集合切割

    /**
     * 集合切割成 count的集合
     * 应用:当数据比较大的时候,大集合数据多比较慢还可能内存溢出,切割成小集合后,容易处理
     * @param list
     * @param count
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> splitList(List<T> list, int count) {
        List<List<T>> listAll = new ArrayList<>();
        if (list == null || list.isEmpty()) {
            return listAll;
        }

        int size = list.size();
        if (size > count) {
            int num = size / count;
            for (int i = 1; i < num + 1; i++) {
                listAll.add(list.subList((i - 1) * count, i * count));
            }
            if (size - num * count > 0) {
                listAll.add(list.subList(num * count, size));
            }
        } else {
            listAll.add(list);
        }
        return listAll;
    }

3.Stream流实现交集和差集

    /**
     * 交集
     *
     * @param list1
     * @param list2
     * @param <T>
     * @return
     */
    public static <T> List<T> intersection(List<T> list1, List<T> list2) {
        if (list1 == null || list2 == null || list1.isEmpty() || list2.isEmpty()) {
            return new ArrayList<>();
        }
        return list1.stream().filter(e -> list2.contains(e)).collect(Collectors.toList());
    }

    /**
     * 差集 结果是list1的不在list2中的差集
     *
     * @param list1
     * @param list2
     * @param <T>
     * @return
     */
    public static <T> List<T> subtraction(List<T> list1, List<T> list2) {
        if (list1 == null || list1.isEmpty()) {
            if (list2 != null && !list2.isEmpty()) {
                return list2;
            } else {
                return Collections.emptyList();
            }
        }
        return list1.stream().filter(e -> !list2.contains(e)).collect(Collectors.toList());
    }

4.检查url是否是有效网络地址的


    /**
     *  检查url是否是有效网络地址的
     * @param fileUrl
     * @return
     */
    public static boolean checkURL(String fileUrl) {
        try {
            URL url = new URL(fileUrl);
            URI uriObj = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
        } catch (MalformedURLException | URISyntaxException e) {
            return false;
        }
        return true;
    }

5.项目启动后事件

import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import static com.cdkttc.dchb.cache.DchbCache.DCHB_CACHE;
/**
 * 项目启动做一些逻辑处理
 */
@Component
@RequiredArgsConstructor
public class xxx implements CommandLineRunner, Ordered {

    private final IService service;

    @Override
    public void run(String... args) throws Exception {
       //逻辑  service.xxx()
    }

    @Override
    public int getOrder() {
        return 99;
    }
}

6.EasyExcel导出实现下拉选项

    /**
     *
     * @param response
     * @param fileName 导出文件名 不带后缀
     * @param taskSheetName sheet 名称
     * @param taskDataList  数据
     * @param clazzTask     表头类
     * @param <T>
     */
    public static <T> void export(HttpServletResponse response, String fileName, String taskSheetName, List<T> taskDataList, Class<T> clazzTask) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding(Charsets.UTF_8.name());
            fileName = URLEncoder.encode(fileName, Charsets.UTF_8.name());
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            Map<Integer, ExcelSelectedResolve> taskSelectedMap = resolveSelectedAnnotation(clazzTask);
            ExcelWriter writer = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet taskSheet = EasyExcel.writerSheet(taskSheetName).head(clazzTask).registerWriteHandler(new SelectedSheetWriteHandler(taskSelectedMap)).build();
            writer.write(taskDataList, taskSheet);
            writer.finish();
        } catch (IOException var6) {
            throw new ServiceException("导出出错");
        }
    }

    /**
     * 解析表头类中的下拉注解
     *
     * @param head 表头类
     * @param <T>  泛型
     * @return Map<下拉框列索引, 下拉框内容> map
     */
    private static <T> Map<Integer, ExcelSelectedResolve> resolveSelectedAnnotation(Class<T> head) {
        Map<Integer, ExcelSelectedResolve> selectedMap = new HashMap<>();

        // getDeclaredFields(): 返回全部声明的属性;getFields(): 返回public类型的属性
        Field[] fields = head.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            // 解析注解信息
            ExcelSelected selected = field.getAnnotation(ExcelSelected.class);
            ExcelProperty property = field.getAnnotation(ExcelProperty.class);
            if (selected != null) {
                ExcelSelectedResolve excelSelectedResolve = new ExcelSelectedResolve();
                String[] source = excelSelectedResolve.resolveSelectedSource(selected);
                if (source != null && source.length > 0) {
                    excelSelectedResolve.setSource(source);
                    excelSelectedResolve.setFirstRow(selected.firstRow());
                    excelSelectedResolve.setLastRow(selected.lastRow());
                    if (property != null && property.index() >= 0) {
                        selectedMap.put(property.index(), excelSelectedResolve);
                    } else {
                        selectedMap.put(i, excelSelectedResolve);
                    }
                }
            }
        }

        return selectedMap;
    }



import java.util.Map;

import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.springframework.stereotype.Component;

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
@Component
public class SelectedSheetWriteHandler implements SheetWriteHandler {
    private final Map<Integer, ExcelSelectedResolve> selectedMap;
    private static char[] alphabet = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    /**
     * Called before create the sheet
     */
    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
 
    }
 
    /**
     * Called after the sheet is created
     */
    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        // 这里可以对cell进行任何操作
        Sheet sheet = writeSheetHolder.getSheet();
        DataValidationHelper helper = sheet.getDataValidationHelper();

        //定义sheet的名称
        String dictSheetName = "字典sheet";
        //1.创建一个隐藏的sheet 名称为 hidden
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        int sheetIndex = workbook.getSheetIndex(dictSheetName);
        Sheet dictSheet=null;
        if (sheetIndex==-1) {
            dictSheet = workbook.createSheet(dictSheetName);
            Name category1Name = workbook.createName();
            category1Name.setNameName(dictSheetName);
        }else{
            dictSheet= workbook.getSheet(dictSheetName);
        }



        for (Map.Entry<Integer, ExcelSelectedResolve> entry : selectedMap.entrySet()) {
            // 设置下拉单元格的首行、末行、首列、末列
            CellRangeAddressList rangeAddressList = new CellRangeAddressList(entry.getValue().getFirstRow(), entry.getValue().getLastRow(), entry.getKey(), entry.getKey());
            int rowLen = entry.getValue().getSource().length;
            DataValidationConstraint constraint=null;
            if (rowLen>50){
                // 设置字典sheet页的值 每一列一个字典项
                for (int i = 0; i < rowLen; i++) {
                    Row row = dictSheet.getRow(i);
                    if (row == null) {
                        row = dictSheet.createRow(i);
                    }
                    row.createCell(entry.getKey()).setCellValue(entry.getValue().getSource()[i]);
                }
                String excelColumn = getExcelColumn(entry.getKey());
                // 下拉框数据来源 eg:字典sheet!$B1:$B2
                String refers = dictSheetName + "!$" + excelColumn + "$1:$" + excelColumn + "$" + rowLen;
                // 创建可被其他单元格引用的名称
//                Name name = workbook.createName();
                Name name = workbook.getName("dict" + entry.getKey());
//                DVConstraint constraint = DVConstraint.createExplicitListConstraint(list);
                if (name==null){
                    name=  workbook.createName();
                    // 设置名称的名字
                    name.setNameName("dict" + entry.getKey());
                    // 设置公式
                    name.setRefersToFormula(refers);
                    // 设置引用约束
                }
                constraint = helper.createFormulaListConstraint("dict" + entry.getKey());

            } else{
                // 设置下拉列表的值
                 constraint = helper.createExplicitListConstraint(entry.getValue().getSource());

            }

            // 设置约束
            DataValidation validation = helper.createValidation(constraint, rangeAddressList);

            validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
            
            if (validation instanceof XSSFDataValidation) {
                validation.setSuppressDropDownArrow(true);
                validation.setShowErrorBox(true);
            } else {
                validation.setSuppressDropDownArrow(false);
            }

            
            validation.createErrorBox("提示", "此值与单元格定义格式不一致!");
            // 阻止输入非下拉框的值
            sheet.addValidationData(validation);

        }
        //设置列为隐藏
        int hiddenIndex = workbook.getSheetIndex(dictSheetName);
        if (!workbook.isSheetHidden(hiddenIndex)) {
            workbook.setSheetHidden(hiddenIndex, true);
        }

    }
    /**
     * 将数字列转化成为字母列
     *
     * @param num
     * @return
     */
    private String getExcelColumn(int num) {
        String column = "";
        int len = alphabet.length - 1;
        int first = num / len;
        int second = num % len;
        if (num <= len) {
            column = alphabet[num] + "";
        } else {
            column = alphabet[first - 1] + "";
            if (second == 0) {
                column = column + alphabet[len] + "";
            } else {
                column = column + alphabet[second - 1] + "";
            }
        }
        return column;

    }



    public static String getExcelLine(int num) {
        String line = "";
        int first = num/26;
        int second = num % 26;
        if (first>0) {
            line = (char)('A'+first-1)+"";
        }
        line += (char)('A'+second)+"";
        return line;
    }


}


/**
 * @author 
 */
@Data
@ColumnWidth(15)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class XXXXExcel implements Serializable {
    private static final long serialVersionUID = 1L;


    /**
     * 污染类型
     */
    @ApiModelProperty(value = "污染类型")
    @ExcelProperty(value = "污染类型")
    @ExcelSelected(sourceClass = {ExcelSelected.class})
    private String polluteType;



}

public interface ExcelDynamicSelect {
        /**
         * 获取动态生成的下拉框可选数据
         * @return 动态生成的下拉框可选数据
         */
        String[] getSource();
    }

import java.lang.annotation.*;

@Documented
@Target({ElementType.FIELD})//用此注解用在属性上。
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
public @interface ExcelSelected {

    /**
     * 固定下拉内容
     */
    String[] source() default {};

    /**
     * 动态下拉内容
     */
    Class<? extends ExcelDynamicSelect>[] sourceClass() default {};

    /**
     * 设置下拉框的起始行,默认为第二行
     */
    int firstRow() default 1;

    /**
     * 设置下拉框的结束行,默认为最后一行
     */
    int lastRow() default 0x10000;

}

import lombok.Data;
import lombok.RequiredArgsConstructor;

import java.util.List;


//动态下拉框中的数据配置类
@Data
@RequiredArgsConstructor
public class ExcelSelected implements ExcelDynamicSelect {

    @Override
    public String[] getSource() {

        XXX xxx= SpringUtil.getBean("xxx", xxx.class);
        List<String> list= xxx.list();
        //当多列需要动态下拉框时,只需自定义类实现ExcelDynamicSelect中的方法,并在方法中查询数据即可。
        return list.toArray(new String[list.size()]);

    }
}

7.Mysql in用union优化

<select id="selectList" resultMap="BaseResultMap" parameterType="java.util.List" >
	<foreach collection="list" item="item" index="index" separator="UNION" >
  		(select * from table where id = #{item} )
	</foreach>
</select>