入职java学习总结

1.业务层导入service

    private final MarketingActivityService marketingActivityService;
    private final MarketingActivityAuditLogService marketingActivityAuditLogService;
    private final MarketingService marketingService;


    @Autowired
    public MarketingActivityController(MarketingActivityService marketingActivityService,
                                       MarketingActivityAuditLogService marketingActivityAuditLogService, MarketingService marketingService) {
        this.marketingActivityService = marketingActivityService;
        this.marketingActivityAuditLogService = marketingActivityAuditLogService;
        this.marketingService = marketingService;
    }

2.collect.stream().collect()

作用:list->map

用法:https://blog.csdn.net/huyizeng7300/article/details/116696994

List<DataCustomerTagPOJO> pojos = BeanConversionUtils.beanListConversion(allTagList, DataCustomerTagPOJO.class);

Map<String, DataCustomerTagPOJO> allTagMap = pojos.stream().collect(Collectors.toMap(DataCustomerTagPOJO::getTagCode, b -> b, (k1, k2) -> k1));

3.JSONObject.parseArray

作用: 该方法将Json字符串数据转换成集合对象。

https://www.cnblogs.com/luxianyu-s/p/9592218.html

String devInfoList = [{"devId":"869718026017001","cabinetId":17,"devType":13,"devTypeStr":"XXX","devName":"XALTE_2003A","cabinetNo":1,"cabinetDoorNo":3}]List<BatchDevInDto> batchDevInDtoList = JSONObject.parseArray(devInfoList, BatchDevInDto.class);

4.@RequestBody&@RequestParam(xxx)

RequestBody:获取前端放在请求body里面的参数

5.MalformedInputException: Input length = 1

yml里面不能有中文注释

6.查看Java类型

public static void main(String[] ags){     
    Integer i=1;          
    System.out.println(i.getClass().toString());   //返回class java.lang.Integer
}

7.swagger

@Api:修饰整个类,描述Controller的作用

@ApiOperation:描述一个类的一个方法,或者说一个接口

@ApiParam:单个参数描述



@ApiModel:用对象来接收参数

@ApiProperty:用对象接收参数时,描述对象的一个字段



其它若干


@ApiResponse:HTTP响应其中1个描述

@ApiResponses:HTTP响应整体描述

8.list下的增强for – forEach

package com.example.demo.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * list下的 增强for循环
 */
public class ForTest {
    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(5);
        list.add(65);

        //普通
        for (int i = 0; i < list.size(); i++) {
            System.out.println("list.get(i) = " + list.get(i));
        }

        //增强一
        for(Integer i : list){
            System.out.println("i = " + i);
        }

        //增强方式二
        list.forEach(item -> System.out.println("item = " + item));


    }
}

9、BeanConversionUtils? BeanList =>list

return BeanConversionUtils.beanListConversion(list, SubdivisionResultVO.class);2
    
  @Override
    public SubdivisionResultVO getSubdivisionById(Long id) {
        log.info("通过id查询人群,id:{}", id);
        SubdivisionDO subdivisionDO = this.getById(id);

        return BeanConversionUtils.beanConversion(subdivisionDO, new SubdivisionResultVO());
    }   

10.JedisUtils.getBean

public UserSessionVo getUserSession() {
   //获取用户缓存
   UserSessionVo userSessionVo = JedisUtils.getBean(CacheKey.CRM_JDM_USER_SESSION_KEY + getSessionId(), UserSessionVo.class);
   return userSessionVo;
}

11.mybatis-plus

1.orderByDesc

queryWrapper.orderByDesc("update_time");

2.ne(boolean condition, R column, Object val)

ne --> 不等于

public Boolean hasExistSubName(String masterId, Long id, String subName, int isCategory) {
    QueryWrapper<SubdivisionDO> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("master_id", masterId).eq("subdivision_name", subName).
            eq("is_category", isCategory).eq("state", SystemConstant.STATE_1);
    /**
     * ne(boolean condition, R column, Object val)
     *
     * null != id :查询条件   -->   null != id 时,添加“id” <>id的条件,否则不添加
     *
     */
    queryWrapper.ne(null != id ,"id", id);
    List<SubdivisionDO> list = this.list(queryWrapper);

    return list.size() > 0;
}

3.page

@Override
public PageDTO<SubdivisionResultVO> queryTable(SearchSubdivisionVO searchSubdivisionVO) {
    log.info("查询人群列表");
    Page<SubdivisionDO> subdivisionDOPage = new Page<>(searchSubdivisionVO.getStart(), searchSubdivisionVO.getLength());
    QueryWrapper<SubdivisionDO> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("state", SystemConstant.STATE_1).eq("master_id", searchSubdivisionVO.getMasterId()).eq("is_category", SystemConstant.STATE_0);
    if (null != searchSubdivisionVO.getCategoryId()) {
        queryWrapper.eq("parent_id", searchSubdivisionVO.getCategoryId());
    }
    if (null != searchSubdivisionVO.getPackageType()) {
        queryWrapper.eq("package_type", searchSubdivisionVO.getPackageType());
    }
    if (null != searchSubdivisionVO.getIsSaveAs()) {
        queryWrapper.eq("is_save_as", searchSubdivisionVO.getIsSaveAs());
    }
    if (StringUtils.isNotBlank(searchSubdivisionVO.getSubName())) {
        queryWrapper.like("subdivision_name", searchSubdivisionVO.getSubName());
    }
    queryWrapper.orderByDesc("update_time");

    Page<SubdivisionDO> page = new Page<>();
    page.setCurrent(searchSubdivisionVO.getStart());
    page.setSize(searchSubdivisionVO.getLength());
    page = this.page(subdivisionDOPage, queryWrapper);
	// ???
    return PageDTO.voPageConversion(page,SubdivisionResultVO.class);
}

12.命名规范

# JDM

## 对象定义要求

对象定义:
前端交互:requestVO/responseVO
数据库持久对象:DO
数据库业务对象:BO
内部传输处理对象:DTO

requestVO包含:xxInsertVO 、xxUpdateVO、xxDeleteVO、xxQueryVO
responseVO包含:xxResultVO
插入:xxInsertVO 
更新:xxUpdateVO
删除:xxDeleteVO
查询:xxQueryVO
响应结果:xxResultVO

一个requestVO如果包含多个复杂对象,复杂对象定义为DTO;

13.抛出异常的新方式

@Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveSubdivision(CreateSubdivisionVO fromSubdivision, String shopId) {
        
        
    }

14.开发规范的几个常用词

PO(Persistant Object) 持久对象
用于表示数据库中的一条记录映射成的 java 对象。PO 仅仅用于表示数据,没有任何数据操作。通常遵守 Java Bean 的规范,拥有 getter/setter 方法。

可以理解是一个PO就是数据库中的一条记录;可以理解某个事务依赖的原始数据;好处是可以将一条记录最为一个对象处理,可以方便转化为其他对象

BO(Business Object) 业务对象
封装对象、复杂对象,里面可能包含多个类
主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。

用于表示一个业务对象。BO 包括了业务逻辑,常常封装了对 DAO、RPC 等的调用,可以进行 PO 与 VO/DTO 之间的转换。BO 通常位于业务层,要区别于直接对外提供服务的服务层:BO 提供了基本业务单元的基本业务操作,在设计上属于被服务层业务流程调用的对象,一个业务流程可能需要调用多个 BO 来完成。

比如一个简历,有教育经历、工作经历、社会关系等等。
我们可以把教育经历对应一个PO,工作经历对应一个PO,社会关系对应一个PO。
建立一个对应简历的BO对象处理简历,每个BO包含这些PO。
这样处理业务逻辑时,我们就可以针对BO去处理。

VO(Value Object) 表现对象
前端界面展示;value object值对象;ViewObject表现层对象;主要对应界面显示的数据对象。对于一个WEB页面,或者SWT、SWING的一个界面,用一个VO对象对应整个界面的值;对于Android而言即是activity或view中的数据元素。

用于表示一个与前端进行交互的 java 对象。有的朋友也许有疑问,这里可不可以使用 PO 传递数据?实际上,这里的 VO 只包含前端需要展示的数据即可,对于前端不需要的数据,比如数据创建和修改的时间等字段,出于减少传输数据量大小和保护数据库结构不外泄的目的,不应该在 VO 中体现出来。通常遵守 Java Bean 的规范,拥有 getter/setter 方法。

DTO(Data Transfer Object) 数据传输对象
前端调用时传输;也可理解成“上层”调用时传输;
比如我们一张表有100个字段,那么对应的PO就有100个属性。但是我们界面上只要显示10个字段,客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,这时我们就可以用只有这10个属性的DTO来传递结果到客户端,这样也不会暴露服务端表结构.到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO.

