沈超琦的博客

STAY HUNGRY,STAY FOOLISH

文章

Hello World

记录生活,记录成长,记录美好 想说的有很多,但都说不出来了.贴上一段代码和一句话,希望自己不负韶华吧. public static void main(String[] args){ System.out.println("Hello World!"); } “终其一生,我们只为寻找最初失去的那个人” ——胡塞尼《群山回唱》

使用流处理数据后导致PageInfo的total属性得到的值等于当前页记录数size

问题: 使用PageHelper分页助手,以往总记录数通过 pageInfo.getTotal()获取都没有问题。这次做了个商品列表分页,发现 total等于当前页的数量,相当于 size了。而后台SQL确实查询出了所有的数据。 原因: 爬了几篇文后,总结一下。 total属性确实是总记录数,并不是有些文章里说的当前页数。 其实解答还是在Github作者的Issues中: https://github.com/pagehelper/pagehelper-spring-boot/issues/21 针对我个人问题的原因就是作者最后说的这一句,别的可能存在的原因可以去看完整的issues里的讨论。 因为我在查询后又使用了lambda的stream()对数据进行了处理。 作者说lambda处理过后的流会丢失分页信息,所以导致数据只显示了默认的当前页的数量。

数据结构-嵌套集模型

这段时间被嵌套集模型折磨得快疯了,当初技术选型的时候没有选择最稳的父子树结构,而是想试试另外的数据结构(选了嵌套集),结果没想到后来产品的骚需求一个一个来,原来的官方Demo已经满足不了需求,只能自己写做逻辑,顺便再温习一下这个数据结构 概述 我们知道,关系数据库的表更适合扁平的列表,而不是像 XML 那样可以直管的保存具有父子关系的层次结构数据。 首先定义一下我们讨论的层次结构,是这样的一组数据,每个条目只能有一个父条目,可以有零个或多个子条目(唯一的例外是根条目,它没有父条目)。许多依赖数据库的应用都会遇到层次结构的数据,例如论坛或邮件列表的线索、企业的组织结构图、内容管理系统或商城的分类目录等等。我们如下数据作为示例: 邻接表(Adjacency List)模型 我们可以很直观的使用下面的方式来保存如图所示的结构。 创建名为 distributions 的表: CREATE TABLE distributions ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(32) NOT NULL, parent INT NULL DEF....

FeignClient中每一个@RequestParam 都要设置value,否者报错

消费方代码 @FeignClient(name = “another-project-name”) public interface demoClient { @GetMapping(value = "/test") Boolean test(@RequestParam("userID")String userID); } 提供方代码 @RestController public class DemoController { @GetMapping(value = "/test") Boolean test(@RequestParam("userID")String userID){ ...... } }

springboot解决跨域问题

1、跨域起因 对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么势必会引起跨域问题的出现。针对跨域问题,我们可能第一个想到的解决方案就是jsonp,并且以前处理跨域问题我基本也是这么处理。 但是jsonp方式也同样有不足,不管是对于前端还是后端来说,写法与我们平常的ajax写法不同,同样后端也需要作出相应的更改。并且,jsonp方式只能通过get请求方式来传递参数,当然也还有其它的不足之处, jQuery ajax方式以jsonp类型发起跨域请求,其原理跟script脚本请求一样,因此使用jsonp时也只能使用GET方式发起跨域请求。跨域请求需要服务端配合,设置callback,才能完成跨域请求。 针对于此,我并没有急着使用jsonp的方式来解决跨域问题,去网上找寻其它方式,也就是本文主要所要讲的,在springboot中通过cors协议解决跨域问题。 2、Cors协议 H5中的新特性:Cross-Origin Resource Sharing(跨域资源共享)。通过它,我们的开发者(主要指后端开发者)可以决定资源是否能被跨域访问。 cors是一个w3c标准,它允....

使用注解@实现防止接口重复提交

