其他知识点

双亲委派机制

https://blog.csdn.net/u013568373/article/details/93995246

一言概之,双亲委派模型,其实就是一种类加载器的层次关系。”

JDK

JDK是个Java开发的工具包

JDK8或者JDK1.8是由于自从JDK1.5/JDK5命名方式改变后遗留的新旧命令方式问题。所以JDK8或者JDK1.8也是同一个东西。

JAVA就是指JDK开发工具,所以我们可以理解为JAVA等价于JDK。JAVA有3个版本:J2SE J2EE J2ME,而J2SE是标准版本,J2ME是手机方向的,J2EE是网站开发方向的。

判断数据类型

xx instanceof xx

导出文件

@PostMapping("/imp111ort")
@ApiOperation(value = "导入111", httpMethod = "POST", response = Result.class)
public  void exportExl() {
    HttpServletResponse response = RequestContextUtil.getResponse();
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    try {
        response.setHeader("Content-disposition", "attachment;filename=" + 		URLEncoder.encode("fileName", "UTF-8") + ".xlsx");

换页、换行、回车、TAB 制表符

6b8801d23502a16bf86a9285048dea90.png


VO和DTO

VO传给前端的
DTO是从前端拿过来的


MySQL截取字符串函数

  1. left(str,length) 从左边截取length

  2. right(str,length)从右边截取length

  3. substring(str,index)当index>0从左边开始截取直到结束 当index<0从右边开始截取直到结束 当index=0返回空

  4. substring(str,index,len) 截取str,从index开始,截取len长度

  5. substring_index(str,delim,count),str是要截取的字符串,delim是截取的字段 count是从哪里开始截取(为0则是左边第0个开始,1为左边开始第一个选取左边的,-1从右边第一个开始选取右边的

  6. subdate(date,day)截取时间,时间减去后面的day

  7. subtime(expr1,expr2) 时分秒expr1-expr2


SQL注入 (${ }和#{ } )

${ } 中因为用了变量,可能出现SQL注入

#{ } 会把有可能的注入变成字符串加一层引号

但是如果整体SQL语句都是变量那就不能用#{}防止SQL注入了,因为加了引号,要用一个正则方法判断一下是否有注入的危险。


回滚

@Transactional(rollbackFor = Exception.class)

如果数据库的操作(保存,更新,删除)要对多个表进行操作。(假如,一个医生表添加了一个人,医院表相应的人数也加一)加上这个事务让操作变成原子性(要么都成功,要么都失败)这个时候就要加回滚,保证失败的时候;另一个也要回到失败的状态。

建表规避字段

DESCRIBE、RANGE

注解释义

@Deprecated

使用@Deprecated表示这个类或者方法没在使用了

@TableLogic

自动补值默认逻辑删除isDeleted(0-未删除,1-已删除)

@TableField(exist = false)

标识这个字段不是数据库表中的字段

@Accessors(chain = true)

生成setter方法返回this(也就是返回的是对象),代替了默认的返回void。

@RequestParam、@RequestBody和@ModelAttribute区别

当前台界面使用GET或POST方式提交数据时,数据编码格式由请求头的ContentType指定。分为以下几种情况:
\1. application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute可以处理,@RequestBody也可以处理。
\2. multipart/form-data,@RequestBody不能处理这种格式的数据。(form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。)
\3. application/json、application/xml等格式的数据,必须使用@RequestBody来处理。

将List根据公共字段转成Map

Map<String, List<HbbPublicVo>> collect = hbbPublicVos.stream().collect(Collectors.groupingBy(HbbPublicVo::getHbbType));

new 和 =

首先基本类型不会被回收

new的时候是先开辟一块空间,该空间地址和变量对应。如果后续对变量进行赋值,例如 = 就会有一个新的有值的空间地址和变量对应,之前的空间就没人指向他了。
例如:

Integer numb = 0;
numb = list.size();
//此时numb = 0 就没有意义了,因为后面赋值了。

异步执行

CompletableFuture.runAsync(() ->{});

MYSQL count(*) 和 count(列名) 的区别

count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

联合索引

联合索引 A,B,C三个字段 如果是唯一索引

那么A可以走索引但不是唯一,AB也可以走索引但是不唯一。

equals()方法的四大原则

对称性:
如果 x.equals(y)返回true,则y.equals(x)也必须返回true。

自反性:
x.equals(x)必须返回true。

传递性
如果 x.equals(y)返回true,而且y.equals(z)返回true,那么z.equals(x)也是返回true。

一致性
如果 x.equals(y)返回true,只要x和y内容一直不变,不管里重复多少次比较,都会返回true。

任何情况下x.equals(null),都会返回false。

java1.8新特性removeIf & lambda表达式处理简化

//简化前
for (int i = 0; i < geoms.size(); i++) {
    if (geoms.get(i).startsWith("POLYGON")) {
        //wkt转成polygon
        Polygon polygon = (Polygon) reader.read(geoms.get(i));
        geoms.remove(geoms.get(i));
        Polygon[] polys = new Polygon[1];
        polys[0] = polygon;
        //polygon转成MultiPolygon
        multiPolygons.add(gf.createMultiPolygon(polys));
        i--;
    }else{
        multiPolygons.add((MultiPolygon) reader.read(geoms.get(i)));
    }
    
}
//简化后
geoms.removeIf(next -> {
            boolean b = next.startsWith("POLYGON");
            try {
                multiPolygons.add(b ? gf.createMultiPolygon(new Polygon[]{(Polygon) reader.read(next)}) : (MultiPolygon) reader.read(next)); 
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return b;
        });

注册拦截器InterceptorConfig

/**
 * 注册拦截器,暂放于此
 *
 * @author yyh
 * @since 2021-03-26
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    /**
     * springboot 拦截器无法注入bean,故添加此配置
     * 拦截器加载的时间点在springcontext之前,所以在拦截器中注入自然为null
     * @return
     */
    @Bean
    public AuthInterceptor getMyInterceptor(){
        return new AuthInterceptor();
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册权限校验拦截器
        registry.addInterceptor(getMyInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login/**","/user/logout", "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/doc.html/**");
    }

}

/**
 * <p>
 * 权限校验拦截
 * <p/>
 *
 * @author yyh
 * @since 2021-05-17
 */
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {

    @Resource
    private RedisCacheUtil redisCacheUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        //测试使用
        if ("123456".equals(token)) {
            return true;
        }
        //判断token是否为空
        if (token != null && !"".equals(token)) {
            //判断token是否存在
            if (redisCacheUtil.hasKey(token)) {
                //存在,重新设置失效时间
                redisCacheUtil.expire(token,120, TimeUnit.MINUTES);
                return true;
            } else {
                throw new TokenInvalidException("token失效");
            }
        } else {
            throw new TokenDefectException("未携带token");
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }
}

端口占用

# 列出所有端口占用情况
netstat -ano
# 精确找到被占用的端口对应的PID
netstat -ano|findstr "port"
# 示例
netstat -ano|findstr "6644"
#查看是哪个进程或程序占用了端口
tasklist|findstr "PID"
# 示例
tasklist|findstr "4"
#在Dos窗口中通过命令结束进程
taskkill /f /t /im xx进程
# 示例
taskkill /f /t /im System

PG库创建序列实现主键自增

-- 先创建序列
CREATE SEQUENCE msg_connection_id_seq START 1; 
-- 再把字段加上默认值
nextval('dbms_connection_msg_connection_id_seq'::regclass)
 -- 序列重置到1000
alter sequence sequence_name restart with 1000
-- 验证 
SELECT nextval('sequence_name');

PG库空间函数计算失效

-- 查询空间字段编码格式
SELECT
	st_srid ( field_name ) 
FROM
	table_name;
-- 更新空间数据编码格式
SELECT
	UpdateGeometrySRID ( 'table_name', 'field_name', 4490 );

又是一个小细节

  • SQL 如果查某些字段,查出来的都是null。此时若有记录但是该字段是空,则total显示对应条数,若没有记录,则total为 0。