用于表示一个数据传输对象。DTO 通常用于不同服务或服务不同分层之间的数据传输。DTO 与 VO 概念相似,并且通常情况下字段也基本一致。但 DTO 与 VO 又有一些不同,这个不同主要是设计理念上的,比如 API 服务需要使用的 DTO 就可能与 VO 存在差异。通常遵守 Java Bean 的规范,拥有 getter/setter 方法

DAO(Data access object) 数据访问对象
这个大家最熟悉,和上面几个O区别最大,基本没有互相转化的可能性和必要.,主要用来封装对数据库的访问。通过它可以把POJO持久化为PO,用PO组装出来VO、DTO;

用于表示一个数据访问对象。使用 DAO 访问数据库,包括插入、更新、删除、查询等操作,与 PO 一起使用。DAO 一般在持久层,完全封装数据库操作,对外暴露的方法使得上层应用不需要关注数据库相关的任何信息。

POJO(Plain ordinary java object) 简单java对象
一个POJO持久化以后就是PO;直接用它传递、传递过程中就是DTO;直接用来对应表示层就是VO。

举个例子:
事情:统计研发部门中的季度绩效(暂定以工程师填写的为准,当然实际上大部分不是)
过程:CTO发布统计绩效请求(附带要求:每个人对应的绩效等级)->各个组(也可以是子部门)负责人发布统计绩效请求(每个对应的绩效等级,并将绩效分为了3个方面)->每位开发工程师统计自己绩效(自身各个方面);
可以从例子中看到:每个责任人要求都不同;
对于CTO,他需要知道的是该季度所用员工的绩效等级;这里可以认为VO:员工姓名、绩效等级;
开发工程师:需将本人这个季度的各个方面的表现都列出来:员工姓名、绩效等级、A方面表现内容及等级、B方面表现内容及等级、C方面表现内容及等级、D方面表现内容及等级、E方面表现内容及等级、F方面表现内容及等级、E方面表现内容及等级;此处可认为是PO:员工姓名、绩效等级、A方面表现内容、A方面等级….E方面表现内容、E方面等级;
然后开发工程师将员工姓名、绩效等级、A方面表现内容及等级、B方面表现内容及等级、C方面表现内容及等级内容传递给小组负责人;此处传递的对象就是DTO
小组负责人:从开发工程师中获取到数据后,经过评定,然后得出员工姓名、绩效等级、原因;此处的评定,可以理解为BO;

14.Objects中的equals方法

避免空指针

Objects.equals(a,b);

//容易空指针
String str = null;
String str2 = "abc";
boolean flag = str.equals(str2);

15.java中两个Integer比较大小需要注意的误区

通过下面的例子,来了解 Integer 比较大小需要注意的几点。

Integer a = 1;
Integer b = 1;
System.out.println(a == b);     // true

Integer c = 128;
Integer d = 128;
System.out.println(c == d);    // false
这是因为 Integer 类在内存中有一个值的范围为[-128, 127]的对象池。

只要 Integer 对象的值在[-128, 127]范围内,都是从这个对象池中取。所以只要是这个范围的 Integer 对象,只要值相同,就是同一个对象。那么 == 的结果,就是 true。超过了这个范围,则会 new 新的 Integer 对象,尽管值相同,但是已经是不同的对象了。

如果你是这样写:

Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a == b);    // false
那么结果就是 false 了,因为他重新生成对象了;

如果超过了 [-128, 127] 之间的值,被装箱后的 Integer 对象并不会被重用,即相当于每次装箱时都新建一个 Integer 对象,所以 Integer c = 128Integer d = 128 参考的不同的对象。内存地址不同,结果是 false,对象如果要比较值,应该用 .equals()方法。

16.浮点类型的比较

\8.**强制**】浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用

equals 来判断。

说明:浮点数采用“尾数+阶码”的编码方式,类似于科学计数法的“有效数字+指数”的表示方式。二进

制无法精确表示大部分的十进制小数,具体原理参考《码出高效》。

反例:

 float a = 1.0f - 0.9f;

 float b = 0.9f - 0.8f;

 if (a == b) {

 // 预期进入此代码快,执行其它业务逻辑

 // 但事实上 a==b 的结果为 false

 }

 Float x = Float.valueOf(a);

 Float y = Float.valueOf(b);

 if (x.equals(y)) {

 // 预期进入此代码快,执行其它业务逻辑

 // 但事实上 equals 的结果为 false

 }

正例:

(1) 指定一个误差范围,两个浮点数的差值在此范围之内,则认为是相等的。

 float a = 1.0f - 0.9f;

 float b = 0.9f - 0.8f;

 float diff = 1e-6f;

 if (Math.abs(a - b) < diff) {

 System.out.println("true");

 }

(2) 使用 BigDecimal 来定义值,再进行浮点数的运算操作。

 BigDecimal a = new BigDecimal("1.0");

 BigDecimal b = new BigDecimal("0.9");

 BigDecimal c = new BigDecimal("0.8");

 BigDecimal x = a.subtract(b);

 BigDecimal y = b.subtract(c);

 if (x.equals(y)) {

 System.out.println("true");

 }

16.BigDecimal

【BigDecimal是什么?】

1、简介
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

2、构造器描述
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //不推荐使用
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用

3、方法描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。

代码示例在15

【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

说明:下例中,反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行

append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。

StringBuffer sb = new StringBuffer();
for (int i = 0; i < 100; i++) {
    sb.append("hello");
}

System.out.println(sb.toString());

17.ArrayList的subList()

【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异
常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。
说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList 而是 ArrayList 的一个视图,对
于 SubList 子列表的所有操作最终会反映到原列表上。
//NNegative example:
List<String> list = new ArrayList<String>();
list.add("22");
//warn
List<String> test = (ArrayList<String>) list.subList(0, 1);  


//Positive example:
List<String> list2 = new ArrayList<String>(list.subList(0, 1));

其中subList(0, 1)取得的是下标为00的元素,不包含下标为1的元素.

18.Map keySet时不能添加问题

强制】使用 Map 的方法 keySet()/values()/entrySet()返回集合对象时,不可以对其进行添

加元素操作,否则会抛出 UnsupportedOperationException 异常。

public class MapTest {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("one", "first");
        map.put("two", "second");
        for (String str : map.keySet()) {
            map.put("three", "3");//异常:java.util.ConcurrentModificationException
            System.out.println(map.get(str));

        }
    }
}

19.集合转数组

参考:https://www.runoob.com/java/java-arraylist-toarray.html

arraylist.toArray(T[] arr)

强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一

致、长度为 0 的空数组。

反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出

现 ClassCastException 错误。

正例:

List list = new ArrayList<>(2);

list.add(“guan”);

list.add(“bao”);

String[] array = list.toArray(new String[0]);

说明:使用 toArray 带参方法,数组空间大小的 length:

1) 等于 0,动态创建与 size 相同的数组,性能最好。

2) 大于 0 但小于 size,重新创建大小等于 size 的数组,增加 GC 负担。

Java 开发手册

12/44

3) 等于 size,在高并发情况下,数组创建完成之后,size 正在变大的情况下,负面影响与上相同。

4) 大于 size,空间浪费,且在 size 处插入 null 值,存在 NPE 隐患。

20.Array.asList()得到的List不能修改

使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方

法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList 体现的是适

配器模式,只是转换接口,后台的数据仍是数组。

String[] str = new String[] { “yang”, “hao” };

List list = Arrays.asList(str);

第一种情况:list.add(“yangguanbao”); 运行时异常。

第二种情况:str[0] = “changed”; 也会随之修改,反之亦然。

1.修改异常

package com.example.demo.Test;

import java.util.Arrays;
import java.util.List;

public class ListTest {
    public static void main(String[] args) {

        Integer[] arr = new Integer[]{3, 343, 54};
        List list = Arrays.asList(arr);
        for (Object item : list) {
            System.out.println(item);
        }

        list.add(43);//异常




    }
}


Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.example.demo.Test.ListTest.main(ListTest.java:16)

2.数组改变 list随之改变

package com.example.demo.Test;

import java.util.Arrays;
import java.util.List;

public class ListTest {
    public static void main(String[] args) {

        Integer[] arr = new Integer[]{3, 343, 54};
        List list = Arrays.asList(arr);
//      list.add(43);
        arr[2] = 888;

        for (Object item : list) {
            System.out.println(item);
        }

    }
}



3
343
888

Process finished with exit code 0

21.instanceof用法