实现逻辑 1.自定义防重复提交的注解和切面 2.在需要验证的接口上增加注解(一般是创建、修改的接口) 3.以每次调用的 用户唯一标识(userId或者sessionId或者token)+ 请求路径+参数 作为key,value任意值都可以,缓存起来(redis或本地缓存),并设置一个合适的缓存失效时间。 4.每次调用时根据key判断,缓存是否存在,存在则抛出异常或提示,不存在则执行业务逻辑 代码 防重复提交注解 ** package com.***.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * <p>Description: [防重复提交注解]</p > */ @Target(ElementType.METHOD) @Retention(Retention....

Stream和Lambda表达式最佳实践

1. Streams简介 今天要讲的Stream指的是java.util.stream包中的诸多类。Stream可以方便的将之前的结合类以转换为Stream并以流式方式进行处理,大大的简化了我们的编程,Stream包中,最核心的就是interface Stream 从上面的图中我们可以看到Stream继承自BaseStream。Stream中定义了很多非常实用的方法,比如filter,map,flatmap,forEach,reduce,collect等等。接下来我们将会逐一讲解。 1.1 创建Stream Stream的创建有很多方式,java引入Stream之后所有的集合类都添加了一个stream()方法,通过这个方法可以直接得到其对应的Stream。也可以通过Stream.of方法来创建: //Stream Creation String[] arr = new String[]{"a", "b", "c"}; Stream<String> stream = Arrays.stream(arr); stream = Stream.of("a", "b", "c");....

Effective JAVA -第一条:用静态工厂代替构造器

序:什么是静态工厂方法 在 Java 中,获得一个类实例最简单的方法就是使用 new 关键字,通过构造函数来实现对象的创建。 就像这样: Fragment fragment = new MyFragment(); // or Date date = new Date(); 不过在实际的开发中,我们经常还会见到另外一种获取类实例的方法: Fragment fragment = MyFragment.newIntance(); // or Calendar calendar = Calendar.getInstance(); // or Integer number = Integer.valueOf("3"); ↑ 像这样的:不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的 静态工厂方法(Static factory method)。 知识点:new 究竟做了什么? 简单来说:当我们使用 new 来构造一个新的类实例时,其实是告诉了 JVM 我需要一个新的实例。JVM 就会自动在内存中开辟一片空间,然后调用构造函数来初始化成员变量,最终把引用返回给调用....

Netty 那点事(一)概述

Netty 和 Mina 是 Java 世界非常知名的通讯框架。它们都出自同一个作者,Mina 诞生略早,属于 Apache 基金会,而 Netty 开始在 Jboss 名下,后来出来自立门户 netty.io。关于 Mina 已有 @FrankHui 的 Mina 系列文章,我正好最近也要做一些网络方面的开发,就研究一下 Netty 的源码,顺便分享出来了。 Netty 目前有两个分支:4.x 和 3.x。4.0 分支重写了很多东西,并对项目进行了分包,规模比较庞大,入手会困难一些,而 3.x 版本则已经被广泛使用。本系列文章针对 netty 3.7.0 final。3.x 和 4.0 的区别可以参考这篇文章:http://www.oschina.net/translate/netty-4-0-new-and-noteworthy?print。 起:Netty 是什么 大概用 Netty 的,无论新手还是老手,都知道它是一个 “网络通讯框架”。所谓框架,基本上都是一个作用:基于底层 API,提供更便捷的编程模型。那么 "通讯框架" 到底做了什么事情呢?回答这个问题并不太容易,我们不妨....

使用feignClient调用接口 报错Method has too many Body parameters]

1、报错 Method has to many Body parmeters ,feign多参数问题 1.1GET方式 错误写法 @RequestMapping(value="/test", method=RequestMethod.GET) Model test(final String name, final int age); 启动服务的时候,会报如下异常: Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract com.chhliu.springboot.restful.vo.User com.chhliu.springboot.restful.feignclient.UserFeignClient.findByUsername(java.lang.String,java.lang.String) 异常原因:当使用Feign时,如果发送的是get请求,那么需要在请求参数前加上@RequestParam注解修饰,Controller里面....

分布式锁之Redis实现