public class Application {

public static void main(String[] args) {

// Object > Person > teacher
// Object > Person > Student
// Object > String
Object o = new Student(); // 主要看这个对象是什么类型与实例化的类名
// instanceof关键字可以判断左边对象是否是右边类或者子类的一个实例
System.out.println(o instanceof Student); // o 是Student类的一个实例对象 所以判断右边类跟student有无关系 以及显示声明有无关系
System.out.println(o instanceof Person); // true
System.out.println(o instanceof Object); // true
System.out.println(o instanceof String); // false
System.out.println(o instanceof Teacher); // 无关系
System.out.println("========================");
Person person = new Student();
System.out.println(person instanceof Person); // true
System.out.println(person instanceof Object); // true
// System.out.println(person instanceof String); // 编译错误
System.out.println(person instanceof Teacher); // 无关系
  }
}

22.forEach循环不remove、add

强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用

Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。

正例:

List<String> list = new ArrayList<>();

list.add("1");

list.add("2");

Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (删除元素的条件) {

iterator.remove();

}

}

反例:

for (String item : list) {

if ("1".equals(item)) {

list.remove(item);

}

}

22.集合初始化

1.map初始值

集合初始化时,指定集合初始值大小。

说明:HashMap 使用 HashMap(int initialCapacity) 初始化。

正例:initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即 loader factor)默认

为 0.75,如果暂时无法确定初始值大小,请设置为 16(即默认值)。

反例:HashMap 需要放置 1024 个元素,由于没有设置容量初始大小,随着元素不断增加,容量 7 次被

迫扩大,resize 需要重建 hash 表,严重影响性能。

2.map遍历

【推荐】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。

说明:keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出 key 所对应

的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是 JDK8,

使用 Map.forEach 方法。

正例:values()返回的是 V 值集合,是一个 list 集合对象;keySet()返回的是 K 值集合,是一个 Set 集合

对象;entrySet()返回的是 K-V 值组合集合。

package com.example.demo.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapTest {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("one", "first");
        map.put("two", "second");
//        for (String str : map.keySet()) {
            map.put("three", "3");
//            System.out.println(map.get(str));
//
//        }

        Set<Map.Entry<String, String>> entrySet = map.entrySet();

        for (Map.Entry<String, String> entry : entrySet) {
            System.out.println("entry = " + entry.getKey()+","+entry.getValue());
        }

    }
}

3.map不能存null值

高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格:

集合类 Key Value Super 说明

Hashtable 不允许为 null 不允许为 null Dictionary 线程安全

ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 锁分段技术(JDK8:CAS)

TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全

HashMap 允许为 null 允许为 null AbstractMap 线程不安全

反例:由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上,存储

null 值时会抛出 NPE 异常

23.List去重

1.利用 Set 集合去重

import lombok.Data;
 
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
 
public class DistinctExample {
    public static void main(String[] args) {
        // 创建并给 List 赋值
        List<Person> list = new ArrayList<>();
        list.add(new Person("李四", "123456", 20));
        list.add(new Person("张三", "123456", 18));
        list.add(new Person("王五", "123456", 22));
        list.add(new Person("张三", "123456", 18));
        // 去重操作
        HashSet<Person> set = new HashSet<>(list);
        // 打印集合信息set.forEach(p -> System.out.println(p));
    }
}

2.自定义去重

import lombok.Data;
 
import java.util.ArrayList;
import java.util.List;
 
public class DistinctExample {
    public static void main(String[] args) {
        // 创建并给 List 赋值
        List<Person> list = new ArrayList<>();
        list.add(new Person("李四", "123456", 20));
        list.add(new Person("张三", "123456", 18));
        list.add(new Person("王五", "123456", 22));
        list.add(new Person("张三", "123456", 18));
        // 去重操作
        List<Person> newList = new ArrayList<>(list.size());
        list.forEach(i -> {
            if (!newList.contains(i)) { // 如果新集合中不存在则插入newList.add(i);
            }
        });
        // 打印集合newList.forEach(p -> System.out.println(p));
    }
}

3.使用 Stream 去重

public class DistinctExample {
    public static void main(String[] args) {
        // 创建并给 List 赋值
        List<Person> list = new ArrayList<>();
        list.add(new Person("李四", "123456", 20));
        list.add(new Person("张三", "123456", 18));
        list.add(new Person("王五", "123456", 22));
        list.add(new Person("张三", "123456", 18));
        // 去重操作
        list = list.stream().distinct().collect(Collectors.toList());
        // 打印集合信息
        list.forEach(p -> System.out.println(p));
    }
}
 
@Data
class Person {
    private String name;
    private String password;
    private int age;
 
    public Person(String name, String password, int age) {
        this.name = name;
        this.password = password;
        this.age = age;
    }
}

24.switch参数null值问题

当 switch 括号内的变量类型为 String 并且此变量为外部参数时,必须先进行 null

判断。

package com.example.demo.Test;

public class SwitchTest {
    public static void main(String[] args) {
        method(null);
    }

    public static void method(String param) {
        switch (param) {
            // 肯定不是进入这里
            case "sth":
                System.out.println("it's sth");
                break;
            // 也不是进入这里
            case "null":
                System.out.println("it's null");
                break;
            // 也不是进入这里
            default:
                System.out.println("default");
        }
    }
}


Exception in thread "main" java.lang.NullPointerException

25.参数校验???

【参考】下列情形,需要进行参数校验:

1) 调用频次低的方法。

2) 执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参数错误导致

中间执行回退,或者错误,那得不偿失。

3) 需要极高稳定性和可用性的方法。

4) 对外提供的开放接口,不管是 RPC/API/HTTP 接口。

5) 敏感权限入口。

12.【参考】下列情形,不需要进行参数校验:??????????没懂

1) 极有可能被循环调用的方法。但在方法说明里必须注明外部参数检查要求。

2) 底层调用频度比较高的方法。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露

问题。一般 DAO 层与 Service 层都在同一个应用中,部署在同一台服务器中,所以 DAO 的参数校验,可

以省略。

3) 被声明成 private 只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参数已经做过检

查或者肯定不会有问题,此时可以不校验参数。

26、注释开发规范

强制】所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、

异常说明外,还必须指出该方法做什么事情,实现什么功能。

说明:对子类的实现要求,或者调用注意事项,请一并说明。

\3. 【强制】所有的类都必须添加创建者和创建日期。

27.随机数

注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够

取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后

取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。

public class RandomTest {
    public static void main(String[] args) {
        Random random = new Random();
        for(int i=0;i<100;i++) {
              //用于生成0~100之间的随机数(包含0不包含100)
            System.out.println(random.nextInt(100));
            }
        }
    
    for(int i=0;i<100;i++) {
            System.out.println(random.nextLong());
        }
}

46
62
46
69
2
-6801696996200159747
4054216794411610809
4965870808550007374
702570525935977311

28.时间规范

强制】获取当前毫秒数 System.currentTimeMillis(); 而不是 new Date().getTime();

说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime()的方式。在 JDK8 中,针对统计时

间等场景,推荐使用 Instant 类。

\5. 【强制】日期格式化时,传入 pattern 中表示年份统一使用小写的 y。

说明:日期格式化时,yyyy 表示当天所在的年,而大写的 YYYY 代表是 week in which year

(JDK7 之后引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,

只要本周跨年,返回的 YYYY 就是下一年。另外需要注意:

  • 表示月份是大写的 M

  • 表示分钟则是小写的 m

  • 24 小时制的是大写的 H

  • 12 小时制的则是小写的 h

正例:表示日期和时间的格式如下所示:

new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);

日期转换

package com.example.demo.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TimeTest {
    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        System.out.println(new Date().getTime());
        StringBuffer sb = new StringBuffer();


        /**
         * 日期转字符串
         */
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = sdf.format(new Date());

        System.out.println(dateString);

        /**
         * 字符串转日期
         */
        Date date;
        try {
            date = sdf.parse(dateString);
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }


    }
}

29.数据库规范

小数类型为 decimal,禁止使用 float 和 double。

如果存储的字符串长度几乎相等,使用 char 定长字符串类型。

\8. 【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长

度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索

引效率。

强制】表必备三字段:id, create_time, update_time。

说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。create_time, update_time

的类型均为 datetime 类型。

强制】必须使用varchar(20)存储手机号

a)涉及到区号或者国家代号,可能出现±()

b)手机号会去做数学运算么?

c)varchar可以支持模糊查询,例如:like“138%”

【推荐】表的命名最好是遵循“业务名称_表的作用”。

正例:jdpay_task / force_project / trade_config

30.类型转换

​ char

​ ↓

Byte→short→int→long—›float→double

自动转换有以下规律:

  1. 小的类型自动转化为大的类型
  2. 整数类型可以自动转化为浮点类型,可能会产生舍入误差

1.自动类型转换(隐式转换)

小的类型自动转化为大的类型

  • 示例1
byte A = 70;
int b = A + 30;
System.out.println("b = " + b);//b = 100
  • 示例2
byte a = 0;

int b = a;

long c = a;

float d = a;

double e = a;

System.out.println("b="+b);

System.out.println("c="+c);

System.out.println("d="+d);

System.out.println("e="+e);

2.整数类型可以自动转化为浮点类型

float A = 2 + 10f;

float B = A - 11.9f;

System.out.println(B)//0.10000038

1.Integer => int

Integer item = new Integer();
//Integer => int
item.intValue() 

2.字符型与数字之间转换

// String -> Integer,Float,Double
String str = "4775";
Integer integer = Integer.parseInt(str);
Float f = Float.parseFloat(str);
Double d = Double.parseDouble(str);

System.out.println("integer = " + integer);// integer = 4775
System.out.println("f = " + f);// f = 4775.0
System.out.println("d = " + d);// d = 4775.0


// String -> 字符串数组
// 方式一
String str1 = "字符串转数组";

String[] strArr1 = new String[str1.length()];
for (int i = 0; i < str1.length(); i++) {
    strArr1[i] = String.valueOf(str1.charAt(i));
    System.out.println("strArr1[i] = " + strArr1[i]);
}
// 方式二 根据正则表达是分割字符串
String[] strArr2 = str1.split("");
for (String item :
        strArr2) {
    System.out.println("item = " + item);
}


// String -> byte[]
byte[] bytes = str1.getBytes(StandardCharsets.UTF_8);
for (byte b : bytes) {
    System.out.print(b);
}


/*------------------------------------------------------------------------------------------*/


/**
 *@Description: int Integer FLOAT double array -> String
 * @param [args]
 * @return void
 * @author HuiLong.Ding
 * @date 2022/7/28 11:23
 */

int a = 10;
Integer b = 12;
Long l= 342L;
Float f2 = 13f;
Double d3 = 442d;

String s1 = String.valueOf(a);
String s2 = String.valueOf(b);
String s5 = String.valueOf(l);
String s3 = String.valueOf(f2);
String s4 = String.valueOf(d3);

System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
System.out.println("s5 = " + s5);
System.out.println("s3 = " + s3);
System.out.println("s4 = " + s4);

2.json => 对象

// 1.
JSONObject.parseObject(JedisUtils.getString(CacheKey.TAG_CATEGORY_MAP_KEY), new TypeReference<LinkedHashMap<String, TagCategoryVo>>() {
});


3.字符串 JSON=> List

// 2.
private List<DataCustomerTagDO> findAllTagListByCache() {
        String allTagListString = JedisUtils.getString(CacheKey.ALL_TAG_LIST_KEY);
        List<DataCustomerTagDO> dataCustomerTagDOS = JSONObject.parseArray(allTagListString, DataCustomerTagDO.class);
        if (null == dataCustomerTagDOS) {
            QueryWrapper<DataCustomerTagDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("state", SystemConstant.STATE_1).eq("visiable", SystemConstant.STATE_1).eq("status", SystemConstant.STATUS_1);
            dataCustomerTagDOS = this.list(queryWrapper);
            allTagListString = JSONObject.toJSONString(dataCustomerTagDOS);
            JedisUtils.saveString(CacheKey.ALL_TAG_LIST_KEY, allTagListString);
        }
        return dataCustomerTagDOS;
    }

4.List => JsonString

JedisUtils.saveString(CacheKey.GOODS_CATEGORY_TREE,JSONObject.toJSONString(treeNodeList));

5.ObjectListDO—>ObjectListVO

@Override
public List<SubdivisionResultVO> getSubdivisionList(String masterId) {
    log.info("查询商家人群列表");
    QueryWrapper<SubdivisionDO> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("master_id", masterId).eq("state", SystemConstant.STATE_1);
    List<SubdivisionDO> list = this.list(queryWrapper);

    return BeanConversionUtils.beanListConversion(list, SubdivisionResultVO.class);
}

6.ObjectDO—>ObjectVO

@Override
public SubdivisionResultVO getSubdivisionById(Long id) {
    log.info("通过id查询人群");
    SubdivisionDO subdivisionDO = this.getById(id);

    return BeanConversionUtils.beanConversion(subdivisionDO, new SubdivisionResultVO());
}

VO—> DO

public Boolean saveTemplate(SmsCareTemplateInsertVO smsCareTemplateInsertVO, UserSessionVo userSessionVo) {
        String content = smsCareTemplateInsertVO.getTemplate();
        String shortUrl = smsCareTemplateInsertVO.getTemplateParams();
        // 校验模板内容
        content = this.checkSmsTemplateContent(content,shortUrl,userSessionVo);
        // 提交京东审核获取modelId
        IsvSmsTemplateTypeEnum isvSmsTemplateTypeEnum = IsvSmsTemplateTypeEnum.getByCode(smsCareTemplateInsertVO.getMarketingManner());
        if(null == isvSmsTemplateTypeEnum){
            throw new ApiException("模板类型参数错误!");
        }
        Long modelId = this.isvCreateSmsTemplate(userSessionVo.getMasterId(),
                                                 smsCareTemplateInsertVO.getTemplate(),
                                                 smsCareTemplateInsertVO.getTemplateTitle(),
                                                 isvSmsTemplateTypeEnum.getModelTypeId(),
                                                 isvSmsTemplateTypeEnum.getOperators());
        log.info("modelId=={}", modelId);
        // 保存到本地库
        SmsCareTemplateDO smsCareTemplateDO = new SmsCareTemplateDO();
    
        BeanConversionUtils.beanConversion(smsCareTemplateInsertVO, smsCareTemplateDO);
    
        log.info("smsCareTemplateDO=={}", smsCareTemplateDO);
        smsCareTemplateDO.setModelId(modelId);//设置modelId
        smsCareTemplateDO.setMasterId(userSessionVo.getMasterId());
        smsCareTemplateDO.setShopId(userSessionVo.getShopId());
        smsCareTemplateDO.setTemplate(content);

        smsCareTemplateDO.setStatus(SystemConstant.STATUS_1);
        //TODO 这里原来使用的是saveOrUpdate
        return this.save(smsCareTemplateDO);
    }

7.时间类型转换

Date => LocalDateTime

Date orderTime = smsBillRecharge.getOrderTime();
LocalDateTime orderLocalDateTime = orderTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
 /**
     * LocalDate转Date
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        if (null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
}

/**
 * Date转LocalDate
 * @param date
 */
public static LocalDate date2LocalDate(Date date) {
    if (null == date) {
        return null;
    }
    return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

}

/**
 * Date转换为LocalDateTime
 * @param date
 */
public static LocalDateTime date2LocalDateTime(Date date){
    Instant instant = date.toInstant();
    ZoneId zoneId = ZoneId.systemDefault();
    LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
  return localDateTime;
}

/**
 * LocalDateTime转换为Date
 * @param localDateTime
 */
public static Date localDateTime2Date( LocalDateTime localDateTime){
    ZoneId zoneId = ZoneId.systemDefault();
    ZonedDateTime zdt = localDateTime.atZone(zoneId);
    Date date = Date.from(zdt.toInstant());
   return date;
}

https://blog.csdn.net/qq_33414176/article/details/115669100?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166174296116780357241408%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166174296116780357241408&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-1-115669100-null-null.142v42pc_rank_34,185v2control&utm_term=Duration&spm=1018.2226.3001.4187)

Date、LocalDateTime、字符串 时间相互转化

LocalDateTime转unix时间戳

//获取秒数
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
//获取毫秒数
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
unix时间戳转LocalDateTime
long timestamp = System.currentTimeMillis();
LocalDateTime localDateTime = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
DateStringDate d1 = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = format.format(d1);
String转date
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");//注意月份是MM
Date date = simpleDateFormat.parse("2019-09-02");
System.out.println(date);
LocalDateTimeString
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
StringLocalDateTime
String dateStr = "2019-10-28 12:03:15";
DateTimeFormatter localDateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime date = LocalDateTime.parse(dateStr, localDateTimeFormat);
 DateLocalDateTime
LocalDateTime localDateTime = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTimeDate
Date date = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());

31.数据初始值

包装类基本数据类型
Booleanboolean false
Bytebyte 0
Shortshort 0
Integerint 0
Longlong0 L
Characterchar /0000
Floatfloat 0.0F
Doubledouble 0.0D

32、bug集合

1.equired a bean of type ‘XXX‘ that could not be found.

impl实现类没有添加@Service注释