在Java中,关于锁我想大家都很熟悉。在并发编程中,我们通过锁,来避免由于竞争而造成的数据不一致问题。通常,我们以 synchronized 、Lock来使用它。 但是Java中的锁,只能保证在同一个JVM进程内中执行。如果在分布式集群环境下呢? 一、分布式锁 分布式锁,是一种思想,它的实现方式有很多。比如,我们将沙滩当做分布式锁的组件,那么它看起来应该是这样的: 加锁 在沙滩上踩一脚,留下自己的脚印,就对应了加锁操作。其他进程或者线程,看到沙滩上已经有脚印,证明锁已被别人持有,则等待。 解锁 把脚印从沙滩上抹去,就是解锁的过程。 锁超时 为了避免死锁,我们可以设置一阵风,在单位时间后刮起,将脚印自动抹去。 分布式锁的实现有很多,比如基于数据库、memcached、Redis、系统文件、zookeeper等。它们的核心的理念跟上面的过程大致相同。 二、redis 我们先来看如何通过单节点Redis实现一个简单的分布式锁。 1、加锁 加锁实际上就是在redis中,给Key键设置一个值,为避免死锁,并给定一个过期时间。 SET lock_key random_value NX ....

我在 GitHub 上的开源项目

LinkCloudDisk Java 🤩1  ⭐️12  🖖3 基于springcloud开发的分布式美剧订阅系统(含爬虫) 2. linkjb Vue 🤩2  ⭐️5  🖖1  🏠http://www.linkjb.com 基于spring,vue开发的在线实时交友网站 3. LinkDisk Java 🤩1  ⭐️1  🖖0 基于分布式的在线云盘 balabala 4. linkblog CSS 🤩1  ⭐️0  🖖0 linkblog init commit 5. python3-study Python 🤩0  ⭐️0  🖖1 request,selenium,scrapy等库和框架的学习

记录第一次交通事故(真的看不惯加塞🐶)

前因后果 今天和往常一样开开心心开车上班敲代码,昨天有个SQL问题一直困扰着我,准备今天到了公司一口气写完然后能划划水轻松轻松, 但是没想到在高架上的时候,一共三个车道,我一直在中间车道开着(我是红色小车),然后我的右方出现了一辆白色的小车,转向灯也不打,直挺挺向我的车道变向过来,我减速不及,直挺挺撞了上去,砰!~~~!😳 我车倒没什么事,只是后视镜被剐蹭了一下,本来也没怎么气,这场事故的责任很明显,我正常行驶,他变到剐蹭到我.想着这是我妈的老车(杭州限行我自己的车和我妈的车轮换来开的),也开了有12年了,本想着下车去看看如果不严重我也就走掉了.结果我一下车,他劈头盖脸一句 "你怎么开的车?!!",瞬间我火一下子就上来了. 这可还行,我惯着你? 直接打交警电话,交警来了一看就说他全责,他还不认,说他没有变道,是我加塞到他前面去的(我真是服了一些中年人颠倒黑白的能力了).最后叫来了一个交通民警,民警一看事故现场照片也说了他全责, 他这才灰溜溜得认了全责. 总结 开车还是要稳一点,虽然真的很看不惯加塞🐶,但是能让还是让吧,像我这种老车倒没什么事,要是自己的新车,那真是既心疼又碍事,....

[报错本]File createNewFile 空指针问题