参考:https://blog.csdn.net/weixin_39887965/article/details/124862563?ops_request_misc=&request_id=&biz_id=102&utm_term=.SubdivisionRecommendControlle&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-124862563.142v32experiment_2_v1,185v2control&spm=1018.2226.3001.4187

33.配置Redis开机自启

如何打开服务呢?

方式一:Win+R快捷键输入services.msc,然后回车或者点击确定

方式二:此电脑(win7我的电脑)邮件单击(管理->服务与应用程序->服务)

如何添加redis服务?

再一次运行cmd终端命令行,切换到redis所在的目录,

输入:

redis-server --service-install redis.windows-service.conf --loglevel verbose

34.try catch final return

35.枚举类 Enum

values(), ordinal() 和 valueOf() 方法

enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。

values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

  • values() 返回枚举类中所有的值。
  • ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
  • valueOf()方法返回指定字符串值的枚举常量。
package com.example.demo.Test;

/**
 * @BelongsProject: demo
 * @BelongsPackage: com.example.demo.Test
 * @Author: HuiLong.Ding
 * @Description: TODO
 * @Date: 2022/07/26  10:20
 */

public class EnumTest {
    public static void main(String[] args) {
        Color c = Color.RED;
        System.out.println(c);

        // 迭代元素
        for (Color cc : Color.values()) {
            System.out.println("cc = " + cc);

        }

        // 调用 values()
        Color[] arr = Color.values();

        // 迭代枚举
        for (Color col : arr)
        {
            // 查看索引
            System.out.println(col + " at index " + col.ordinal());
        }

        // 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException
        System.out.println(Color.valueOf("RED"));
        // System.out.println(Color.valueOf("WHITE"));
    }


}


enum Color {
    RED(1, "大红色五星红旗"),
    GREEN(2, "头顶青青草原");

    private Integer code;
    private String description;

    Color(Integer code, String description) {
        this.code = code;
        this.description = description;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Color{" +
                "code=" + code +
                ", description='" + description + '\'' +
                '}';
    }
}



public static SubdivisionOrderByTypeEnum getByCode(int code) {
    for (SubdivisionOrderByTypeEnum it : SubdivisionOrderByTypeEnum.values()) {
        if (it.getCode() == code) {
            return it;
        }
    }
    return null;
}

36.时间

1.duration && period

duration && period

37.@Not注解

空检查
@Null			验证对象是否为null
@NotNull		验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank		检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty		检查约束元素是否为NULL或者是EMPTY. 
    
@NotEmpty 用在集合类上面
@NotBlank 用在String上面
@NotNull 用在八种基本类型上{ byte、shor、intlongfloatdoublebooleanchar}

Booelan检查
@AssertTrue		验证 Boolean 对象是否为 true  
@AssertFalse	验证 Boolean 对象是否为 false  

长度检查
@Size(min=, max=)		验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=)		验证注解的元素值长度在min和max区间内

日期检查
@Past		验证 DateCalendar 对象是否在当前时间之前  
@Future		验证 DateCalendar 对象是否在当前时间之后  
@Pattern	验证 String 对象是否符合正则表达式的规则

数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng"",Integernull
@Min			验证 NumberString 对象是否大等于指定的值  
@Max			验证 NumberString 对象是否小等于指定的值  
@DecimalMax		被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin		被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits			验证 NumberString 的构成是否合法  
@Digits(integer=,fraction=)		验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。

@Range(min=, max=)	验证注解的元素值在最小值和最大值之间
@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;

@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber信用卡验证
@Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)

38.mysql 安装配置

强制关闭mysql

tasklist |findstr mysql
taskkill -f -pid 1812

初始化

mysqld  --initialize-insecure

39.新建application模板 bug

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ooa799wT-1667555042409)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908102556804.png)]

1.接口访问404

扫描不到controller

application目录结果错误,要在web下,和controller一个层级

2.bean找不到

缺少yml配置文件

40.复制mysql表、

create table tb1 like tb2;

1
2、复制表的大体结构及全部数据,不会复制主键、索引等

create table tb1 select * from tb2;

3、分两步完成,先复制表结构,再插入数据

create table tb1 like tb2;
insert into tb1 select * from tb2;

41.mysql自增键过大

解决办法:DO的id上加一个注解

/**
 * 主键id
 */
@TableId(value="id",type = IdType.AUTO)
private Long id;

42.easyexcil 文件导出的使用

 /**
     *@Description: 导出发货列表信息
     * @param
     * @return
     * @author HuiLong.Ding
     * @date 2022/9/13 16:25
     */
    @Override
    public void exportGrantList(RewardGrantQueryVO rewardGrantQueryVO, HttpServletResponse response) throws IOException {
       // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
        //清空response
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=gb2312");
        response.setCharacterEncoding("utf-8");
        String date = LocalDateUtils.format(LocalDateTime.now(), "yyMMddhhmmss");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        StringBuilder fileNameBuilder = new StringBuilder();
        fileNameBuilder.append("发货明细").append(date);
        String fileName = URLEncoder.encode(fileNameBuilder.toString(), "UTF-8").replace("\\+", "%20");
        // 置response的Header
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        // 开始写出
        EasyExcel.write(response.getOutputStream())
                .registerWriteHandler(getStyleStrategy())// 设置字体样式
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 设置单元格宽度自适应
                .head(RewardGrantExportTitleVO.class)// 标题列表 通过ExcelProperty注解
                .autoCloseStream(true) // 自动关闭流
                .sheet("发货明细")// 设置sheet
                .doWrite(data(rewardGrantQueryVO));// 写入数据 List

    }

    private List<RewardGrantExportTitleVO> data(RewardGrantQueryVO rewardGrantQueryVO) {
        // todo 添加查询条件
        QueryWrapper queryWrapper = queryCondition(rewardGrantQueryVO);

        List<ActivityRewardGrantDO> activityRewardGrantDOS = activityRewardGrantMapper.selectList(queryWrapper);
        log.info("activityRewardGrantDOS=={}", activityRewardGrantDOS);

        List<RewardGrantExportTitleVO> rewardGrantExportTitleVOs = new ArrayList<>();
        activityRewardGrantDOS.forEach(item -> {
            RewardGrantExportTitleVO rewardGrantExportTitleVO = new RewardGrantExportTitleVO();
            rewardGrantExportTitleVO.setRewardGrantGuid(item.getRewardGrantGuid());
            rewardGrantExportTitleVO.setUserPin(item.getUserPin());
            rewardGrantExportTitleVO.setActivityName(item.getActivityName());
            rewardGrantExportTitleVO.setRewardName(item.getRewardName());
            rewardGrantExportTitleVO.setReceiptName(item.getReceiptName());
            rewardGrantExportTitleVO.setReceiptMobile(item.getReceiptMobile());
            rewardGrantExportTitleVO.setReceiptAddress(item.getReceiptAddress());
            rewardGrantExportTitleVO.setExpressCompany(item.getExpressCompany());
            rewardGrantExportTitleVO.setExpressBill(item.getExpressBill());
            // 发货状态
            if(item.getShipStatus() == 0){
                rewardGrantExportTitleVO.setStatus("未发货");
            }else if(item.getShipStatus() == 1){
                rewardGrantExportTitleVO.setStatus("已发货");
            }
//            // 时间处理
//            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//            rewardGrantExportTitleVO.setAwardTime(formatter.format(item.getAwardTime()));
//            rewardGrantExportTitleVO.setShipTime(formatter.format(item.getShipTime()));
            rewardGrantExportTitleVOs.add(rewardGrantExportTitleVO);
        });
        log.info("rewardGrantExportTitleVOs=={}", rewardGrantExportTitleVOs);
        return rewardGrantExportTitleVOs ;
    }


    //设置样式 去除默认表头样式及设置内容居中
    public static HorizontalCellStyleStrategy getStyleStrategy(){
        //内容样式策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        //垂直居中,水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容边框
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        //设置 自动换行
//        contentWriteCellStyle.setWrapped(true);
        // 字体策略
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 12);
        contentWriteCellStyle.setWriteFont(contentWriteFont);

        //头策略使用默认
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 获取字体实例
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("宋体");
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);

        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
package cn.nascent.jdhd.common.utils;

import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @BelongsProject: jd-hd
 * @BelongsPackage: cn.nascent.jdhd.common.utils
 * @Author: HuiLong.Ding
 * @Description: TODO
 * @Date: 2022/09/14  11:20
 */
public class Custemhandler extends AbstractColumnWidthStyleStrategy {

    private static final int MAX_COLUMN_WIDTH = 255;
    private  Map<Integer, Map<Integer, Integer>> CACHE = new HashMap(8);

    public Custemhandler() {
    }


    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
        if (needSetWidth) {
            Map<Integer, Integer> maxColumnWidthMap = (Map)CACHE.get(writeSheetHolder.getSheetNo());
            if (maxColumnWidthMap == null) {
                maxColumnWidthMap = new HashMap(16);
                CACHE.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);
            }

            Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
            if (columnWidth >= 0) {
                if (columnWidth > 255) {
                    columnWidth = 255;
                }

                Integer maxColumnWidth = (Integer)((Map)maxColumnWidthMap).get(cell.getColumnIndex());
                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
                    ((Map)maxColumnWidthMap).put(cell.getColumnIndex(), columnWidth);
                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
                }

            }
        }
    }

    private Integer dataLength(List<CellData> cellDataList, Cell cell, Boolean isHead) {
        if (isHead) {
            return 0;
        } else {
            CellData cellData = (CellData)cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();
            if (type == null) {
                return -1;
            } else {
                switch(type) {
                    case STRING:
                        return cellData.getStringValue().getBytes().length;
                    case BOOLEAN:
                        return cellData.getBooleanValue().toString().getBytes().length;
                    case NUMBER:
                        return cellData.getNumberValue().toString().getBytes().length;
                    default:
                        return -1;
                }
            }
        }
    }
}

42.自定义分页查询

<resultMap id="turntableJoinLogResultVO" type="cn.nascent.jdhd.service.activity.model.resultvo.activity.TurntableJoinLogResultBO">
    <result column="userPin" property="userPin"/>
    <result column="winStatus" property="winStatus"/>
    <result column="shipStatus" property="shipStatus"/>
    <result column="rewardType" property="rewardType"/>
    <result column="rewardName" property="rewardName"/>
    <result column="joinTime" property="joinTime"/>
</resultMap>

<select id="queryJoinLogPage" resultMap="turntableJoinLogResultVO">
    select atjl.user_pin userPin,
           atjl.win_status winStatus,
           arg.ship_status shipStatus,
           atjl.reward_type rewardType,
           atjl.reward_name rewardName,
           atjl.join_time joinTime
    from    activity_turntable_join_log atjl left join activity_reward_grant arg
    on atjl.join_guid = arg.process_id

    <where>
        atjl.state = 1 and arg.state = 1

        <if test="userPin != '' and userPin != null ">
            AND atjl.user_pin = #{userPin}
        </if>
        <if test="winStatus != '' and #winStatus != null ">
            AND atjl.win_status = #{winStatus}
        </if>
        <if test="shipStatus != '' and #shipStatus != null ">
            AND arg.ship_status = #{shipStatus}
        </if>
        <if test="rewardType != '' and #rewardType != null ">
            AND atjl.reward_type = #{rewardType}
        </if>

        <if test="startTime != '' and startTime != null and endTime != '' and endTime != null">
            AND atjl.join_time between #{startTime} and #{endTime}
        </if>


    </where>



</select>

43.遍历分页pagedto对象

@Override
public PageDTO<TurntableJoinLogResultVO> queryJoinLogPage(TurntableJoinLogQueryVO turntableJoinLogQueryVO) {
    log.info("分页查询参与记录列表入参: turntableJoinLogQueryVO={}", JSON.toJSONString(turntableJoinLogQueryVO));
    Page<ActivityTurntableJoinLogDO> activityTurntableJoinLogDOPage = new Page<>();
    PageDTO<TurntableJoinLogResultVO> resultVOPageDTO = new PageDTO<>();
    try {

        // todo 设置分页
        activityTurntableJoinLogDOPage.setCurrent(turntableJoinLogQueryVO.getStart());
        activityTurntableJoinLogDOPage.setSize(turntableJoinLogQueryVO.getLength());
        // todo 添加查询条件
        QueryWrapper<ActivityTurntableJoinLogDO> queryWrapper = queryCondition(turntableJoinLogQueryVO);
        // todo 分页查询
        activityTurntableJoinLogDOPage = this.page(activityTurntableJoinLogDOPage, queryWrapper);
        // todo 返回值封装
        System.out.println("resultVOPageDTO.getSize() = " + activityTurntableJoinLogDOPage.getRecords().size());
        List<TurntableJoinLogResultVO> turntableJoinLogResultVOList = new ArrayList<>();
        for (int i = 0; i < activityTurntableJoinLogDOPage.getRecords().size(); i++) {
            TurntableJoinLogResultVO turntableJoinLogResultVO = new TurntableJoinLogResultVO();
            System.out.println("JSON.toJSON(activityTurntableJoinLogDOPage.getRecords().get(i)) = " + JSON.toJSON(activityTurntableJoinLogDOPage.getRecords().get(i)));
            // 用户pin user_pin
            turntableJoinLogResultVO.setUserPin(activityTurntableJoinLogDOPage.getRecords().get(i).getUserPin());

            // 中奖状态
            Integer winStatus = activityTurntableJoinLogDOPage.getRecords().get(i).getWinStatus();
            if (winStatus == SystemConstant.ZERO) {
                turntableJoinLogResultVO.setWinStatus("未中奖");
            } else {
                turntableJoinLogResultVO.setWinStatus("已中奖");
            }

            // 奖品发放状态
            QueryWrapper<ActivityRewardGrantDO> qw = new QueryWrapper<>();
            qw.eq("process_id", activityTurntableJoinLogDOPage.getRecords().get(i).getJoinGuid()).last("limit 1");
            ActivityRewardGrantDO activityRewardGrantDO = activityRewardGrantMapper.selectOne(qw);
            turntableJoinLogResultVO.setShipStatus(RewardGrantShipStatusEnum.getDesc(activityRewardGrantDO.getShipStatus()));

            // 商品类型
            String rewardType = null;
            try {
                rewardType = ActivityRewardTypeEnum.getByCode(activityTurntableJoinLogDOPage.getRecords().get(i).getRewardType()).getDesc();
            } catch (Exception e) {
                throw new BadRequestException("奖品类型不存在!");
            }
            turntableJoinLogResultVO.setRewardType(rewardType);

            // 商品名称
            turntableJoinLogResultVO.setRewardName(activityTurntableJoinLogDOPage.getRecords().get(i).getRewardName());

            // 参与时间
            turntableJoinLogResultVO.setJoinTime(activityTurntableJoinLogDOPage.getRecords().get(i).getJoinTime());

            turntableJoinLogResultVOList.add(turntableJoinLogResultVO);
        }
        resultVOPageDTO.setData(turntableJoinLogResultVOList);
        resultVOPageDTO.setTotal(activityTurntableJoinLogDOPage.getTotal());
        resultVOPageDTO.setSize(activityTurntableJoinLogDOPage.getSize());
        resultVOPageDTO.setCurrent(activityTurntableJoinLogDOPage.getCurrent());

    } catch (BadRequestException e) {

        log.error("分页查询参与记录列表异常:e == " + e);
        throw new ApiException(e.getMessage());

    } catch (Exception e) {

        log.error("分页查询参与记录列表异常:e == " + e);
        throw new ApiException("查询失败");
    }
    return resultVOPageDTO;
}

43.导出文件

/**
 *@Description: 导出发货列表信息
 * @param
 * @return
 * @author HuiLong.Ding
 * @date 2022/9/13 16:25
 */
@Override
public void exportGrantList(RewardGrantQueryVO rewardGrantQueryVO, HttpServletResponse response) throws IOException {
    log.info("导出发货列表信息入参:rewardGrantQueryVO:{}", JSON.toJSONString(rewardGrantQueryVO));
    // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
    try {
        //清空response
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=gb2312");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("发货明细", "UTF-8").replace("\\+", "%20");
        // 置response的Header
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        // 开始写出
        EasyExcel.write(response.getOutputStream())
                .registerWriteHandler(ExcelUtils.buildHeadCellStyle())// 设置字体样式
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 设置单元格宽度自适应
                .head(RewardGrantExcelPropertyVO.class)// 标题列表 通过ExcelProperty注解
                .autoCloseStream(true) // 自动关闭流
                .sheet("发货明细")// 设置sheet
                .doWrite(data(rewardGrantQueryVO));// 写入数据 List
    } catch (IOException e) {
        log.error("导出信息列表异常:" + e);
        throw new RuntimeException(e);
    }

}
 /**
     * Build head cell style
     *
     * @return
     */
    public static HorizontalCellStyleStrategy buildHeadCellStyle() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为白色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)10);
        //加粗
        headWriteFont.setBold(false);
        // 字体样式
        headWriteFont.setFontName("宋体");
        headWriteCellStyle.setWriteFont(headWriteFont);
        //自动换行
        headWriteCellStyle.setWrapped(false);
        // 水平对齐方式
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 垂直对齐方式
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
        // 背景白色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        //自动换行
        contentWriteCellStyle.setWrapped(true);
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)10);
        // 水平对齐方式
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 垂直对齐方式
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 字体样式
        contentWriteFont.setFontName("宋体");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

    }