现在公司是混合开发平台的,开发环境中代码需要上传到运维平台(docker+jenkins)进行服务的部署,今天遇到了个问题,在本地开发环境没有问题,一到云平台部署就报错,后来定位到了 File的createNewFile方法,才发现路径没有定位好,父路径没有创建 例子: if(!file.exists()){ try { file.getParentFile().mkdirs(); file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }

RabbitMQ消息队列监控API

最近有一个项目,需要编写一个监听rabbitMQ集群状态的项目,需要通过rabbit提供的API来获取相应数据并组装,所以需要学习一下rabbit的API HTTP API URLHTTP请求类型接口含义 /api/connectionsGET获取当前RabbitMQ集群下所有打开的连接 /api/nodesGET获取当前RabbitMQ集群下所有节点实例的状态信息 /api/vhosts/{vhost}/connectionsGET获取某一个虚拟机主机下的所有打开的connection连接 /api/connections/{name}/channelsGET获取某一个连接下所有的管道信息 /api/consumers/{vhost}GET获取某一个虚拟机主机下的所有消费者信息 /api/exchanges/{vhost}GET获取某一个虚拟机主机下面的所有交换器信息 /api/queues/{vhost}GET获取某一个虚拟机主机下的所有队列信息 /api/usersGET获取集群中所有的用户信息 /api/users/{name}get/put/delete获取/更新/....

WebSocket学习(一)

简介 下一个项目需要做一个对于rabbitmq里队列交换机等资源的监控项目,需要用到的技术有rabbitmq的API和websocket协议(其实最主要的是前端的大屏,领导喜欢看大屏哈哈哈哈),其实以前也用过websocket,但是都只是使用,并没有对websocket协议本身有过深入的分析了解,趁这次知识储备的机会对这个协议做一个简单的了解 与HTTP协议的关系 同样作为应用层的协议,WebSocket在现代的软件开发中被越来越多的实践,和HTTP有很多相似的地方,这里将它们简单的做一个纯个人、非权威的比较: 比较 相同点 都是基于TCP的应用层协议。 都使用Request/Response模型进行连接的建立。 在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码。 都可以在网络中传输数据。 不同点 WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用。 WS的连接不能通过中间人来转发,它必须是一个直接连接。 WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据。 WS连接建立之后,数据的传输使用帧来....

Java 8 新特性

Java 8 新特性 1.lambda 表达式 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。 Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。 使用 Lambda 表达式可以使代码变的更加简洁紧凑。 基本的语法格式为: (parameters) -> expression 或 (parameters) ->{ statements; } 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。 简单实例: // 1. 不需要参数,返回值为 5 () -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值 (x, y) -> x – y // 4. 接收2个int型整数,返回....

Spring核心依赖注入

前言 提起Spring,大家肯定不陌生,它是每一个Java开发者绕不过去的坎。Spring 框架为基于 java 的企业应用程序提供了一整套解决方案,方便开发人员在框架基础快速进行业务开发。 在官网中,我们发现它的核心技术之一:Dependency Injection,简称:DI ,翻译过来就是依赖注入。今天我们就来盘一盘它。 在本文中,我们将深入研究 Spring 框架 DI背后的故事,包括 Spring Inversion of Control(控制反转)、 DI 和 ApplicationContext 接口。 基于这些基本概念,我们将研究如何使用基于 java 和基于 XML 的配置来 创建Spring 应用程序。 最后,我们将探讨在创建 Spring 应用程序时遇到的一些常见问题,包括 bean冲突和循环依赖性。 一 控制反转(Inversion of Control) 在学习DI之前,我们先学习一下 IoC(控制反转),接下来的一段可能读起来会让你感觉比较啰嗦,但是要细细体会每一次改变的意图,和我们的解决方案,对于理解控制反转非常重要。 首先来了解下我们通常实例化一个对象的....

[原创]dom4j的指定element获取树结构

最近在做CDA文档(一种医疗机构内部通用的XML格式文档,基于V3模板)的项目,遇到了一个需求,通过指定CDA文档的xpath获取指定xml的树结构. public List<Object> searchByNode(String documentId,String xpath){ List resultList = new ArrayList<>(); String cdacontent = xxxService.getByDocumentId(documentId) .....通过documentId 获取具体的CDA文档 Map map = new HashMap(); map.put("cda","urn:hl7-org:v3"); //指定XML命名空间 SAXReader reader = new SAXReader(); reader.getDocumentFactory().setXPathNamespaceURIs(map); Ducument result = null; InputSource source = new InputSourc....

mybatis一级缓存二级缓存

一级缓存   Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言。所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。 为什么要使用一级缓存,不用多说也知道个大概。但是还有几个问题我们要注意一下。   1、一级缓存的生命周期有多长? **  **a、MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象。Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。   b、如果SqlSession调用了close()方法,会释放....

STAY HUNGRY,STAY FOOLISH

© 2020 沈超琦的博客

Powered by Bolo
Theme self-bolo-sakura by Mashiro
浏览 2451 文章 21 评论 3
浙ICP备18010929号

主题 | Theme