43.mybatis-plus 使用or

QueryWrapper<RewardCenterAwardDO> queryWrapper = new QueryWrapper<>();
queryWrapper.ne(null != rewardNameQueryVO.getId(), "id", rewardNameQueryVO.getId())
        .eq("master_id", masterId)
        .and(null != rewardNameQueryVO.getAwardType(), temp ->temp.eq("award_type",SystemConstant.ONE).or().eq("award_type", SystemConstant.TWO))
        .eq("award_name", rewardNameQueryVO.getAwardName())
        .eq("state", SystemConstant.STATE_1);
Long count = this.count(queryWrapper);

44.mysql中@的使用

select @a;

变量名,如果你不加的话,会认为这是一个列名,但是这列不存在,就报错了;

  • @变量名 : 定义一个用户变量.
  • = 对该用户变量进行赋值.

用户变量赋值有两种方式: 一种是直接用"=“号,另一种是用”:=“号。

其区别在于:

  • 使用set命令对用户变量进行赋值时,两种方式都可以使用;
  • 用select语句时,只能用”:=“方式,因为select语句中,”="号被看作是比较操作符。

(@i:=@i+1)

可以在生成查询结果表的时候生成一组递增的序列号

select (@i:=@i+5) as rownum, surname, personal_name from student, (select @i:=100) as init;

select @ids := 101,@l := 0

GROUP_CONCAT + group by

按照分组,连接字段上的数据,默认以,,也可以指定分割符

45.时间推移计算

@Test
    public void addTest(){
        SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date nowDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        Date updateDate1 = calendar.getTime();
        System.out.println("当前时间="+sdf.format(updateDate1));
        //往前推1个月
        calendar.add(Calendar.MONTH, -1);
        Date updateDate2 = calendar.getTime();
        System.out.println("往前推1个月的时间"+sdf.format(updateDate2));
        //往后推13个月
        calendar.add(Calendar.MONTH, 13);
        Date updateDate3 = calendar.getTime();
        System.out.println("往后推13个月的时间="+sdf.format(updateDate3));
        //往前推1天
        calendar.add(Calendar.DATE, -1);
        Date updateDate4 = calendar.getTime();
        System.out.println("往前推1天的时间"+sdf.format(updateDate4));
        //往前推1小时
        calendar.add(Calendar.HOUR_OF_DAY, -1);
        Date updateDate5 = calendar.getTime();
        System.out.println("往前推1小时的时间="+sdf.format(updateDate5));
        //往前推1分钟
        calendar.add(Calendar.MINUTE, -1);
        Date updateDate6 = calendar.getTime();
        System.out.println("往前推1分钟的时间="+sdf.format(updateDate6));
        //往前推1秒钟
        calendar.add(Calendar.SECOND, -1);
        Date updateDate7 = calendar.getTime();
        System.out.println("往前推1秒的时间="+sdf.format(updateDate7));
    }
**控制台输出:**
    当前时间=2017-10-27 16:35:58
    往前推1个月的时间2017-09-27 16:35:58
    往后推13个月的时间=2018-10-27 16:35:58
    往前推1天的时间2018-10-26 16:35:58
    往前推1小时的时间=2018-10-26 15:35:58
    往前推1分钟的时间=2018-10-26 15:34:58
    往前推1秒的时间=2018-10-26 15:34:57

46.node npm 重装

C:\Users\Administrator>npm install axios -save -g

added 8 packages, and audited 9 packages in 4s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New minor version of npm available! 8.15.0 -> 8.19.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.19.2
npm notice Run npm install -g npm@8.19.2 to update!
npm notice

C:\Users\Administrator>Run npm install -g npm@8.19.2 to update
'Run' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

C:\Users\Administrator> npm install -g npm@8.19.2 to update

47.mapper扫描不到

问题描述

No qualifying bean of type ‘xxx.xxx.mapper.XxxMapper‘ available: expected at least 1 bean which....

解决办法

@MapperScan(basePackages = "com.huilong.ding.dao.reward")

@SpringBootApplication
@ComponentScan(basePackages = "com.huilong.ding")
@MapperScan(basePackages = "com.huilong.ding.dao.reward")//加个扫描
public class MainApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MainApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class,args);
    }
}

48.util 工具方法

/**
 * @Description: 计算两个日期的相隔天数,采用四舍 退1 如 [2022-09-20 11:30,2022-09-22 15:21] 返回2 不是3
 * @author HuiLong.Ding
 * @date 2022/9/26 16:08
 */
private Integer daysBetween(String date1str, String date2str) throws ParseException {
    log.info("计算两个日期的相隔天数入参:date1str = {},date2str = {} ", date1str, date2str);
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Date date1 = format.parse(date1str);
    Date date2 = format.parse(date2str);
    return (int) ((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));
}

/**
 * @Description: 推算时间
 * @param timeStr      开始时间
 * @param intervalTime 间隔时间 eg: -1 往前推1 前, 5 往后推5天
 * @return
 * @author HuiLong.Ding
 * @date 2022/9/29 11:16
 */
private String calculationTime(String timeStr, Integer intervalTime) {
    log.info("根据开始时间推算结束时间入参:timeStr = {},intervalTime = {} ", timeStr, intervalTime);
    SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
    Date nowDate = DateUtil.parse(timeStr);
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(nowDate);
    // 推移
    calendar.add(Calendar.DATE, intervalTime);
    Date updateDate2 = calendar.getTime();
    String resTime = sdf.format(updateDate2);
    return resTime;
}

49.java实现折线统计图

50.获取list中某个字段的重复数据

 List<String> expressBillList = rewardGrantExcelPropertyVOList.stream().filter(p -> StringUtils.isNotEmpty(p.getExpressBill())).map(p -> p.getExpressBill()).collect(Collectors.toList());
            //获取重复的物流单号
            List<String> expressBillList1 = expressBillList.stream()
                    // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
                    .collect(Collectors.toMap(e -> e, e -> 1, Integer::sum))
                    .entrySet().stream().filter(e -> e.getValue() > 1).map(Map.Entry::getKey).collect(Collectors.toList());

            List<String> orderGuidList = rewardGrantExcelPropertyVOList.stream().filter(p->StringUtils.isNotEmpty(p.getRewardGrantGuid())).map(p -> p.getRewardGrantGuid()).collect(Collectors.toList());
            //获取重复的兑换编号
            List<String> orderGuidList1 = orderGuidList.stream()
                    // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
                    .collect(Collectors.toMap(e -> e, e -> 1, Integer::sum))
                    .entrySet().stream().filter(e -> e.getValue() > 1).map(Map.Entry::getKey).collect(Collectors.toList());

51.double保留两位小数

https://blog.csdn.net/Coder_kiwi/article/details/109280005?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166528473916782425147477%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166528473916782425147477&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-2-109280005-null-null.142v52pc_rank_34_queryrelevant25,201v3control_2&utm_term=double%E4%BF%9D%E7%95%99%E4%B8%A4%E4%BD%8D%E5%B0%8F%E6%95%B0&spm=1018.2226.3001.4187

52.mysql更新语句

UPDATE activity_turntable_join_log SET reward_type = 0   WHERE win_status = 0

53.如何新增测试模块

package cn.nascent.jdhd.service.activity.service.templatetrim;

import cn.nascent.jdhd.dao.reward.entity.ActivityRewardGrantDO;
import cn.nascent.jdhd.reward.service.ActivityRewardGrantService;
import cn.nascent.jdhd.service.activity.model.requestvo.activity.TurntableJoinLogQueryVO;
import cn.nascent.jdhd.service.activity.model.resultvo.activity.TurntableDataScreeningResultVO;
import cn.nascent.jdhd.service.activity.service.activity.ActivityTurntableJoinLogService;
import cn.nascent.jdhd.web.MainApplication;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @Author xiejinyou
 * @CreateTime 2022-09-16
 **/

@SpringBootTest(classes = {MainApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
@ActiveProfiles("dev")
class TemplateActivityConfigServiceTest {

    @Autowired
    private TemplateActivityConfigService templateActivityConfigService;

    @Autowired
    private ActivityTurntableJoinLogService activityTurntableJoinLogService;

    @Autowired
    private ActivityRewardGrantService activityRewardGrantService;

    @Test
    void updateReduceTemplateActivityTime() {

        templateActivityConfigService.updateReduceTemplateActivityTime("1222");
    }

    @Test
    void getDataScreening() {
        List<String> time = new ArrayList<>();
        time.add("2022-09-02");
        time.add("2022-10-23");

        TurntableJoinLogQueryVO turntableJoinLogQueryVO = new TurntableJoinLogQueryVO();
        turntableJoinLogQueryVO.setActivityId("129534d9-1ce9-4da4-956f-0e24c62878e5");
        turntableJoinLogQueryVO.setJoinTime(time);
        TurntableDataScreeningResultVO res = activityTurntableJoinLogService.getDataScreening(turntableJoinLogQueryVO);
        System.out.println("res = " + res);
    }

    @Test
    void  addActivityRewardGrant() {
        ActivityRewardGrantDO activityRewardGrantDO = new ActivityRewardGrantDO();
        activityRewardGrantDO.setRewardGrantGuid("测试_订单编号");
        activityRewardGrantDO.setUserPin("测试测试测试");
        activityRewardGrantDO.setActivityName("测试测试测试");
        activityRewardGrantDO.setRewardName("测试测试测试");
        activityRewardGrantDO.setShipStatus(1);
        activityRewardGrantDO.setReceiptName("生态合作");
        activityRewardGrantDO.setReceiptMobile("1433223");
        activityRewardGrantDO.setReceiptAddressDetail("杭州九堡东方电子商务园南讯软件");
        activityRewardGrantDO.setExpressCompany("EMS");
        activityRewardGrantDO.setExpressBill("5323132353231323");
        activityRewardGrantDO.setAwardTime(LocalDateTime.now());
        activityRewardGrantDO.setShipTime(LocalDateTime.now());
        for (int i = 0; i < 10; i++) {
            activityRewardGrantService.addActivityRewardGrant(activityRewardGrantDO);
        }
    }
}

54…stream().map().collect()

https://blog.csdn.net/weixin_40001125/article/details/105766744?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166597515216800186589620%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166597515216800186589620&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~pc_rank_v39-1-105766744-null-null.142v58pc_rank_34_2,201v3control_2&utm_term=initiateInviteList.stream%28%29.map&spm=1018.2226.3001.4187

取list中的其中一列

List<String> joinTimeList = initiateInviteList.stream().map(DailyInviteDataStatisticsResultBO::getJoinTime).collect(Collectors.toList());

排序

List<String> initiateInviteNumList = initiateInviteList.stream()
        .sorted(Comparator.comparing(DailyInviteDataStatisticsResultBO::getJoinTime))
        .map(DailyInviteDataStatisticsResultBO::getCount).map(Object::toString).collect(Collectors.toList());

55.Function实现接口映射

private final Map<Integer, Function<ActivityDataScreeningQueryVO, ActivityDataScreeningResultVO>> grantTypeMap = new HashMap<>();

@PostConstruct
public void dispatcherInit() {
    grantTypeMap.put(ActivityTypeEnum.ACTIVITY_TURNTABLE_LUCK_DRAW.getCode(), activityTurntableJoinLogService::getDataScreening);
    grantTypeMap.put(ActivityTypeEnum.INVITE_FOLLOW_STORE.getCode(), activityInviteFollowStoreLogService::getDataScreening);
}


@Override
public ActivityDataScreeningResultVO getDataScreening(ActivityDataScreeningQueryVO request) {
    log.info("ActivityDataStatisticsService, 活动统计, request={}", JSONObject.toJSONString(request));
    Function<ActivityDataScreeningQueryVO, ActivityDataScreeningResultVO> function = grantTypeMap.get(request.getActivityType());
    if (null == function) {
        throw new ApiException("参数错误! 请传入正确的活动类型");
    }
    return function.apply(request);
}

56.内外两层的参数校验

public class InviteFollowInsertVO implements Serializable {
    @Valid
    @ApiModelProperty(value = "活动基础配置")
    private ActivityConfigSaveReqVO activityConfig;

    @NotEmpty(message = "活动奖品配置不能为空")
    @ApiModelProperty(value = "活动奖品配置")
    private List<@Valid ActivityRewardConfigSaveReqVO> activityRewardConfigList;

}

57.查询修改git提交的用户名

1 # 获取当前的用户名
2 git config user.name
3
4 # 修改用户名
5 git config --global user.name “新改用户名”

58.mysql 无密码登录

1.停止 MySQL 任务

net stop MySQL
1

2.mysqld 命令:无密码登录

mysqld --console --skip-grant-tables --shared-memory

59.git切换分支

首先通过

$ git branch -a 

来查看所在目录的分支

$ git branch -a
  master
* trunk
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/zhanghanlun

然后输入命令切换分支

适用于第一次创建并切换分支

$ git checkout -b zhanghanlun origin/zhanghanlun
1

其中远程分支为origin/zhanghanlun

本地分支为zhanghanlun

如果已经有本地分支

直接输入命令

git checkout zhanghanlun

60.安装nvm

https://blog.csdn.net/weixin_60187838/article/details/122261341?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166684164616782414942154%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166684164616782414942154&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-4-122261341-null-null.142v62pc_search_tree,201v3control_2,213v1t3_esquery_v1&utm_term=nvm%20install%2014.15.1&spm=1018.2226.3001.4187

nvm 安装报错:Could not retrieve

在本地找到安装nvm的路径,在nvm文件夹下找到settings.txt,添加以下代码即可:

node_mirror:npm.taobao.org/mirrors/node/
npm_mirror:npm.taobao.org/mirrors/npm/

61.Invalid bound statement (not found): service的方法

Invalid bound statement (not found): cn.sprite.service.reward.service.RewardCenterAwardService.queryTable

意思就是无效绑定,找不到service的方法

原因

包下面所有的接口在编译后之后都会生成相应的实现类,也就是说除了我的AdminUserServiceImp外Spring Boot还注入了一个mapper实现类,当我在Controller中使用@AutoWired或@Resource获取时,获取到时这个Mapper实现类的实例,但实际上并没有真正继承AdminUserService接口,只有你在运行的时候服务器才会报错,找不到对应的方法。

解决办法:

参考地址:Invalid bound statement (not found): service的方法

1、@Mapper注解:
作用:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类
添加位置:接口类上面

@Mapper
public interface UserDAO {
   //代码
}

2、@MapperScan
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加,

@SpringBootApplication
@ComponentScan(basePackages ={ "cn.sprite"})
@MapperScan("cn.sprite.dao")
public class MainApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MainApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class,args);
    }
}

3、@ComponentScan

@ComponentScan 的作用就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中,注解定义

基本上所有bean都要扫描注入,否则会报错:找不到对应实体对象

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-plus是MyBatis增强工具包,用于简化CRUD操作。该工具包为MyBatis提供了一些高效,有用,即用的功能,使用它可以有效地节省您的开发时间。 Mybatis-plus特征: 与MyBatis完全兼容 启动时自动配置 开箱即用的用于操作数据库的界面 强大而灵活的条件包装器 生成主键的多种策略 Lambda样式的API 全能和高度可定制的代码生成器 自动分页操作 SQL注入防御 支持活动记录 支持可插拔的自定义界面 内置许多有用的扩展 Mybatis-plus功能: 1、单表CURD(简单 + 批量)操作,自动完成(支持 like 比较等查询)。 2、分页插件,Count查询自动或自定义SQL查询。 3、Spring根据不同环境加载不同配置支持(支持typeAliasesPackage通配符扫描)。 【自动生成Entity  Mapper  Service文件】 Mybatis-plus更新日志: v3.4.3 增加瀚高数据库支持 增加注解 Order By 支持默认排序 Wrapper exists notExists orderBy groupBy 支持参数绑定 Wrapper 支持 setParamAlias 其它优化 优化 KeyGenerator 支持多实现多数据源注入 增强 ServiceImpl 泛型推断,解决多继承与代理问题 新增 PageDto 用于微服务对象传输序列化 新增 Page 提供静态 of 构造方式 增加代理 MethodHandleProxies 对 lambda 调试支持 调整 ActiveRecord 日志对象初始化 调整 ActiveRecord 模式 Model 类开发 pkVal 方法外部可用 删除标记过时代码 优化枚举值获取方式 分页 count 安全处理 Sequence 方法支持重写支持 升级 Mybatis 3.5.7 修复自动配置 lazy-initialization 无属性提示 修复 mysql on duplicate key update 字段名判断为表名问题 修复 lambda 条件 npe 异常 重构 lambda 信息提取方法 获取 lambda 信息不在序列化 合并 gitee pulls/ 141 fixed github issues/3208 3016 fixed github issues/3482 数据权限处理器支持 union all 调整事务未启用打印提示信息 单元测试优化相关依赖升级
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值