2021年3月6日星期六

辽宁近5战已输掉4场 争冠路上遭遇重大危机?_比赛

原标题:辽宁近5战已输掉4场 争冠路上遭遇重大危机?

北京时间3月6日,2020-21赛季CBA常规赛第三阶段比赛继续进行,辽宁队与上海队的比赛在下午15:30开赛。上海队在加时赛表现出更高的进攻效率,以122-115战胜辽宁队。

输给上海队后,辽宁队经历了本赛季的第二次2连败。第一次2连败是第二阶段的最后2场比赛,接连输给广东、四川。此次2连败是输给广厦、上海。本场失利也是辽宁队近5场比赛的第4次失利。

如果说上赛季辽宁队打进总决赛,是超额完成任务,那么本赛季辽宁队从上到下都明确提出了争冠的目标。过惯了人员吃紧苦日子的辽宁队在本赛季引入朱荣振、付豪,加上自主培养的张镇麟、吴昌泽,国内球员的纸面实力已成国内顶级。在外援方面,辽宁队也大手笔频出,先是以400万美金的高薪邀请来西蒙斯,在西蒙斯不适应球队后,又一次签下弗格和泰勒两名外援。很多辽宁球迷都说辽宁队终于过上了富裕日子。

在上场大比分输给广厦队后,辽宁队上上下下都感到了巨大的压力。主教练杨鸣的休息时间都大为减少。本场比赛朱荣振、梅奥双双复出,本该是增添了获胜的砝码。在前一节半都打得很好的情况下,辽宁队在第二节末段进攻开始断电。

第三节是上海队双外援的优势节,辽宁队在顶住压力之后。第四节又被上海队在最后2分钟领先5分,幸好郭艾伦连投带传贡献5分,帮助辽宁队拖进加时赛。在加时赛,邓蒙连续命中不讲理3分,一度建立起8分的巨大优势,彻底奠定比赛优势。

从比赛场面来看,辽宁队在防守端出现太多问题,上海队多次由弗神外线持球,刘铮、张春军等球员溜底线空切,这一战术打了辽宁队5、6次,屡试不爽。在张兆旭身陷犯规危机,在场下休息时,辽宁队两大内线韩德君、付豪却状态不佳,无法单打砍分。梅奥复出后手感冰凉,运动战进球寥寥。如果不是郭艾伦、赵继伟、朱荣振发挥出色,辽宁队可能在第三、四节就直接崩盘了。

在输给广东队之后,此前一直领先的辽宁队心态上发生了很大变化。此后接连输给四川、广厦、上海,只赢了本赛季严重下滑的福建队。辽宁队以往第四节惹不起的特质,在这几场比赛中荡然无存,球员被逆转后就开始患得患失,不敢出手。单外援的劣势,让辽宁队面对优秀的双外援组合时,总是防住这个又漏了那个。

对目前的辽宁队来说,摆正心态保住第2的位置,比和广东拼意义不大的常规赛冠军更为重要。毕竟季后赛还是赛会制,主客场优势相当于没有。辽宁队需要彻底审视自身存在的问题,摆正心态,拿出真正有效的解决办法,多赢关键比赛,全力保住第2的位置。(剑风袭面)返回搜狐,查看更多

责任编辑:

原文转载:http://sport.shaoqun.com/a/470750.html

跨境电商:https://www.ikjzd.com/

cima是什么:https://www.ikjzd.com/w/1372

东西网:https://www.ikjzd.com/w/1238


原标题:辽宁近5战已输掉4场争冠路上遭遇重大危机?北京时间3月6日,2020-21赛季CBA常规赛第三阶段比赛继续进行,辽宁队与上海队的比赛在下午15:30开赛。上海队在加时赛表现出更高的进攻效率,以122-115战胜辽宁队。输给上海队后,辽宁队经历了本赛季的第二次2连败。第一次2连败是第二阶段的最后2场比赛,接连输给广东、四川。此次2连败是输给广厦、上海。本场失利也是辽宁队近5场比赛的第4次失利
旺店通:https://www.ikjzd.com/w/2390
adore:https://www.ikjzd.com/w/2202
vat:https://www.ikjzd.com/w/109
RCEP框架下的中国跨境电商新变化:https://www.ikjzd.com/home/141384
今年亚马逊PrimeDay请Taylor Swift开演唱会背后的商业逻辑:https://www.ikjzd.com/home/101233
亚马逊运营必须要知道的选品思路:https://www.ikjzd.com/home/96674

曦湾天馥200㎡·一站式整装

曦湾天馥位于深圳南山是深圳湾片区的高端住宅小区,毛坯交付,面积200㎡,新中式风格

项目地点:深圳南山

交付情况:毛坯

项目面积:200㎡

风格定位:新中式风格

整装团队:德派装饰&君尚软装&摩洛卡家居

户型图

本案例户型方正的大平层,南北通透,客餐厅双阳台,全明无暗房。

客餐厅

整体空间是传统与现代的有机结合,客厅区与餐厅区切割有度,将空间完美运用,中间吧台的加入,增加了使用功能,敞开式的手法产生和谐的互动。

客厅

客厅独特的灰色大理石电视背景墙,散发中式的古韵;结合中式的软装布置,整个客厅不仅有中式的典雅,也具时尚与现代感。

卧室

卧室满是中式风情,床头水墨画的装饰,两边对称的吊灯,结合床上中式床褥,东方意境尤为突出,天花板的留白,在这更显空间的大气感。

原文转载:http://home.shaoqun.com/a/115194.html

跨境电商:https://www.ikjzd.com/

沃尔码:https://www.ikjzd.com/w/220

心怡科技:https://www.ikjzd.com/w/1327


曦湾天馥位于深圳南山是深圳湾片区的高端住宅小区,毛坯交付,面积200㎡,新中式风格项目地点:深圳南山交付情况:毛坯项目面积:200㎡风格定位:新中式风格整装团队:德派装饰&君尚软装&摩洛卡家居户型图本案例户型方正的大平层,南北通透,客餐厅双阳台,全明无暗房。客餐厅整体空间是传统与现代的有机结合,客厅区与餐厅区切割有度,将空间完美运用,中间吧台的加入,增加了使用功能,敞开式的手法产生
prime day:https://www.ikjzd.com/w/131.html
reddit:https://www.ikjzd.com/w/180
斑马物联网:https://www.ikjzd.com/w/1316
做亚马逊你可能不知道的这些关于UPC的知识:https://www.ikjzd.com/tl/97704
英国本土10大电商平台盘点!:https://www.ikjzd.com/home/585
38个亚马逊店铺运营知识问答:https://www.ikjzd.com/tl/109336

平常喝水都会发胖的人,要怎样减肥?

核心提示:易胖体质到底是一种怎样的体质?影响人胖瘦的荷尔蒙主要有两种,能让人变瘦的荷尔蒙是主管新陈代谢的肾上腺素和甲状腺素;会令人发胖的荷尔蒙是胰岛素。当人体内瘦的荷尔蒙低于胖的荷尔蒙时,人体就会偏向易胖体质。

传说中的"喝水都会胖"的体质指的其实就是易胖体质。易胖体质到底是一种怎样的体质?影响人胖瘦的荷尔蒙主要有两种,能让人变瘦的荷尔蒙是主管新陈代谢的肾上腺素和甲状腺素;会令人发胖的荷尔蒙是胰岛素。当人体内瘦的荷尔蒙低于胖的荷尔蒙时,人体就会偏向易胖体质。


易胖体质的形成虽有遗传性原因,但是主要还是受日常生活方式影响形成。一般来说,易胖体质的人一般会有以下几种表现:

1.一日三餐不正常并且经常在外就餐。

平常连喝水都会胖 要怎样减肥?

2.爱吃零食,爱吃宵夜。

3.有吸烟喝酒习惯。

4.经常熬夜。

5缺乏运动。

6.吃饭速度过快。

如果刚好那么不幸,以上表现你中了3项以上,那你可要当心咯,一不小心就可能胖成球啦。那易胖体质的人应该要如何减肥?下面几种小方法赶紧学起来!

1.每周选择1天断食 剩下6天正常饮食

有研究表明,适当断食不仅可以帮助减重,还可以排毒,让人更加健康。但是断食过度会造成营养不良,因此,我们推荐轻断食减肥方法。这种节奏的断食疗法最适合三"高"患者和习惯性减肥的女性朋友。7天的周期内随意选择自己最适合的一天禁食,剩下6天保持正常的饮食节奏,既能养成定期排毒的好习惯,又不会给身体和心理带来太大压力。但要注意,处于青春期、哺乳期、孕期和低血糖严重的女性都不适合执行断食法。

2.严格控制一天摄入热量

摄入热量过多是导致肥胖的直接原因。要减肥,就要严格把关,控制饮食,减少热量摄入。一般来说,人体每天至少需要1200大卡的热量来维持身体的基础代谢。对于女性来说,摄入热量不超过1500大卡就能够减肥。因此,在这个月里,你需要合理分配一天饮食的热量,早餐吃好,午餐吃饱,晚餐吃少。

3.适量补充蛋白质


很多女生在减肥时,都可怜兮兮地只让自己吃青菜、水果,顶多再加一点低脂的牛奶、优格,但这样吃久了,身体肌肉都变得软趴趴,即使体重变轻也没有身体曲线,变成软肉人了!蛋白质是构成细胞最重要的原料,唯有吸收蛋白质才能增加肌肉的组成,而肌肉也是增加基础代谢率的关键喔!只要吃对就绝对不会胖,反而会让身体线条更优美。首先你要选择低脂、高蛋白的蛋白质来源,你可以选择鸡胸、鸡腿或是鱼类,牛、羊、猪则要注意选择油脂不要太多的部位,或是你可以在吃的时候把皮跟肥肉剔掉。

4.每天坚持运动30~60分钟

有氧运动是燃脂效果最理想的运动类型。在坚持30分钟以上的中低强度的有氧运动,能够消耗大量的脂肪为身体供能。因此,要达到良好的瘦身效果,需要确保每次有氧运动持续30分钟以上,最好不要超过一小时。提高基础代谢率离不开运动。力量训练能够很好地锻炼到肌肉,让肌肉更有弹性。一些人会认为做力量训练的燃脂效果不理想,就只选择做有氧运动。在做力量训量过程中,燃烧脂肪确实并不多。但有研究表明,在做完力量训练后的一两个小时,身体会持续消耗热量。另外,力量训练会大大提高人的代谢能力,让人养成易瘦体质。因此,除了做有氧运动,要想改变易胖体质,还需要结合力量训练。


原文转载:http://health.shaoqun.com/a/198074.html

跨境电商:https://www.ikjzd.com/

kkr:https://www.ikjzd.com/w/1340

extra:https://www.ikjzd.com/w/1736


核心提示:易胖体质到底是一种怎样的体质?影响人胖瘦的荷尔蒙主要有两种,能让人变瘦的荷尔蒙是主管新陈代谢的肾上腺素和甲状腺素;会令人发胖的荷尔蒙是胰岛素。当人体内瘦的荷尔蒙低于胖的荷尔蒙时,人体就会偏向易胖体质。 传说中的"喝水都会胖"的体质指的其实就是易胖体质。易胖体质到底是一种怎样的体质?影响人胖瘦的荷尔蒙主要有两种,能让人变瘦的荷尔蒙是主管新陈代谢的肾上腺素和甲状腺素;会令人发胖的荷尔蒙是胰岛
krazy:https://www.ikjzd.com/w/1801
airwallex:https://www.ikjzd.com/w/1011
黑石集团:https://www.ikjzd.com/w/1339.html
为什么卖房也要做亚马逊?这其中的暴利你了解吗?:https://www.ikjzd.com/home/94064
亚马逊9.9美元包邮能在半年赚300万?:https://www.ikjzd.com/home/132177
口述:老婆自称性冷淡却跟网友见面开房女人网友老婆:http://lady.shaoqun.com/m/a/43375.html

不抽烟喝酒不同房,怀孕前3个月一定要注意6件事

核心提示:怀孕前3个月属于孕早期,这个时期胎儿还不稳定,孕妈妈一定要小心谨慎,尤其要注意下面这几件事。

我们都知道,怀孕前3个月尤为重要。因为在怀孕早期,胚胎发育十分关键,一不小心都会有流产的风险,因此怀孕的人在前3个月会变得很小心谨慎。

孕妇们要注意啦,怀孕早期注意这6件事,让你平稳度过前3个月!

1.不能抽烟喝酒

有些人在怀孕之前就有抽烟喝酒的习惯,在怀孕时一定要戒掉,吸烟喝酒不仅对自身健康有害,对宝宝的发育也有不良后果,尤其是酒,不仅是酒,含有酒精的饮料也是孕期的重点"忌口"对象。另外怀孕的人要尽量避免吸入二手烟,烟会对胎儿的神经发育造成不可预估的伤害,为了让宝宝健健康康、安安稳稳地降生,孕妈们平时再有烟酒的习惯,也要"忍痛割爱"。

2.避免夫妻生活

怀孕早期一定要控制住自己,尽可能的不要进行夫妻生活,因为在怀孕早期胚胎尚未稳定还继续夫妻生活,对孕妇和胎儿都会带来不利的影响。在这一阶段,怀孕者要尽可能避免压迫腹部,时间越短越好。

3.不要刻意减少饮水

有经验的人都会知道,随着怀孕时间的增加,子宫慢慢变大,会逐渐压迫到膀胱出现尿频的症状,这是属于正常现象。但有很多怀孕者因为尿频而感到烦躁或者害羞,常常会刻意减少饮水和憋尿,这样虽然减少了排尿的次数,却增加了尿路感染的风险,得不偿失。孕妈们不要轻易尝试。

4.不能提重物

有许多女性在怀孕时总觉得提一点重物是小事,其实这对于怀孕前3个月的孕妇来说会有很不好的影响,身体疲惫或者过度劳累都会增加流产风险。另外,怀孕者不要长时间站立或者蹲下,这样对胎儿影响也很大。怀孕早期,胚胎不稳定时,孕妇提重物、长时间站立或者蹲下等行为是不可取的。

5.养成良好的睡眠习惯


许多年轻人都喜欢熬夜,觉得不熬夜生活就不完整。但是,怀孕的女性要注意,在备孕和怀孕期间,熬夜都是不可取的。养成良好的睡眠习惯对于怀孕者来说很重要。良好的睡眠才能给胎儿营造健康的生长环境。

6.保持良好的心情

初次怀孕的心情都是起伏不定的,有些怀孕者在怀孕早期时情绪波动很大,这是由于怀孕者身体激素的变化而影响。有许多怀孕者会莫名其妙的感觉到心烦,此时身边人应该多加包容。因为孕妇情绪的好坏也会影响到胎儿发育的。


原文转载:http://health.shaoqun.com/a/198072.html

跨境电商:https://www.ikjzd.com/

李群:https://www.ikjzd.com/w/1767

虚拟信用卡:https://www.ikjzd.com/w/1055


核心提示:怀孕前3个月属于孕早期,这个时期胎儿还不稳定,孕妈妈一定要小心谨慎,尤其要注意下面这几件事。 我们都知道,怀孕前3个月尤为重要。因为在怀孕早期,胚胎发育十分关键,一不小心都会有流产的风险,因此怀孕的人在前3个月会变得很小心谨慎。孕妇们要注意啦,怀孕早期注意这6件事,让你平稳度过前3个月!1.不能抽烟喝酒有些人在怀孕之前就有抽烟喝酒的习惯,在怀孕时一定要戒掉,吸烟喝酒不仅对自身健康有害,对
王惟:https://www.ikjzd.com/w/1744
海豚村:https://www.ikjzd.com/w/1779
徐家骏:https://www.ikjzd.com/w/1803
英国成功"脱欧",英镑狂飙!:https://www.ikjzd.com/home/10806
口述:女友一共有三个丈夫让我情何以堪女友结婚丈夫:http://lady.shaoqun.com/m/a/34371.html
非洲电商市场成熟度排名:毛里求斯排名第一:https://www.ikjzd.com/home/19284

如果这5个症状你都有,说明妇科炎症已经找上门了

核心提示:当女性感染上妇科炎症,身体会出现比较明显的症状,比如月经异常,比如持续痛经,如果疑似感染妇科炎症,一定要及时就医。

当女性感染上妇科炎症,身体会出现比较明显的症状,比如月经异常,比如持续痛经……当你的身体出现下面这几种症状时,则可能是感染了妇科炎症,一定要及时治疗。


妇科炎症的症状

1.私处瘙痒

阴部瘙痒也是妇科炎症常见的一个症状,也是很多女性最为尴尬的症状,对日常生活也会造成影响。而一般患有霉菌性的yin道炎,就会出现很明显的阴部瘙痒,而且瘙痒的症状在夜晚睡觉的时候最为明显和严重,严重影响了女性的正常休息。

2.私处有异味

一般身体健康的女性,阴部的分泌物是无色无味透明的,但是如果患上妇科炎症的女性,白带分泌物就会出现异味,但是不同的妇科炎症分泌物的异味也会有所不同、有一些异味会类似于鱼腥味,有些则会是恶臭的味道,而白带出现这些异味都是不正常的,如果出现这种情况就要谨慎起来,及时到医院检查。

3.月经异常

一般健康的女性,来月经的时间是有规律的,经期的血量也是处在稳定性的,但是如果女性患上妇科炎症,就会影响到月经出现异常,会出现经期周期不规律、推迟或者延后,血量也会影响到,突然增多或者减少。

4.月经间期出血

健康的女性来月经的周期一般是3-7天,而且在月经之后就不会在出血了。但是患上妇科炎症的女性在经期过后还会出现断断续续的出血,也是一个很不正常的现象,很有可能是因为妇科炎症引起的yin道出血。

5.持续痛经

很多女性在月经期的时候都会出现一些轻微性的下腹疼痛,但是那都是可以忍受的,但是如果经常出现持续性的难以忍受的痛经,那么这种情况是不正常的,有可能是妇科炎症引起的,常见会出现严重疼痛的妇科炎症如:慢性盆腔炎等。

妇科炎症该如何预防?

妇科炎症对女性的影响这么大,日常该如何预防?

1.贴身内衣单独清洗

内衣裤一定要每天更换,而且清洗的时候不能和衣服袜子放到一起洗,最好是分开清洗,而且要用专用清洗内衣裤的杀菌洗剂浸泡一下在清洗,这样不仅可以清除内衣裤里面的细菌,还能避免出现交叉感染、

2.注意公共卫生清洁


我们去旅行有时候会居住在公共的宾馆里面,这些公共地方都是存在这大量的细菌的,特别是厕所,和浴盆,所以如果在使用公共的厕所是马桶的时候,最好不要坐在上面,或者在上面垫上卫生纸,而宾馆的公共浴盆最好是不要使用。

3.不要滥用抗生素

在生活中我们经常会有发烧、头痛的小病,遇到这种病症最好可以通过食物调养,实在难受才能适当使用抗生素类药物,切莫滥用抗生素,抗生素滥用可能会导致细菌出现耐药的情况,反而导致病情加重,且不利于后续治疗。所以千万不能图省事滥用抗生素。


原文转载:http://health.shaoqun.com/a/198068.html

跨境电商:https://www.ikjzd.com/

刘小东:https://www.ikjzd.com/w/1853

feedback:https://www.ikjzd.com/w/159


核心提示:当女性感染上妇科炎症,身体会出现比较明显的症状,比如月经异常,比如持续痛经,如果疑似感染妇科炎症,一定要及时就医。 当女性感染上妇科炎症,身体会出现比较明显的症状,比如月经异常,比如持续痛经……当你的身体出现下面这几种症状时,则可能是感染了妇科炎症,一定要及时治疗。妇科炎症的症状1.私处瘙痒阴部瘙痒也是妇科炎症常见的一个症状,也是很多女性最为尴尬的症状,对日常生活也会造成影响。而一般患有
landing:https://www.ikjzd.com/w/2368
csa:https://www.ikjzd.com/w/904
飞书互动:https://www.ikjzd.com/w/1319.html
亚马逊跟卖投诉:卖家投诉跟卖警告信模板和投诉跟卖方法:https://www.ikjzd.com/home/6803
口述:寂寞前任车里撕破我黑丝纵欲黑丝林洋护城河:http://lady.shaoqun.com/m/a/42894.html
2019黑五和网一热浪已退去,没爆单的卖家接下来如何做?:https://www.ikjzd.com/home/112075

SpringMVC执行流程及源码分析

SpringMVC流程及源码分析

前言

​ 学了一遍SpringMVC以后,想着做一个总结,复习一下。复习写下面的总结的时候才发现,其实自己学的并不彻底、牢固、也没有学全,视频跟书本是要结合起来一起,每一位老师的视频可能提到的东西都不一致,也导致也不是很全面,书本上会讲的笔记系统、全面。同时我自己也是一个初学者,下面总结的可能并不完善、正确,希望看到的大神给我指出,在此非常感谢。


目录
  • SpringMVC流程及源码分析
  • 一 、Spring核心模块
    • 1、核心模块
    • 2、Spring版本命名规则(补充)
  • 二、SpringMVC流程及原理
    • 1、执行流程
      • 1.1、执行流程
      • 1.2、执行流程说明:
        • 1.2.1、第02、03说明
        • 1.2.2、第04说明
        • 1.2.2、SpringMVC组件说明
        • 1.2.3、SpringMVC详细流程图
  • 二、源码分析
    • 1、初始化
      • 1.1、ApplicationContext
    • 2、前端控制器(中央处理器)DistepcherServlet
      • 2.1、查找处理器映射器HandlerMapping
      • 2.2、根据处理器映射器HandlerMapping返回结果调用处理器适配器HandlerAdapter
      • 2.3、检查拦截器Interceptor
      • 2.3、处理器适配器HandlerAdapter执行Handler(Controller)返回ModelAndView
      • 2.4、视图解析器ViewResolver
      • 2.5、视图View
        • 2.5.1、视图对象的作用
        • 2.5.2、View接口图
        • 2.5.3、View的实现类图
        • 2.5.4、View的UML图
        • 2.5.5、常用的View视图类
      • 2.6、其他重要的点
        • 2.6.1、DispatcherServlet.properties
  • 三、引用参考资料
    • 1、引用资料
    • 2、参考资料

一 、Spring核心模块

1、核心模块

​ Spring Web MVC (下文简称为 SpringMVC )是 Spring 提供 Web 应用的框架设计,属于表现层的框架。SpringMVC是Spring框架的一部分。
Spring框架包括大致六大模块,核心容器(Core Container)、AOP和设备支持、数据访问及集成、Web、报文发送、Test

2021022601-01-Spring5核心模块图解

图片来源于Spring官网5.0.0.M5:

​ https://docs.spring.io/spring-framework/docs/5.0.0.M5/spring-framework-reference/html/overview.html#overview-modules

对于Spring5模块图,有2点疑问:
1、不清楚为什么在Spring官网上5.0版本以后,Release版(稳定版)的都未找到模块图,但是在M(里程碑版)版找到 了,如果有人在5.0以后的Release版(稳定版)找到,麻烦给我留个言,谢谢。
2、在其他博文中看到Spring5模块结构图是这样的:

2021022601-02-Spring5核心模块图解-疑问

挺奇怪这个图是哪里来的?(路过的大神请指点)

对于问题2,我在Spring5.2.13.RELEASE GA中,找到了如下所示信息:

2021022601-03-Spring5核心模块图解-5.2.13.RELEASE

拷贝以上信息:

Spring Framework Documentation

Version 5.2.13.RELEASE

What's New, Upgrade Notes, Supported Versions, and other topics, independent of release cadence, are maintained externally on the project's Github Wiki.

Overviewhistory, design philosophy, feedback, getting started.
CoreIoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP.
TestingMock Objects, TestContext Framework, Spring MVC Test, WebTestClient.
Data AccessTransactions, DAO Support, JDBC, O/R Mapping,
Web ServletSpring MVC, WebSocket, SockJS, STOMP Messaging.
Web ReactiveSpring WebFlux, WebClient, WebSocket.
IntegrationRemoting, JMS, JCA, JMX, Email, Tasks, Scheduling, Caching.
LanguagesKotlin, Groovy, Dynamic Languages.

按照以上信息的Web Servlet、Web Reactive已经是分属于不同的模块了。

  • Web Servlet:Spring MVC, WebSocket, SockJS, STOMP Messaging.
  • Web Reactive:Spring WebFlux, WebClient, WebSocket.

Spring官方文档:https://spring.io/projects/spring-framework#learn/

2、Spring版本命名规则(补充)

上面提到了Spring又不同的版本,在此记录一下各个版本的意义。

描述方式说明含义
Snapshot快照版尚不稳定,仍处于开发中的版本
Release稳定版功能相对稳定,可以对外发行,但有时间限制
GA正式版代表广泛可用的稳定版(General Availability)
M里程碑版(M是Milestone的意思)具有一些全新的功能或是有意义的版本
RC终测版Release Candidate(最终测试),即将作为正式版发布

二、SpringMVC流程及原理

1、执行流程

SpringMVC执行流程图
2021022601-04-鲁班学院-springmvc流程图-2清晰点图片来源:三、引用参考资料

1.1、执行流程

  • 01、用户发送出请求到前端控制器(中央处理器)DispatcherServlet进行处理。

  • 02、前端控制器DispatcherServlet收到请求后,调用处理器映射器HandlerMapping。

  • 03、处理器映射器HandlerMapping(处理器映射器)根据request请求的URL等信息查找能够进行处理的Handler,以及相关拦截器interceptor,并构造HandlerExecutionChain执行链,然后将构造好的HandlerExecutionChain执行链对象返回给前端控制器DispatcherServlet。

  • 04、前端控制器DispatcherServlet根据处理器映射器HandlerMapping的

  • 05、处理器适配器HandlerAdapter经过适配调用具体的处理器(Handler/Controller),即业务中自己写的Controller。

  • 06、Controller处理完后返回ModelAndView(springmvc的封装对象,将model和view封装在一起)给处理器适配器HandlerAdapter;

  • 07、处理器适配器HandlerAdapter将Controller执行结果ModelAndView返回给前端控制器DispatcherServlet。

  • 08、前端控制器DispatcherServlet调用视图解析器ViewReslover处理ModelAndView。

  • 09、视图解析器ViewReslover解析后根据逻辑视图名解析成物理视图名即具体的页面地址,生成并返回具体对象View(springmvc封装对象,是一个接口)。

  • 10、前端控制器DispatcherServlet根据对象View进行视图渲染,填充Model。

  • 11、前端控制器DispatcherServlet向用户返回响应

1.2、执行流程说明:

1.2.1、第02、03说明

(1) 处理器映射器:springmvc框架中的一种对象,框架把实现了HandlerMapping接口的类都叫做映射器(多个);

(2) 处理器映射器作用:根据请求,从springmvc容器对象中获取处理器对象(MyController controller = ctx.getBean("some")

(3) 框架把找到的处理器对象放到一个叫做处理器执行链(HandlerExecutionChain)的类保存

(4) HandlerExecutionchain:类中保存着
 a:处理器对象(MyController);
 b:项目中的所有的拦截器List

(5) 方法调用:HandlerExecutionChain mappedHandler - getHandler (processedRequest);

1.2.2、第04说明

(1) HandlerExecutionChain执行链找到对应的处理器映射器HandlerAdapter。
(2) 处理器适配器:springmvc框架中的对象,需要实现HandlerAdapter接口,
(3) 处理器适配器作用:执行处理器方法(调用MyController.doSome()得到返回值ModelAndView )
(4) 前端控制器中调用适配器:HandlerAdapter ha =getHandlerAdapter (mappedHandler.getHandler());
(5) 执行处理器方法:mv= ha.handle (processedRequest, response, mappedHandler.getHandler());

第08说明:
(1) 视图解析器:springmvc中的对象,需要实现ViewResoler接口(可以有多个)
(2) 视图解析器作用:组成视图完整路径,使用前缀,后缀。并创建View对象。
(3) view是一个接口,表示视图的,在框架中jsp,htm1不是string表示,而是使用view和他的实现类表示视图。

InternalResourceview:视图类,表示jsp文件,视图解析器会创建InternalResourceView类对象。 这个对象的里面,有一个属性url-/WEB-INF/view/show.jsp

1.2.2、SpringMVC组件说明

  • (1). 前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU。
  • (2). 处理器映射器(HandlerMapping):根据URL去查找处理器.
  • (3). 处理器(Handler):(需要程序员去写代码处理逻辑的).
  • (4). 处理器适配器(HandlerAdapter):会把处理器包装成适配器,这样就可以支持多种类型的处理器,类比笔记本的适配器(适配器模式的应用).
  • (5). 视图解析器(ViewResovler):进行视图解析,多返回的字符串,进行处理,可以解析成对应的页面.

1.2.3、SpringMVC详细流程图

综上所述,总结下SpringMVC的详细流程图:

2021022601-05-springmvc流程图-详细
图片来源:三、引用参考资料

二、源码分析

以下源码来源jar包:spring-webmvc-5.25.RELEASE.jar

1、初始化

1.1、ApplicationContext

​ ApplicationContext初始化入口类:ApplicationObjectSupport的setApplicationContext方法,setApplicationContext方法中核心部分就是初始化容器initApplicationContext(context),子类AbstractDetectingUrlHandlerMapping实现了该方法。
类图:
2021022601-06-RequestMappingHandlerMapping类层次图
UML图:
2021022601-07-RequestMappingHandlerMapping-uml
​ RequestMappingHandlerMapping ,用于注解@Controller,@RequestMapping来定义controller.
初始化时,3个类的大致分工如下:

  • AbstractHandlerMethodMapping定义整个算法流程;
  • RequestMappingInfoHandlerMapping提供匹配条件RequestMappingInfo的解析处理;
  • RequestMappingHandlerMapping根据@RequestMapping注解生成 RequestMappingInfo,同时提供isHandler实现

2、前端控制器(中央处理器)DistepcherServlet

​ 从上面的流程图可以看到前端控制器(中央处理器)DistepcherServlet是SpringMVC核心,查看DistepcherServlet类的继承情况。
UML图:
![2021022601-08-DispatcherServlet UML图](https://gitee.com/chuchq/blogs-gallery/raw/master/images / 2021/2021022601-08-DispatcherServlet UML图.png)
从继承关系看出:
​ DistepcherServlet ---> FrameworkServlet ---> HttpServletBean---> HttpServlet
​ 那就说明DistepcherServlet 类也是一个Servlet类,那最终核心的方法就是service()方法,即Servlet的核心方法。
​ 那就找service()方法,在DistepcherServlet中没有servic()方法,在父类FrameworkServlet有service()方法,源码如下:
来源:

org.springframework.web.servlet.FrameworkServlet.service(HttpServletRequest request, HttpServletResponse response)

/**	 * Override the parent class implementation in order to intercept PATCH requests.	 */	@Override	protected void service(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());		if (httpMethod == HttpMethod.PATCH || httpMethod == null) {			processRequest(request, response);		}		else {			super.service(request, response);		}	}

可以看到:
FrameworkServlet.service(HttpServletRequest request, HttpServletResponse response)拿到request请求,判断当前请求是否是PATCH请求,不是的就调用父类的servic()方法,掉用父类中的service方法就是去调用该类中doPost(),doGet()方法,根据不同的请求方式然后走doPost()或者doGet(),调用中以doGet()为例,
FrameworkServlet类的doGet()源码:

/**	 * Delegate GET requests to processRequest/doService.	 * <p>Will also be invoked by HttpServlet's default implementation of {@code doHead},	 * with a {@code NoBodyResponse} that just captures the content length.	 * @see #doService	 * @see #doHead	 */	@Override	protected final void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		processRequest(request, response);	}

​ doGet()又调用FrameworkServlet类中的processRequest(request, response);

/**	 * Process this request, publishing an event regardless of the outcome.	 * <p>The actual event handling is performed by the abstract	 * {@link #doService} template method.	 */	protected final void processRequest(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		long startTime = System.currentTimeMillis();		Throwable failureCause = null;		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();		LocaleContext localeContext = buildLocaleContext(request);		RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();		ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);		asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());		initContextHolders(request, localeContext, requestAttributes);		try {			doService(request, response);		}		catch (ServletException | IOException ex) {			failureCause = ex;			throw ex;		}		catch (Throwable ex) {			failureCause = ex;			throw new NestedServletException("Request processing failed", ex);		}		finally {			resetContextHolders(request, previousLocaleContext, previousAttributes);			if (requestAttributes != null) {				requestAttributes.requestCompleted();			}			logResult(request, response, failureCause, asyncManager);			publishRequestHandledEvent(request, response, startTime, failureCause);		}	}

​ processRequest(request, response)方法中最关键的又调用了doService(request, response);查看FrameworkServlet类中的doService(request, response),或者是调试跟踪可知,doService(request, response)由子类DispatcherServlet实现。

源码来源:

org.springframework.web.servlet.FrameworkServlet.doService(HttpServletRequest request, HttpServletResponse response)

/**	 * Subclasses must implement this method to do the work of request handling,	 * receiving a centralized callback for GET, POST, PUT and DELETE.	 * <p>The contract is essentially the same as that for the commonly overridden	 * {@code doGet} or {@code doPost} methods of HttpServlet.	 * <p>This class intercepts calls to ensure that exception handling and	 * event publication takes place.	 * @param request current HTTP request	 * @param response current HTTP response	 * @throws Exception in case of any kind of processing failure	 * @see javax.servlet.http.HttpServlet#doGet	 * @see javax.servlet.http.HttpServlet#doPost	 */	protected abstract void doService(HttpServletRequest request, HttpServletResponse response)			throws Exception;

​ 查看DispatcherServlet中的doService(HttpServletRequest request, HttpServletResponse response)方法

/**	 * Exposes the DispatcherServlet-specific request attributes and delegates to {@link #doDispatch}	 * for the actual dispatching.	 */	@Override	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {		logRequest(request);		// Keep a snapshot of the request attributes in case of an include,		// to be able to restore the original attributes after the include.		Map<String, Object> attributesSnapshot = null;		if (WebUtils.isIncludeRequest(request)) {			attributesSnapshot = new HashMap<>();			Enumeration<?> attrNames = request.getAttributeNames();			while (attrNames.hasMoreElements()) {				String attrName = (String) attrNames.nextElement();				if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {					attributesSnapshot.put(attrName, request.getAttribute(attrName));				}			}		}		// Make framework objects available to handlers and view objects.		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);		request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());		if (this.flashMapManager != null) {			FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);			if (inputFlashMap != null) {				request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));			}			request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());			request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);		}		try {			doDispatch(request, response);		}		finally {			if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {				// Restore the original attribute snapshot, in case of an include.				if (attributesSnapshot != null) {					restoreAttributesAfterInclude(request, attributesSnapshot);				}			}		}	}

​ DispatcherServlet的doService()方法中最终调用doDispatch(request, response),查看源码如下:
org.springframework.web.servlet.DispatcherServlet.doDispatch()

/**	 * Process the actual dispatching to the handler.	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters	 * to find the first that supports the handler class.	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers	 * themselves to decide which methods are acceptable.	 * @param request current HTTP request	 * @param response current HTTP response	 * @throws Exception in case of any kind of processing failure	 */	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {		HttpServletRequest processedRequest = request;		HandlerExecutionChain mappedHandler = null;		boolean multipartRequestParsed = false;		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);		try {			ModelAndView mv = null;			Exception dispatchException = null;			try {				// 文件上传相关,判断是不是二进制请求				processedRequest = checkMultipart(request);				multipartRequestParsed = (processedRequest != request);				// 取得处理当前请求的controller,这里也称为hanlder处理器,第一个步骤的意义就在这里体现了.这里并不是直接返回controller,而是返回的HandlerExecutionChain请求处理器链对象,该对象封装了handler和拦截器interceptors.				// Determine handler for the current request.				mappedHandler = getHandler(processedRequest);				// 如果handler为空,则返回404				if (mappedHandler == null) {					noHandlerFound(processedRequest, response);					return;				}				//3. 获取处理request的处理器适配器HandlerAdapter				// Determine handler adapter for the current request.				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());				// Process last-modified header, if supported by the handler.				String method = request.getMethod();				boolean isGet = "GET".equals(method);				if (isGet || "HEAD".equals(method)) {					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {						return;					}				}				//处理器适配器执行之前,检查拦截器的方法				if (!mappedHandler.applyPreHandle(processedRequest, response)) {					return;				}				//处理器适配器根据找到,执行handler,返回ModelAndView				// Actually invoke the handler.				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());				if (asyncManager.isConcurrentHandlingStarted()) {					return;				}				applyDefaultViewName(processedRequest, mv);				mappedHandler.applyPostHandle(processedRequest, response, mv);			}			catch (Exception ex) {				dispatchException = ex;			}			catch (Throwable err) {				// As of 4.3, we're processing Errors thrown from handler methods as well,				// making them available for @ExceptionHandler methods and other scenarios.				dispatchException = new NestedServletException("Handler dispatch failed", err);			}			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);		}		catch (Exception ex) {			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);		}		catch (Throwable err) {			triggerAfterCompletion(processedRequest, response, mappedHandler,					new NestedServletException("Handler processing failed", err));		}		finally {			if (asyncManager.isConcurrentHandlingStarted()) {				// Instead of postHandle and afterCompletion				if (mappedHandler != null) {					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);				}			}			else {				// Clean up any resources used by a multipart request.				if (multipartRequestParsed) {					cleanupMultipart(processedRequest);				}			}		}	}

​ 可以看出doDispatch()就是SpringMVC的核心代码了,分析doDispatch():

2.1、查找处理器映射器HandlerMapping

​ 首先看下处理器映射器HandlerMapping类图:
2021022601-09-HandlerMapping类图

doDispatch()关键代码:

HandlerExecutionChain mappedHandler = null;mappedHandler = getHandler(processedRequest);

​ mappedHandler是一个执行链HandlerExecutionChain 对象,这里封装了handler和拦截器interceptors,getHandler(processedRequest)方法就是从处理器映射器HandlerMapping中找到url和controller的对应关系,并返回给前端控制器DispatchServlet。
查看getHandler(processedRequest);源码:

/**	 * Return the HandlerExecutionChain for this request.	 * <p>Tries all handler mappings in order.	 * @param request current HTTP request	 * @return the HandlerExecutionChain, or {@code null} if no handler could be found	 */	@Nullable	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {		if (this.handlerMappings != null) {			for (HandlerMapping mapping : this.handlerMappings) {				HandlerExecutionChain handler = mapping.getHandler(request);				if (handler != null) {					return handler;				}			}		}		return null;	}

调试代码如下:
2021022601-10-DispatchServlet-doDispatch-getHandler执行截图
从代码调试中可以看到handlerMapping中有三个对象:

this.handlerMappings = {ArrayList@4662} size = 3 0 = {BeanNameUrlHandlerMapping@4791} 1 = {RequestMappingHandlerMapping@4792} 2 = {RouterFunctionMapping@4793} 
  • BeanNameUrlHandlerMapping:初始化时会将urlpath做映射存储(

  • RequestMappingHandlerMapping:初始化时会将Controller中配置@RequestMapping注解的方法做映射存储(注解);

  • RouterFunctionMapping:
    (这个对象不是太理解)
    这也就是为什么要去HandlerMapping找一个Handler了,因为处理器映射器HandlerMapping有不同的实现:

  • 1、

  • 2、注解方式

接着看getHandler(HttpServletRequest request)方法,先遍历HandlerMappers,查找控制器找到之后就返回执行链HandlerExecutionChain类型的Handler。

2021022601-11-DispatchServlet-doDispatch-getHandler-执行截图

可以看到返回的Handler中,拿到的就是我们自己编码的Controller类,以及拦截器(演示项目中未编写,所以调试汇总返回的Handler最后是0 interceptors)
HandlerExecutionChain with [com.bjpowernode.controller.MyController#doSome()] and 0 interceptors
2021022601-12-02-DispatchServlet-doDispatch-getHandler-mappedHandler执行截图2
将正在调试的idea打开自己编写的Controller来对照,发现一致:
2021022601-13-DispatchServlet-doDispatch-getHandler-执行返回结果截图

2.2、根据处理器映射器HandlerMapping返回结果调用处理器适配器HandlerAdapter

doDispatch()里面的关键代码:

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

源码如下:

/**	 * Return the HandlerAdapter for this handler object.	 * @param handler the handler object to find an adapter for	 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.	 */	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {		if (this.handlerAdapters != null) {			for (HandlerAdapter adapter : this.handlerAdapters) {				if (adapter.supports(handler)) {					return adapter;				}			}		}		throw new ServletException("No adapter for handler [" + handler +				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");	}

为什么还要获取处理器适配器HandlerAdapter:与获取处理器映射器HandlerMapping一样,Spring提供了不通的处理器适配器。
调试如下:

2021022601-14-01-DispatchServlet-doDispatch-getHandlerAdapter-执行截图-出方法-在用
查看DEBUG调试模式中getHandlerAdapter()方法在中的:
handler、adapter、this.handlerAdapters

2021022601-15-DispatchServlet-doDispatch-getHandlerAdapter-执行结果截图
以下是拷贝的结果:
handler

handler = {HandlerMethod@4792} "com.bjpowernode.controller.MyController#doSome()" logger = {LogAdapter$JavaUtilLog@4858} bean = {MyController@4859} beanFactory = {DefaultListableBeanFactory@4847} "org.springframework.beans.factory.support.DefaultListableBeanFactory@56b5a4c3: defining beans [myController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,org.springframework.web.servlet.view.InternalResourceViewResolver#0]; root of factory hierarchy" beanType = {Class@3782} "class com.bjpowernode.controller.MyController" method = {Method@4860} "public org.springframework.web.servlet.ModelAndView com.bjpowernode.controller.MyController.doSome()" bridgedMethod = {Method@4860} "public org.springframework.web.servlet.ModelAndView com.bjpowernode.controller.MyController.doSome()" parameters = {MethodParameter[0]@4861} responseStatus = null responseStatusReason = null resolvedFromHandlerMethod = {HandlerMethod@4863} "com.bjpowernode.controller.MyController#doSome()" interfaceParameterAnnotations = null description = "com.bjpowernode.controller.MyController#doSome()"

adapter

adapter = {RequestMappingHandlerAdapter@4827} customArgumentResolvers = null argumentResolvers = {HandlerMethodArgumentResolverComposite@4833} initBinderArgumentResolvers = {HandlerMethodArgumentResolverComposite@4834} customReturnValueHandlers = null returnValueHandlers = {HandlerMethodReturnValueHandlerComposite@4835} modelAndViewResolvers = null contentNegotiationManager = {ContentNegotiationManager@4836} messageConverters = {ArrayList@4837} size = 4 requestResponseBodyAdvice = {ArrayList@4838} size = 0 webBindingInitializer = null taskExecutor = {SimpleAsyncTaskExecutor@4839} asyncRequestTimeout = null callableInterceptors = {CallableProcessingInterceptor[0]@4840} deferredResultInterceptors = {DeferredResultProcessingInterceptor[0]@4842} reactiveAdapterRegistry = {ReactiveAdapterRegistry@4844} ignoreDefaultModelOnRedirect = false cacheSecondsForSessionAttributeHandlers = 0 synchronizeOnSession = false sessionAttributeStore = {DefaultSessionAttributeStore@4845} parameterNameDiscoverer = {DefaultParameterNameDiscoverer@4846} beanFactory = {DefaultListableBeanFactory@4847} "org.springframework.beans.factory.support.DefaultListableBeanFactory@56b5a4c3: defining beans [myController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,org.springframework.web.servlet.view.InternalResourceViewResolver#0]; root of factory hierarchy" sessionAttributesHandlerCache = {ConcurrentHashMap@4848} size = 0 initBinderCache = {ConcurrentHashMap@4849} size = 0 initBinderAdviceCache = {LinkedHashMap@4850} size = 0 modelAttributeCache = {ConcurrentHashMap@4851} size = 0 modelAttributeAdviceCache = {LinkedHashMap@4852} size = 0 order = 2147483647 supportedMethods = null allowHeader = "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS" requireSession = false cacheControl = null cacheSeconds = -1 varyByRequestHeaders = null useExpiresHeader = false useCacheControlHeader = true useCacheControlNoStore = true alwaysMustRevalidate = false servletContext = {ApplicationContextFacade@4754} logger = {LogAdapter$JavaUtilLog@4854} applicationContext = {

this.handlerAdapters

this.handlerAdapters = {ArrayList@4658} size = 4 0 = {HttpRequestHandlerAdapter@4810} 1 = {SimpleControllerHandlerAdapter@4820} //

可以看到找到4个处理器适配器。通过DEBUG模式可以看到,此次取到的处理器适配器HandlerAdapter是:RequestMappingHandlerAdapter

ha = {RequestMappingHandlerAdapter@4827} 

2.3、检查拦截器Interceptor

doDispatch()中的关键代码:

if (!mappedHandler.applyPreHandle(processedRequest, response)) {					return;				}org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle

applyPreHandle(processedRequest, response)源码:

/**	 * Apply preHandle methods of registered interceptors.	 * @return {@code true} if the execution chain should proceed with the	 * next interceptor or the handler itself. Else, DispatcherServlet assumes	 * that this interceptor has already dealt with the response itself.	 */	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {		HandlerInterceptor[] interceptors = getInterceptors();		if (!ObjectUtils.isEmpty(interceptors)) {			for (int i = 0; i < interceptors.length; i++) {				HandlerInterceptor interceptor = interceptors[i];				if (!interceptor.preHandle(request, response, this.handler)) {					triggerAfterCompletion(request, response, null);					return false;				}				this.interceptorIndex = i;			}		}		return true;	}

2.3、处理器适配器HandlerAdapter执行Handler(Controller)返回ModelAndView

doDispatch()中的关键代码:

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

DEBUG模式调试,是跳到了:
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
源码如下:

/**	 * This implementation expects the handler to be an {@link HandlerMethod}.	 */	@Override	@Nullable	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)			throws Exception {		return handleInternal(request, response, (HandlerMethod) handler);	}

再往下看handleInternal(request, response, (HandlerMethod) handler)方法,
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

@Override	protected ModelAndView handleInternal(HttpServletRequest request,			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {		ModelAndView mav;		checkRequest(request);		// Execute invokeHandlerMethod in synchronized block if required.		if (this.synchronizeOnSession) {			HttpSession session = request.getSession(false);			if (session != null) {				Object mutex = WebUtils.getSessionMutex(session);				synchronized (mutex) {					mav = invokeHandlerMethod(request, response, handlerMethod);				}			}			else {				// No HttpSession available -> no mutex necessary				mav = invokeHandlerMethod(request, response, handlerMethod);			}		}		else {			// No synchronization on session demanded at all...			mav = invokeHandlerMethod(request, response, handlerMethod);		}		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);			}			else {				prepareResponse(response);			}		}		return mav;	}

注意,handleInternal(request, response, (HandlerMethod) handler)方法的返回值是ModelAndView ,这里就完成了处理器适配器HandlerAdapter执行Handler(Controller)并将结果ModelAndView返回给前端控制器DistepchServlet

2.4、视图解析器ViewResolver

  接上2.3:前端控制器DistepchServlet接收到处理器适配器HandlerAdapter返回的ModelAndView以后,这里分2种情况:

  • (1)、如果ModelAndView里面是逻辑视图
    前端控制器DistepchServlet调用视图解析器ViewResolver通过逻辑视图查找真正的视图对象View,并返回给前端控制器DistepchServlet。
  • (2)、如果ModelAndView里面是非逻辑视图:
    如:MappingJackson2JsonView(把当前数据转为为JSON数据,并不需要对视图逻辑名称进行转换)

总结一下:
视图解析器ViewResolver接口主要作用是解析前端控制器DispatcherServlet传递的逻辑视图名,并将解析结果的真正的视图对象View传回给前端控制器DispatcherServlet

ViewResolverd的实现类:

2021022601-16-ViewResolver-实现类图-hierarchy
ViewResolver的UML:

2021022601-17-ViewResolver-uml图

2.5、视图View

2.5.1、视图对象的作用

  • (1)、将控制器返回的数据处理渲染,最终返回客户端展示给用户,主要就是完成转发或者是重定向的操作.。
  • (2)、为了实现视图模型和具体实现技术的解耦(指的是Spring在org.springframework.web.servlet包中定义的抽象View接口),详见2.5.2View接口图。
  • (3)、视图对象View由视图解析器负责实例化。由于视图是无状态(每一次请求都会创建一个新的view对象)的,所以不会有线程安全的问题.

2.5.2、View接口图

2021022601-18-View-接口方法

2.5.3、View的实现类图

2021022601-19-View-实现类图-hierarchy

2.5.4、View的UML图

![2021022601-20-01-View-uml(hierarchic group layout)](https://gitee.com/chuchq/blogs-gallery/raw/master/images / 2021/2021022601-20-01-View-uml(hierarchic group layout).png)

2.5.5、常用的View视图类

视图类型 简介
URL视图资源图 InternalResourceView 将JSP或其他资源封装成一个视图。被视图解析器InternalResourceViewResolver默认使用。
JstlView InternalResourceView的子类。如果JSP中使用了JSTL的国际化标签,就需要使用该视图类。
文档视图 AbstractExcelView Excel文档视图的抽象类。
AbstractPdfView PDF文档视图的抽象类
报表视图 ConfigurableJasperReportsView 常用的JasperReports报表视图
JasperReportsHtmlView
JasperReportsPdfView
JasperReportsXlsView
JSON视图 MappingJackson2JsonView 将数据通过Jackson框架的ObjectMapper对象,以JSON方式输出

2.6、其他重要的点

2.6.1、DispatcherServlet.properties

DispatcherServlet.properties文件是在SpringMVC架包中:
2021022601-21-jar-DispatchServlet.properties
DispatcherServlet.properties内容:

# Default implementation classes for DispatcherServlet's strategy interfaces.# Used as fallback when no matching beans are found in the DispatcherServlet context.# Not meant to be customized by application developers.org.springframework.web.servlet.LocaleResolver=	org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverorg.springframework.web.servlet.ThemeResolver=	org.springframework.web.servlet.theme.FixedThemeResolverorg.springframework.web.servlet.HandlerMapping=	org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\	org.springframework.web.servlet.function.support.RouterFunctionMappingorg.springframework.web.servlet.HandlerAdapter=	org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\	org.springframework.web.servlet.function.support.HandlerFunctionAdapterorg.springframework.web.servlet.HandlerExceptionResolver=	org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=	org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatororg.springframework.web.servlet.ViewResolver=	org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=	org.springframework.web.servlet.support.SessionFlashMapManager

SpringMVC为什么能加载不同处理器映射器HandlerMapping、处理器适配器handlerAdapter,就是因为框架配置了这个DispatcherServlet.properties文件。

三、引用参考资料

1、引用资料

  • SpringMVC流程图引用地址:https://www.iqiyi.com/w_19s2gmyazh.html

  • SpringMVC流程图引用地址2:https://blog.csdn.net/win7system/article/details/90674757

  • View视图作用引用地址:https://blog.csdn.net/qq_43193797/article/details/84928603

  • Spring官方文档:https://spring.io/projects/spring-framework#learn/

    在写此文的时候可能还有少部分是参考了其他资料,但是整理的时候我已经找不到原文出处了,如果原文作者看到,请及时联系我,我在文章中加上引用出处,谢谢!

2、参考资料

  • 参考:w3cschool-Spring MVC 4.2.4.RELEASE 中文文档:

    https://www.w3cschool.cn/spring_mvc_documentation_linesh_translation/

  • 参考:https://www.cnblogs.com/leftthen/category/790002.html


免责声明:
本文中使用的部分图片来自于网络(地址见:三、引用参考资料),如有侵权,请联系博主进行删除。

转载声明:

写博客不易,请尊重原作者!!

​ 欢迎大家阅读、转载,如果是整文转载请在文章开头或者结尾处 注明 原文地址、作者,如果是大段参考备注 参考链接









原文转载:http://www.shaoqun.com/a/608577.html

跨境电商:https://www.ikjzd.com/

易趣:https://www.ikjzd.com/w/210

贝恩投资公司:https://www.ikjzd.com/w/1336


SpringMVC流程及源码分析前言​ 学了一遍SpringMVC以后,想着做一个总结,复习一下。复习写下面的总结的时候才发现,其实自己学的并不彻底、牢固、也没有学全,视频跟书本是要结合起来一起,每一位老师的视频可能提到的东西都不一致,也导致也不是很全面,书本上会讲的笔记系统、全面。同时我自己也是一个初学者,下面总结的可能并不完善、正确,希望看到的大神给我指出,在此非常感谢。目录SpringMVC
noon:https://www.ikjzd.com/w/259
haofang:https://www.ikjzd.com/w/1046
prime:https://www.ikjzd.com/w/129
新手创业跨境电商适合做亚马逊还是shopee?:https://www.ikjzd.com/home/109606
红海里面怎么找蓝海?以婴儿车为例(美国站图文详解):https://www.ikjzd.com/home/91641
跨境电商运营具体都有哪些工作:https://www.ikjzd.com/home/125607

格里芬放弃1330万美元 感谢活塞队让所有人受益_拉尼亚

原标题:格里芬放弃1330万美元 感谢活塞队让所有人受益

北京时间3月6日消息,来自《The Athletic》著名记者萨马斯-查拉尼亚的报道称,消息灵通人士透露,为了恢复自由身,布雷克-格里芬放弃了1330万美元。

今天格里芬和活塞队达成买断协议。原本他的剩余薪水为7575万美元(本赛季3680万美元,2021-22赛季拥有3895万美元的球员选项),为了最终达成买断,格里芬放弃了1330万美元。

这意味着,格里芬将在未来从活塞队领到6245万美元的薪水。消息源称,活塞队不会使用延伸条款,所以将在2022年夏天前完成对格里芬薪水的支付。

格里芬将在当地时间本周日17时度过澄清期,成为一名完全自由球员。根据查拉尼亚得到的线报,多支季后赛强队都对格里芬表示出了兴趣,篮网队是目前的领跑者。

完成买断后,格里芬在声明中表示:"感谢活塞队的努力,这个决定让所有人都受益。在这里,我祝愿活塞队未来能取得成功。"

活塞队老板汤姆-戈尔斯在声明中表示:"格里芬是活塞队和底特律的伟大代表,他的职业道德和对待比赛的态度给我们的球队文化做出了巨大贡献。格里芬是一位完美的职业球员,我们希望他能在未来继续获得成功。"

对格里芬来说,接下去他的目标将是争夺总冠军。返回搜狐,查看更多

责任编辑:

原文转载:http://sport.shaoqun.com/a/470740.html

跨境电商:https://www.ikjzd.com/

淘粉吧怎么返利:https://www.ikjzd.com/w/1725

vat:https://www.ikjzd.com/w/109


原标题:格里芬放弃1330万美元感谢活塞队让所有人受益北京时间3月6日消息,来自《TheAthletic》著名记者萨马斯-查拉尼亚的报道称,消息灵通人士透露,为了恢复自由身,布雷克-格里芬放弃了1330万美元。今天格里芬和活塞队达成买断协议。原本他的剩余薪水为7575万美元(本赛季3680万美元,2021-22赛季拥有3895万美元的球员选项),为了最终达成买断,格里芬放弃了1330万美元。这意味
吴佳:https://www.ikjzd.com/w/1770
乐一番:https://www.ikjzd.com/w/1562
etoro:https://www.ikjzd.com/w/1402
黑五刚过,亚马逊德国站开始查没有交VAT税的卖家:https://www.ikjzd.com/home/11562
2018亚马逊黑色星期五爆单表现强劲,亚马逊内定严查Vine和VC乱象!:https://www.ikjzd.com/home/11659
人人都在说赚钱的跨境电商,但是你真的了解吗?:https://www.ikjzd.com/home/23123

中年男人出现8个异常,说明身体走下坡路了!

核心提示:在大众的印象中,男人总是觉得自己十分强壮,不在意身体出现的各种异常,等到查出疾病却后悔不已。英国《每日邮报》刊出多位健康专家制定的一个健康自测问卷,以帮助男性了解健康状况,还不快来测测?

在大众的印象中,男人总是觉得自己十分强壮,不在意身体出现的各种异常,等到查出疾病却后悔不已。英国《每日邮报》刊出多位健康专家制定的一个健康自测问卷,以帮助男性了解健康状况,还不快来测测?

问题一:寒冷天气呼吸困难吗?

呼吸困难代表心脏在被迫加大工作量,如果同时有心脏被压迫的感觉应警惕。

英国心血管学会心脏病专家Lane·Simpson表示,假如在寒冷天气、饱餐后或体力消耗大时,都觉得呼吸困难,胸口疼痛、发紧,可能预示着动脉变窄。

应对:

做心电图以检测心脏活动状况,也可进行压力测试。

问题二:晚上经常起夜吗?

如果感到尿急,排尿量却不多,甚至尿液、精液中带血,这可能是尿路感染、前列腺炎的征兆,甚至预示癌症。

应对:

尿频并非前列腺癌征兆,但通过体检能了解自身的患病风险。

此外,检查直肠情况和前列腺特异性抗原水平会帮助诊断癌症。


问题三:是否有尴尬的瘙痒?

血液中葡萄糖的水平过高易造成真菌感染,从而使外阴瘙痒。

如果症状一直没有改善,同时还出现视物模糊、口渴、极度疲劳及尿频(特别是晚上),那么,这很可能提示2型糖尿病。

应对:

建议验血,或者改变不良生活习惯。

问题四:经常大量出汗吗?

如果有大量出汗(特别是晚上)、性 欲减退、易怒、压抑等症状,很可能和男性睾酮水平下降有关系。

应对:

针对睾酮的治疗不仅能改善ED,还能帮助降低胆固醇水平。


问题五:肠道经常胀气?

肠道胀气难忍、排便习惯突然改变、肛门疼痛带有黏液或出现便血,都可能和肠癌有关。

排便习惯改变是因为肿瘤干扰了正常的消化过程。

此外,肿瘤会带来溃疡或息肉,进而引起出血。

应对:

50岁以下男性更要警惕结肠炎,50岁以上男性假如出现以上症状,最好去做结肠癌的排查。

问题六:是否失去一种感官功能?

失去一种感觉的同时,如果又频繁出现无原因的暴躁、易怒,并伴有持续性头痛,这可能提示脑血管出血或脑肿瘤。

应对:

综合各种症状来确诊,持续头痛也可能是眼疾或高血压。


问题七:夜间开车很困难?

如果是年轻人,可能是视网膜黄斑变性,它会影响人的夜间视力。

如果是老年人,其原因更可能是白内障。

应对:

解决白内障最有效的办法是手术,也是唯一的方法。

问题八:曾经出现短暂视物重影?

如果脑中的血液供应被暂时干扰,就会有这种情况,这或许提示短暂性脑缺血发作("小中风")。


出现重影也可能和其他疾病有关,如甲状腺问题、糖尿病等。

应对:

如出现说话含糊等症状超过十分钟者,最好马上送往医院,因为这一症状预示中风的靠近。


原文转载:http://health.shaoqun.com/a/197099.html

跨境电商:https://www.ikjzd.com/

一淘网:https://www.ikjzd.com/w/1698

patents:https://www.ikjzd.com/w/857


核心提示:在大众的印象中,男人总是觉得自己十分强壮,不在意身体出现的各种异常,等到查出疾病却后悔不已。英国《每日邮报》刊出多位健康专家制定的一个健康自测问卷,以帮助男性了解健康状况,还不快来测测? 在大众的印象中,男人总是觉得自己十分强壮,不在意身体出现的各种异常,等到查出疾病却后悔不已。英国《每日邮报》刊出多位健康专家制定的一个健康自测问卷,以帮助男性了解健康状况,还不快来测测?问题一:寒冷天气
prime day:https://www.ikjzd.com/w/131
韩蓬:https://www.ikjzd.com/w/1635
writer:https://www.ikjzd.com/w/1280
赶跟卖却被封店铺?分享8种亚马逊店铺被封的原因及解决方案!:https://www.ikjzd.com/home/142658
2019跨境出海当大卖,欧洲市场不容错过!:https://www.ikjzd.com/home/17241
为产品插上主角光环,让精准有效的广告工具为您效力!:https://www.ikjzd.com/home/17952

2021年3月5日星期五

JavaScript对象的两类属性(数据属性与访问器属性)

对JavaScript来说,属性并非只是简单的名称和值,JavaScript用一组特征(attribute)来描述属性 (property)。

第一类属性数据属性具有四个特征。

value:就是属性的值。

writable:决定属性能否被赋值。

enumerable:决定for in能否枚举该属性。

configurable:决定该属性能否被删除或者改变特征值。

在大多数情况下,我们只关心数据属性的值即可。

第二类属性是访问器(getter/setter)属性,它也有四个特征。

getter:函数或undefined,在取属性值时被调用。

setter:函数或undefined,在设置属性值时被调用。

enumerable:决定for in能否枚举该属性。

configurable:决定该属性能否被删除或者改变特征值。

我们通常用于定义属性的代码会产生数据属性,

其中的writable、enumerable、configurable都默认为 true。

我们可以使用内置函数 Object.getOwnPropertyDescripter来查看,

如以下代码所示:

var o = { a: 1 }; o.b = 2; //a和b皆为数据属性

Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}

 

这里使用了两种语法来定义属性,定义完属性后,我们用JavaScript的API来查看这个属性,

我们可以发现,这样定义出来的属性都是数据属性,writeable、enumerable、configurable都是默认值为true。

 

如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty,示例如下:

var o = { a: 1 }; Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true}); //a和b都是数据属性,但特征值变化了

Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}

o.b = 3; console.log(o.b); // 2

使用了Object.defineProperty来定义属性,这样定义属性可以改变属性的writable和enumerable。

我们同样用Object.getOwnPropertyDescriptor来查看,发现确实改变了writable和enumerable特征。因为writable特征为false,所以我们重新对b赋值,b的值不会发生变化。

在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下所示:

var o = { get a() { return 1 } };

console.log(o.a); // 1

访问器属性跟数据属性不同,每次访问属性都会执行getter或者setter函数。这里我们的getter函数返回了1,所以o.a每次都得到1。

JavaScript 对象的运行时是一个"属性的集合",属性以字符串或者Symbol(es6出现新的Symbol类型)为key,以数据属性特征值或者访问器属性特征值为value。

现在js有7大类型:underfined,null,number,String,Boolean,Object,和Symbol这7大语言类型。









原文转载:http://www.shaoqun.com/a/606611.html

跨境电商:https://www.ikjzd.com/

代购公司:https://www.ikjzd.com/w/1982

airwallex:https://www.ikjzd.com/w/1011


对JavaScript来说,属性并非只是简单的名称和值,JavaScript用一组特征(attribute)来描述属性(property)。第一类属性数据属性具有四个特征。value:就是属性的值。writable:决定属性能否被赋值。enumerable:决定forin能否枚举该属性。configurable:决定该属性能否被删除或者改变特征值。在大多数情况下,我们只关心数据属性的值即可。第二类
智赢:https://www.ikjzd.com/w/1511
识货:https://www.ikjzd.com/w/1745
zen cart:https://www.ikjzd.com/w/1282
少妇口述:女儿撞破我偷情后陷堕落漩涡:http://lady.shaoqun.com/m/a/82771.html
亚马逊或将英国的"数字服务税"转嫁给卖家!:https://www.ikjzd.com/home/114618
亚马逊近期高频问题汇总:https://www.ikjzd.com/home/562

Mysql基础部分总结

Mysql基本语法:

文末有mysql资料

执行顺序:

from -> join -> on -> where -> groupby -> avg max .. -> having -> select ->order by

SQL语言分类:

  • DQL:数据查询语言
  • DML:数据操作语言
  • DDL:数据定义语言
  • DCL:数据控制语言

DQL

data query language

SELECT:

  • 可以理解为Java的System.out.println()的输出;
  • 输出内容可以是
    • 字段 select 字段名 from 表名
    • 常量 select 90
    • 函数 select concat('a', 'bbb');
    • 表达式 select 100/1234;
    • 起别名 select last_name as '姓名
    • 去重 select DISTINCT department_id

关于 select中的 '+':

  • select 数值+数值; 直接运算
  • select 字符+数值;先试图将字符转换成数值,如果转换成功,则继续运算;否则转换成0,再做运算
    • select 'aa'+70 #70
    • select 70 +'30' #100
  • select null+值;结果都为null

描述表结构:

DESC departments;

条件查询

/* 条件运算符: > < <> != >= <= 逻辑运算符: && || ! and or not 模糊查询 : like ,between ,and ,in ,is null 		like '%%' 匹配不出null值 	通配符:   % 任意多个字符,包含0个.   _ 任意单个字符  默认转义\  自定义转义: ESCAPE '转义字符' */ #1 查询工资在 12000-17000 的员工姓名和工资SELECT last_name as '姓名',salary as '工资'FROM employeesWHERE salary BETWEEN 12000 and 17000; #2 查询员工号为 176 的员工的姓名和部门号和年薪SELECT employee_id as '编号',last_name as '姓名',job_id as '部门号',salary*12 as '年薪'FROM employeesWHERE employee_id =176 ; #3 选择工资不在 5000 到 12000 的员工的姓名和工资SELECT last_name as '姓名',salary as '工资'FROM employeesWHERE salary not BETWEEN 5000 and 17000;#4 选择在 20 或 50 号部门工作的员工姓名和部门号SELECT last_name as '姓名',department_id as '部门号'FROM employeesWHERE -- department_id =20 or department_id =50department_id in(20,50);#5#属性判空 选择公司中没有管理者的员工姓名及 job_idSELECT last_name as '姓名',job_id as '工作号'FROM employeesWHERE ISNULL(manager_id);#6选择公司中有奖金的员工姓名,工资和奖金级别SELECT last_name as '姓名',commission_pct as '奖金',salary as "工资"FROM employeesWHERE not ISNULL(commission_pct);#7 选择员工姓名的第三个字母是 a 的员工姓名SELECT last_name as '姓名'FROM employeesWHERE last_name LIKE '__a%';#8 选择姓名中有字母 a 和 e 的员工姓名SELECT last_name as '姓名'FROM employeesWHERE last_name LIKE '%a%e%' or last_name LIKE '%e%a%';;#9 显示出表 employees 表中 first_name 以 'e'结尾的员工信息SELECT last_name as '姓名'FROM employeesWHERE last_name LIKE '%e';;#10 显示出表 employees 部门编号在 80-100 之间 的姓名、职位SELECT last_name as '姓名',department_id '部门号'FROM employeesWHERE department_id BETWEEN 80 AND 100;;#11 显示出表 employees 的 manager_id 是 100,101,110 的员工姓名、职位SELECT last_name as '姓名',job_id as '职位',manager_idFROM employeesWHERE manager_id in(100,101,110);

排序

#1 查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序SELECT last_name as name,department_id as dID ,salary*12 as yearsalFROM employeesORDER BY yearsal DESC,last_name ASC#2 选择工资不在 8000 到 17000 的员工的姓名和工资,按工资降序SELECT last_name as name,salary as salFROM employeesWHERE salary not BETWEEN 8000 and 17000ORDER BY salary DESC#3 查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号升序SELECT department_id as dID,email,LENGTH(email) as '邮箱长度'FROM employeesORDER BY LENGTH(email) DESC,department_id ASC

常见函数:

字符函数

  • LOWER(str)
  • UPPER(str)
  • CONCAT(str1,str2,...)
  • SUBSTR(str,pos,len) ps:有多种重载函数
  • LENGTH(str)
  • INSTR(str,substr) 返回子串的第一次出现的索引
  • TRIM([remstr FROM] str) 默认去除前后空格
    • SELECT LENGTH(TRIM('a' FROM "aaa123aaa")) as '长度' => 123
  • REPLACE(str,from_str,to_str)
  • LPAD(str,len,padstr) ,RPAD(str,len,padstr) 用指定字符填充指定长度
    • SELECT LPAD('aaaaa','10','#') => #####aaaaa

数学函数

  • ROUND(X,D) 四舍五入
    • ROUND(45.926,2) => 45.93
  • TRUNCATE 截断
    • TRUNCATE(45.926,2) =>45.92
  • MOD :求余

日期函数

  • now :当前时间

  • STR_TO_DATE(str,format):将日期格式的字符转换成指定格式的日期

    • STR_TO_DATE('2017-01-06 10:20:30','%Y-%m-%d %H:%i:%s')
    • 2017-01-06 10:20:30
  • DATE_FORMAT(date,format) :将日期转换成字符

    • DATE_FORMAT('2021223','%Y年%m月%d日')

流程控制函数

-练习-

#1显示系统时间(注:日期+时间)SELECT NOW()#2 计算年薪SELECT last_name as name,salary,salary*1.2 as newsalFROM employees#3将员工的姓名按首字母排序,并写出姓名的长度(length)SELECT last_name as name ,LENGTH(last_name) as '长度'FROM employeesORDER BY SUBSTR(name,1,1) ASC,LENGTH(name) DESC#4 输出 <last_name> earns <salary> monthly but wants <salary*3>SELECT CONCAT(last_name,' earn ',ROUND(salary),' monthly but wants ',ROUND(salary*3)) as 'Dream Salary'FROM employees#5/*job gradeAD_PRES AST_MAN BIT_PROG CSA_REP DST_CLERK ELast_name Job_id Gradeking  AD_PRES A*/SELECT last_name,job_id, #case 也算一个字段,用逗号分隔CASE job_id	WHEN 'AD_PRES' THEN		'A'	WHEN 'ST_MAN' THEN	'B'	WHEN 'IT_PROG' THEN		'C'	WHEN 'SA_REP' THEN	'D'	WHEN 'ST_CLERK' THEN	'E'	ELSE		'null'END as 'grade'FROM employeesORDER BY grade ASC

分组函数:

特征:

  1. 忽略null值,不计入
  2. 搭配distinct去重
  • AVG() 数值型
  • SUM() 数值型
  • COUNT() 任意数据类型
  • MAX() 任意数据类型
  • MIN() 任意数据类型
COUNT(*):

​ 为什么使用推荐使用COUNT(*)统计总记录数,根据分组函数的特点,null值不计入,当某个字段为null时,可能会出现漏记.

摘自官网:

InnoDB以相同的方式处理SELECT COUNT(*)和SELECT COUNT(1)操作。没有性能差异。

分组查询:

1.单子段分组:

select 分组函数,分组后的字段from 表【where 筛选条件】    -- 分组前的筛选条件group by 分组的字段【having 分组后的筛选】 -- 分组函数,筛选满足条件的组【order by 排序列表】

2.按函数分组

group by 后还可使用函数,

​ 例子:按员工姓名长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些;

SELECT LENGTH(last_name) as 'length', COUNT(*)FROM employeesGROUP BY LENGTH(last_name)HAVING COUNT(*) >3

3.多字段分组

例子:查询每个部门每个工种的员工平均工资

SELECT AVG(salary),department_id,job_idFROM employeesWHERE not ISNULL(department_id)GROUP BY department_id,job_idORDER BY AVG(salary) ASC

φ(゜▽゜*)♪

-练习一-

#1.查询各 job_id 的员工工资的最大值,最小值,平均值,总和,并按 job_id 升序SELECT job_id, MAX(salary),MIN(salary),AVG(salary),SUM(salary)FROM employeesGROUP BY job_idORDER BY job_id ASC#2.查询各个管理者手下员工的最低工资,其中最低工资不能低于 6000, 没有管理者的员工不计算在内SELECT manager_id, MIN(salary)FROM employeesWHERE not ISNULL(manager_id) -- 分组前的筛选条件GROUP BY manager_idHAVING MIN(salary)>=6000 -- 筛选满足条件的组ORDER BY manager_id ASC #3.查询员工表中的最大入职时间和最小入职时间的相差天数SELECT DATEDIFF(MAX(hiredate),MIN(hiredate))FROM employees

联合查询:

UNION

when use:查新的结果来自多个表,且多个表没有直接的连接关系,但查询的信息一致

特点:

  1. 查询的列数是一致的,顺序也最好一致
  2. union默认去重,如果使用 union all 可包含重复项

连接查询:

笛卡尔乘积现象:

SELECT b.*,g.*FROM boys b,beauty g

表1 有m行,表2 有n行,结果=m*n;

原因:无有效的连接条件

避免:可以使用WHERE 添加有效的连接条件

内连接:

返回两张表都满足条件的部分.

  • 等值连接 :连接条件中使用等于号(=)运算符比较
  • 非等值连接:连接条件中不使用等于号(=)运算符比较
  • 自连接 :相当于一张表当作俩张表使用.
#(等值连接) #查询每个城市的部门个数 SELECT city,COUNT(*) FROM locations l,departments d WHERE l.location_id = d.location_id GROUP BY city # 查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资 SELECT	d.department_name,d.manager_id ,MIN(e.salary)  FROM employees e,departments d WHERE e.department_id =d.department_id AND NOT ISNULL(e.commission_pct) GROUP BY e.department_id #查询每个国家下的部门个数大于 2 的国家编号 SELECT l.country_id FROM locations l,departments d WHERE l.location_id = d.location_id GROUP BY country_id HAVING COUNT(*)>2#不等值连接 #依据job_grades给每个员工工资分等级 SELECT e.salary ,jg.grade_level FROM employees e,job_grades jg WHERE e.salary BETWEEN jg.lowest_sal AND jg.highest_sal ORDER BY e.salary ASC	#自连接  #选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式 # employees Emp manager Mgr SELECT e.last_name as 'employees' ,e.employee_id as 'Emp' ,m.last_name as' manager',m.employee_id as'Mgr' FROM employees e,employees m WHERE e.manager_id =m.employee_id

外连接:

外链接的查询结果=主表中的所有记录+从表匹配值(ifnull 则显示null)

  • 左外连接 left join 左边的是主表

  • 右外连接 right join 右边的是主表

  • 全外连接: FULL JOIN (Mysql不支持)

    •  select <select_list> from A full join B on A.key=B.key where A.key is null or b.key is null
sql99语法
select -- 查询列表from 表1 -- [连接类型]join 表2on 连接条件 --where 筛选条件
#查询beauty中男朋友情况SELECT g.`name` ,b.id,b.boyNameFROM beauty g LEFT JOIN boys bon g.boyfriend_id =b.id#查询哪一个部门没有员工SELECT d.* ,e.employee_id,e.manager_idFROM departments d LEFT JOIN employees eon d.department_id = e.department_idWHERE e.manager_id is null#查询部门名为 SAL,IT的员工信息SELECT e.*,d.department_nameFROM departments d RIGHT JOIN employees eon d.department_id = e.department_idWHERE d.department_name in('SAL','IT')

交叉连接:

即笛卡尔乘积结果


子查询:

分类:

  1. 标量子查询 - 结果集只有一行一列
  2. 列子查询 -一列多行 (单一字段)
  3. 行子查询 -一行多列(可以多行多列,多字段)
  4. 表子查询 -多行多列

位置:

  1. select +标量子查询
  2. from +表子查询
  3. where /having +(标量+列查询+行)
  4. exists

where /having :

  • 标量子查询
  • 列子查询
  • 行子查询

特点:

  • 标量查询 搭配 单行操作符 > < <> >= <=
  • 列子查询 搭配 多行操作符 in ,any ,some ,all
标量子查询:
#返回job_id与141号员工相同,salary比143号员工多的 员工姓名,job_id,和工资SELECT last_name,job_id,salaryFROM employeesWHERE job_id=(	SELECT job_id	FROM employees	WHERE employee_id=141) AND salary >(	SELECT salary	FROM employees	WHERE employee_id=143)#返回公司工资最少的员工信息,last_name,job_id,salarySELECT last_name,job_id,salaryFROM employeesWHERE salary =(	SELECT MIN(salary)	FROM employees)
列子查询(多行):

any:和子查询返回的某一个比较

In/not in : 等于列表中的任意一个

#返回location_id是1400或1700的部门中所有员工姓名SELECT last_nameFROM employeesWHERE department_id in (	SELECT department_id	FROM departments	WHERE location_id in (1400,1700))#返回其他工种比job_id为'IT_PROG'工种任一工资低的员工的员工号,姓名,job_id,以及salarySELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary < ANY(	SELECT salary	FROM employees	WHERE job_id = 'IT_PROG') AND job_id <>'IT_PROG';
行子查询:
#返回员工编号最小,工资最高的信息.SELECT * FROM employeesWHERE (employee_id,salary)=(	SELECT MIN(employee_id),MAX(salary)	FROM employees)

select:

标量子查询
#查询每个部门的员工个数,显示departments表SELECT d.* ,(	SELECT COUNT(*)	FROM employees e	WHERE d.department_id=e.department_id) 统计FROM departments d -- 27/*错误代码 why?SELECT d.* ,(	SELECT COUNT(*)	FROM employees e	WHERE d.department_id=e.department_id) 'ANS'FROM employees e,departments d2889*/

from:

#查询每个部门的平均工资的工资等级SELECT ag_dep.*,g.grade_levelFROM (	SELECT AVG(salary) as ag,department_id	FROM employees	GROUP BY department_id)ag_depINNER JOIN job_grades g -- 直接起别名 如果 AS 'g'则会报错ON ag_dep.ag BETWEEN g.lowest_sal AND g.highest_sal

exists(相关子查询):

/*语法:EXISTS(完整的查询语句)返回:0或1*/#查询没有女朋友的boySELECT bo.* FROM boys boWHERE NOT EXISTS (	SELECT boyfriend_id	FROM beauty g	WHERE bo.id =g.boyfriend_id)#连接查询SELECT b.*FROM boys b LEFT JOIN beauty gon b.id= g.boyfriend_idWHERE g.name is NULL

-练习-

-- 1. 查询和 Zlotkey 相同部门的员工姓名和工资SELECT last_name,salary,department_idFROM employeesWHERE department_id=(		SELECT department_id		FROM employees		WHERE last_name ='Zlotkey')#34-- 2. 查询工资比公司平均工资高的员工的员工号,姓名和工资SELECT employee_id,last_name,salaryFROM employeesWHERE salary>(	SELECT AVG(salary)	FROM employees)#51-- 3. 查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资SELECT employee_id,last_name,salaryFROM (	SELECT AVG(e.salary) ag_sal,e.department_id eid	FROM employees e	GROUP BY department_id) tab1 INNER JOIN employees e1on e1.department_id = tab1.eidWHERE e1.salary >tab1.ag_salORDER BY e1.employee_id #38-- 4. 查询和姓名中包含字母 u 的员工在相同部门的员工的员工号和姓名SELECT employee_id,last_nameFROM employeesWHERE department_id in(	SELECT DISTINCT department_id	FROM employees 	WHERE last_name LIKE '%u%')#96-- 5. 查询在部门的 location_id 为 1700 的部门工作的员工的员工号SELECT employee_idFROM employeesWHERE department_id in(	SELECT department_id	FROM departments	WHERE location_id=1700)#18-- 6. 查询管理者是 King 的员工姓名和工资SELECT last_name,salaryFROM employees eWHERE manager_id in(	SELECT employee_id	FROM employees	WHERE last_name ='K_ing')#14-- 7. 查询工资最高的员工的姓名,要求 first_name 和 last_name 显示为一列,列名为 姓.名SELECT CONCAT(first_name,last_name) as "姓名"FROM employeesWHERE salary =(	SELECT MAX(salary)	FROM employees)

分页查询:

select -- 查询列表from 表1 [type] join 表2-- [连接类型] on 连接条件 --where 筛选条件group by 分组字段having 分组后筛选order by 排序字段limit offset ,size;offset = (page-1)*size

DML:

data manipulation language

插入:

insert into 表名(列名,...) values(值1) -- 一insert into 表名 set 字段=值,字段=值,... -- 二#1 插入值类型与列类型一致 ,可调换顺序 ,不可为null的值必须插入值#2 方式一支持 一次插入多行 + 子查询

修改:

update 表名 set 字段=值,字段=值 【where 筛选条件】; -- 1-- 2 多表更新update 表1 别名 left|right|inner join 表2 别名 on 连接条件 set 字段=值,字段=值 【where 筛选条件】;

删除:

delete from 表名 【where 筛选条件】【limit 条目数】truncate table 表名#多表删除 实例delete gfrom beauty ginner join boys b on g.boyfriends_id = b.idwhere b.boyName='xxx';

delete 与 truncate 区别:

  1. truncate删除后,如果再插入,标识列从1开始
    delete删除后,如果再插入,标识列从断点开始
  2. delete可以添加筛选条件
    truncate不可以添加筛选条件
  3. truncate效率较高
  4. truncate没有返回值
    delete可以返回受影响的行数
  5. truncate不可以回滚
    delete可以回滚

DDL:

data defination language

库:

#创建CREATE DATABASE if NOT EXISTS boos;#重命名RENAME DATABASE boos TO books;#设置字符集ALTER DATABASE boos CHARACTER SET gbk;#删除库DROP DATABASE boos;

表:

drop table if 表名 existscreate table 【if not exists】 表名(	字段名 字段类型(长度) 【约束】,	字段名 字段类型 【约束】,	....	字段名 字段类型 【约束】 )create table if not exists books(	id INT(2) AUTO_INCREMENT,	bname VARCHAR(20), 	privce DOUBLE ,	PRIMARY KEY (id))

1.添加列
alter table 表名 add column 列名 类型 【first|after 字段名】;

ALTER TABLE books ADD COLUMN author INT;

2.修改列的类型或约束
alter table 表名 modify column 列名 新类型 【新约束】;

alter table books modify column name DOUBLE UNIQUE;

3.修改列名
alter table 表名 change column 旧列名 新列名 类型;

同时可修改类型

alter table books change bname name varchar(30);

4 .删除列
alter table 表名 drop column 列名;

ALTER TABLE books DROP COLUMN NAME

5.修改表名
alter table 表名 rename 【to】 新表名;

alter table books rename to new_books;

6.表的复制

#1、复制表的结构create table 表名 like 旧表;CREATE TABLE copyed LIKE new_books#2、复制表的结构+数据create table 表名 select 查询列表 from 旧表【where 筛选】;CREATE TABLE copy_booksSELECT * FROM new_books WHERE 1=1;

数据类型:

整型:tinyint、smallint、mediumint、int/integer、bigint

  • ①都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号(没有符数)
  • 长度
    • 存放数据大小依据数据类型已经确定. 而长度代表显示的最大宽度,而不够则用左边0填充,但需搭配zerofill,并且默认为无符号整型

浮点型:

  • 定点数:decimal(M,D)
  • 浮点数: float(M,D) , double(M,D)

M = 整数位数+小数位数

D =小数位数

Mysql8中: 如果D=3,插入12.456则会四舍五入为12.5

字符型:char、varchar、binary、varbinary、enum、set、text、blob

char:char(M),最大长度不能超过M,其中M可以省略,默认为1

varchar:可变长度的字符,写法为varchar(M),最大长度不能超过M,其中M不可以省略

日期型:year,date日期 ,time时间, datetime 日期时间

6ZNBuT.png

约束:

  • NOT NULL:非空,该字段的值必填
  • UNIQUE:唯一,该字段的值不可重复
  • DEFAULT:默认,该字段的值不用手动插入有默认值
  • CHECK:检查,mysql不支持
  • PRIMARY KEY:主键,该字段的值不可重复并且非空 unique+not null
  • FOREIGN KEY:外键,用于限制两个表的关系,在从表添加外键约束,用于引用主表某列的值

主键,外键:

主键:一个表至多有一个主键,但可以有多个唯一

外键:

  1. 在从表设置外键关系
  2. 从表外键列类型 和 主表的关联列类型要求一致或兼容
  3. 主表的关联列必须是一个key(主键,唯一)
  4. 插入数据 ,先插入主表,再删除从表
    • 删除数据时,先删除从表,再删除主表
支持类型是否可起约束名
列级约束外键约束没有效果不可以
表级约束除了非空和默认可以,但对主键无效
create table 表名( #列级约束	字段名 字段类型 not null,#非空	字段名 字段类型 primary key,#主键	字段名 字段类型 unique,#唯一	字段名 字段类型 default 值,#默认 #表级约束	constraint 约束名 foreign key(字段名) references 主表(被引用列), constraint fk_stu_major foreign key(majorid) references major(id),  constraint 约束名 [约束](字段), -- 约束名 = 别名 ,变量 constraint pk primary key(id))show INDEX FROM 表名

标识列:

自增长列:

  • 一个表至多有一个自增长列
  • 自增长列只能支持数值型
  • 自增长列必须为一个key

TCL

Transaction Control Language 事务控制语言

事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行

事务特点:

  • A: Atomicity 一个事务是不可再分割的整体,要么都执行要么都不执行
  • C: Consistency 一个事务可以使数据从一个一致状态切换到另外一个一致的状态
  • I:Isolation 一个事务不受其他事务的干扰,多个事务互相隔离的
  • D:Durability 一个事务一旦提交了,则永久的持久化到本地
set autocommit=0start transaction delete from account where id =25savepoint a #设置保存点delete from account where id =28rollback to a; #回滚到a

重点在spring中介绍事务操作

其他

视图:

what:虚拟表,通过表动态生成的数据 ,只保存sql逻辑不保存结果

where:

  • 多个地方用到同样的查询结果
  • 使用的sql语句比较复杂
#创建create VIEW myview1 AsSELECT last_name,department_name,job_titleFROM employees ejoin departments d on e.department_id = d.department_idjoin jobs j on j.job_id = e.job_idSELECT * from myview1 where last_name like '%a%'#修改create or replace view [视图名]as[查询语句]#删除 drop view [视图名]

变量:

系统变量:

  • 全局变量:服务器层面上的,必须拥有super权限才能为系统变量赋值,作用域为整个服务器,也就是针对于所有连接(会话)有效

  • 会话变量:服务器为每一个连接的客户端都提供了系统变量,作用域为当前的连接(会话)

  •  show 【global|session 】variables like ''; set 【global|session 】 变量名=值

自定义变量:

  • 用户变量:针对于当前连接(会话)生效

    •  set @变量名=值; select @变量名; set @m =1; set @n = 2; set @sum = @m +@n; select @sum;
  • 局部变量:仅仅在定义它的begin end中有效

    •  declare 变量名 类型 【default 值】;

存储过程:

what :一组预先编译号的SQL语句集合

why use:

  • 提高代码的重用性
  • 简化操作
  • 减少编译次数和数据库服务器连接次数
create procedure 存储过程名(参数列表)begin[sql 语句]end参数列表:参数模式 参数名 参数类型In stuname varchar(20)
参数模式:
  • in:该参数可作为输入
  • out:该参数可以作为返回值
  • inout:输入+返回值

调用: call 存储过程名(实参列表)

delimiter 结束标记:

delimiter $ -- 任意

案例:

IN:

CREATE DEFINER=`root`@`localhost` PROCEDURE `logincheck`(IN username VARCHAR(20),IN password VARCHAR(20))BEGIN	#Routine body goes here...	DECLARE result VARCHAR(20) DEFAULT '';	SELECT COUNT(*) INTO result	FROM admin	WHERE admin.username =username AND	admin.`password` =password;	SELECT IF (result>0 ,'成功','失败');ENDCALL logincheck('admin1','123')#JDBC中db.connect( "db_host" ).execute_sql( "CALL logincheck('admin1','123')" );

OUT:

CREATE DEFINER=`root`@`localhost` PROCEDURE `findboy`(In butyName VARCHAR(20),OUT boyName VARCHAR(20))BEGIN	#Routine body goes here...	SELECT bo.boyName INTO boyName	FROM boys bo	JOIN beauty g on bo.id = g.boyfriend_id	WHERE g.name = butyName;ENDCALL findboy('小昭',@boyName);SELECT @boyName

函数:

区别:

  • 存储过程:可以有0个返回,也可以有多个返回 ,批量操作
  • 函数: 有且仅有一个1个 , 适合处理数据返回结果
CREATE FUNCTION `函数名`(参数列表)	RETURNS 返回类型BEGIN	#Routine body goes here...		RETURN 0;END;--------------------CREATE DEFINER = CURRENT_USER FUNCTION ``()	RETURNS integerBEGIN	#Routine body goes here...		RETURN 0;END;select 函数名(参数列表)

DCL:

data control language

流程控制结构:

分支:

CREATE PROCEDURE casse(IN score INT)BEGIN	CASE 	WHEN scorce>=90 THEN		SELECT 'A';	WHEN scorce>=90 THEN		SELECT 'B';	ELSE		SELECT 'C';	END CASE;END;#---------------------------------CREATE PROCEDURE casse(IN score INT)BEGIN IF search_condition THEN	statement_list	ELSEIF search_condition THEN	statement_listELSE	statement_listEND IF;END;#-------------循环-------------------CREATE PROCEDURE casse(IN cnt INT)BEGINDECLARE i INT DEFAULT 0;WHILE i<=cnt DO	INSERT into admin(username,`password`) VALUES(xxx,xxx)END WHILE;END;

链接:https://pan.baidu.com/s/1EeBnOhgMSJjvn35RZtz5sw
提取码:3mji
复制这段内容后打开百度网盘手机App,操作更方便哦









原文转载:http://www.shaoqun.com/a/606609.html

跨境电商:https://www.ikjzd.com/

万色:https://www.ikjzd.com/w/2382

csa认证:https://www.ikjzd.com/w/904


Mysql基本语法:文末有mysql资料执行顺序:from->join->on->where->groupby->avgmax..->having->select->orderbySQL语言分类:DQL:数据查询语言DML:数据操作语言DDL:数据定义语言DCL:数据控制语言DQLdataquerylanguageSELECT:可以理解为Java的S
敏思达:https://www.ikjzd.com/w/2304
cima是什么:https://www.ikjzd.com/w/1372
haofang:https://www.ikjzd.com/w/1046
亚马逊上"医用口罩"价格上涨3-4倍,平台警告哄抬物价的卖家!:https://www.ikjzd.com/home/116737
玩转亚马逊A+页面,提高Listing转化率:https://www.ikjzd.com/home/14645
eBay调整SpeedPAK中国大陆至西班牙收寄服务:https://www.ikjzd.com/home/132124

受益于亚马逊的退货计划,Kohl’s 新增了200万客户

科尔(Kohl)负责人表示:"随着1月假期后流量的增加,我们尤其看到了这一点。到2020年,由于亚马逊退货计划,我们可以将至少200万新的独特客户归功于科尔购物,其中三分之一是千禧一代。虽然合作的细节是保密的,但我们仍然看到这对销售和利润都有促进作用。"

 

美国国家零售联合会(National Retail Federation)预测,随着COVID-19疫苗的继续推出,2021年的零售销售将增长6.5%至8.2%

 

科尔公司早些时候公布的第四季度盈余和销售额均超出了预期。

 

这家百货商店零售商的重点是在架子和架子上摆上醒目的标签,为目前有货并在不久的将来推出的多个品牌取名。

 

卡尔文·克莱恩(Calvin Klein)的内衣和休闲服将在秋季进入600家商店和电子商务网站Eddie Bauer的户外装备将在500家商店和在线商店推出。

 

同时,科尔(Kohl)自己的运动休闲品牌FLX将于本月推出男女装。

 

作为公司转型的一部分,科尔一直专注于商品阵容。去年五月,该公司宣布将终止八个品牌,此后将其注意力转移到发展女装和运动服业务等领域。

 

与美容零售商丝芙兰(Sephora)的合作伙伴关系今年也即将到来,盖斯称此举是"改变游戏规则的人"。

 

负责人表示"它不仅会以可观的利润推动显着的美容销售增长,还将对整个商店产生光环效应,并推动我们其他类别的销售,包括对我们的女性业务产生积极影响"

 

分析师对科尔的前景越来越乐观"我们喜欢Kohl继续专注于活跃美容,作为枢纽的商店和柔软的家庭商品,并结合公司引人注目的忠诚度计划和更敏捷的库存管理,"

 

即使获得了所有利好消息,Kohl's仍然面临着一群激进投资者的挑战,他们说"糟糕的零售执行力"正在伤害着公司。

 

GlobalData的常务董事尼尔·桑德斯(Neil Saunders)表示,"完全拒绝了科尔的经营不善的说法。" 但是,GlobalData确实提出了一个问题,即科尔的所作所为是否足以成长。

 

他写道:"增长预测和销售恶化引发了科尔的计划是否雄心勃勃或变革性的问题。该公司一直积极主动,勤奋工作,并寻求合理的增长途径,例如发展更大的运动服业务,投资系统以支持全渠道,与亚马逊以及最近与丝芙兰建立合作伙伴关系……也就是说,我们认为科尔的需求加快行动速度,尤其是在提高商店相关性方面。"





原文转载:http://www.shaoqun.com/a/606603.html

跨境电商:https://www.ikjzd.com/

关键词分析工具:https://www.ikjzd.com/w/1968

预售:https://www.ikjzd.com/w/889


科尔(Kohl)负责人表示:"随着1月假期后流量的增加,我们尤其看到了这一点。到2020年,由于亚马逊退货计划,我们可以将至少200万新的独特客户归功于科尔购物,其中三分之一是千禧一代。虽然合作的细节是保密的,但我们仍然看到这对销售和利润都有促进作用。"美国国家零售联合会(NationalRetailFederation)预测,随着COVID-19疫苗的继续推出,2021年的零售销售将增长6.5%
6pm:https://www.ikjzd.com/w/317
俄罗斯灰色清关:https://www.ikjzd.com/w/1409
虚拟信用卡:https://www.ikjzd.com/w/1055
3分钟读懂FBA新政策,不让你的旺季销量输在物流上:https://www.ikjzd.com/home/13304
(深度干货)亚马逊站外引流的27种方法技巧:https://www.ikjzd.com/home/9347
社交电商火爆当下,跨境电商社交化愈演愈烈:https://www.ikjzd.com/home/19546

华为 Java 编程军规 !

1、引言

这个标准是衡量代码本身的缺陷,也是衡量一个研发人员本身的价值。华为作为一家全球化的 IT 公司,十几万员工,无论是人事管理,还是代码管理,都是一件不容易的事情,没有规范的约束,想想都是件可怕的事情。下面挑选了一些网上流传的编程规范,一起来学习下,以下内容不涉及基础的语法规范(请见 Refer),更侧重于一些编程习惯,如何提高程序的健壮性、可维护性等。(PS:以下内容未经官方考证,如阅读者出现不适,请选择立即关闭本页 -_-||| )

2、军规简介

  • 军规一:【避免在程序中使用魔鬼数字,必须用有意义的常量来标识。】

  • 军规二:【明确方法的功能,一个方法仅完成一个功能。】

  • 军规三:【方法参数不能超过5个】

  • 军规四:【方法调用尽量不要返回null,取而代之以抛出异常,或是返回特例对象(SPECIAL CASE object,SPECIAL CASE PATTERN);对于以集合或数组类型作为返回值的方法,取而代之以空集合或0长度数组。】

  • 军规五:【在进行数据库操作或IO操作时,必须确保资源在使用完毕后得到释放,并且必须确保释放操作在finally中进行。】

  • 军规六:【异常捕获不要直接catch (Exception ex) ,应该把异常细分处理。】

  • 军规七:【对于if „ else if „(后续可能有多个else if …)这种类型的条件判断,最后必须包含一个else分支,避免出现分支遗漏造成错误;每个switch-case语句都必须保证有default,避免出现分支遗漏,造成错误。】

  • 军规八:【覆写对象的equals()方法时必须同时覆写hashCode()方法。】

  • 军规九:【禁止循环中创建新线程,尽量使用线程池。】

  • 军规十:【在进行精确计算时(例如:货币计算)避免使用float和double,浮点数计算都是不精确的,必须使用BigDecimal或将浮点数运算转换为整型运算。】

3、军规说明

  • 军规一:【避免在程序中使用魔鬼数字,必须用有意义的常量来标识。】 说明:是否是魔鬼数字要基于容易阅读和便于全局替换的原则。0、1作为某种专业领域物理量枚举数值时必须定义常量,严禁出现类似NUMBER_ZERO的"魔鬼常量"。

  • 军规二:【明确方法的功能,一个方法仅完成一个功能。】 说明:方法功能太多,会增加方法的复杂度和依赖关系,不利于程序阅读和将来的持续维护,无论是方法还是类设计都应符合单一职责原则。

  • 军规三:【方法参数不能超过5个】 说明:参数太多影响代码阅读和使用,为减少参数,首先要考虑这些参数的合理性,保持方法功能单一、优化方法设计,如果参数确实无法减少,可以将多个参数封装成一个类(对象),同时考虑在新的类(对象)中增加相应的行为,以期更符合OOP。

  • 军规四:【方法调用尽量不要返回null,取而代之以抛出异常,或是返回特例对象(SPECIAL CASE object,SPECIAL CASE PATTERN);对于以集合或数组类型作为返回值的方法,取而代之以空集合或0长度数组。】 说明:返回null会增加不必要的空指针判断,遗漏判断也会导致严重的NullPointerException错误。

  • 军规五:【在进行数据库操作或IO操作时,必须确保资源在使用完毕后得到释放,并且必须确保释放操作在finally中进行。】 说明:数据库操作、IO操作等需要关闭对象必须在try -catch-finally 的finally中close(),如果有多个IO对象需要关闭,需要分别对每个对象的close()方法进行try-catch,防止一个IO对象关闭失败其他IO对象都未关闭。

  • 军规六:【异常捕获不要直接 catch(Exception ex) ,应该把异常细分处理。】 说明:catch (Exception ex)的结果会把RuntimeException异常捕获,RuntimeException是运行期异常,是程序本身考虑不周而抛出的异常,是程序的BUG,如无效参数、数组越界、被零除等,程序必须确保不能抛出RuntimeException异常,不允许显示捕获RuntimeException异常就是为了方便测试中容易发现程序问题。

  • 军规七:【对于if „ else if „(后续可能有多个elseif …)这种类型的条件判断,最后必须包含一个else分支,避免出现分支遗漏造成错误;每个switch-case语句都必须保证有default,避免出现分支遗漏,造成错误。】

  • 军规八:【覆写对象的equals()方法时必须同时覆写hashCode()方法。】 说明:equals和hashCode方法是对象在hash容器内高效工作的基础,正确的覆写这两个方法才能保证在hash容器内查找对象的正确性,同时一个好的hashCode方法能大幅提升hash容器效率。

  • 军规九:【禁止循环中创建新线程,尽量使用线程池。】

  • 军规十:【在进行精确计算时(例如:货币计算)避免使用float和double,浮点数计算都是不精确的,必须使用BigDecimal或将浮点数运算转换为整型运算。】 说明:浮点运算在一个范围很广的值域上提供了很好的近似,但是它不能产生精确的结果。二进制浮点对于精度计算是非常不适合的,因为它不可能将0.1——或者10的其它任何次负幂精确表示为一个长度有限的二进制小数。

4、有关开发效率和协作的几点建议与心得体会

今天看到某同学写给团队成员的一封邮件,发现比较通用,分享出来吧:

1、小提交:

把大的任务拆分成多个独立小任务,每完成小任务确保无 Bug 后就可以提交合并到主分支甚至发布;频繁提交有利于自己把控项目进度、降低风险、同其他人协作和代码 Review ; 每天可以提交合并多次。每个小任务是 1-2 个小时可以完成的粒度,最大的一天完成。并行做多个任务的时候,优先做最短时间能够实现的任务。

2、命名规范:

尽量避免无意义的字符做变量 比如 a, b, t 。可以逐步改善,可以参考 能够用简单方式实现的功能,不引入复杂的类,对象,避免不必要的 new 对象,避免引入不必要的泛型、线程。开发初期冗余大于抽象和依赖。避免自己重新实现比较通用的组件和函数。调研多种实现方式的时候,选用做简单的实现方式。尽量少写代码。

4、Web 工程尽量避免在应用内部保存"状态",这样可以适应频繁发布、重启无影响。

5、善于用打日志的方式调试,在程序关键点打日志。尽量少用断点方式,日志方式可以批量调试一批功能,效率相对高。

6、避免一屏显示不下的超大函数。

7、添加必要、简洁的注释:

循环中的 continue, break 尽量加上单行注释;尽量避免非函数结尾的 return,必要的时候加注释。类自动生成 toString() 方法,方便调试和打日志。

8、不把自己局限到做某个功能,每个人都是整个项目的 Owner ,尽量交叉 Review ,交叉开发。

9、遇到问题及时和其他人沟通,避免浪费时间。

10、从最终产品的目标审视自己细小的设计,熟悉自己负责部分的上下游代码。时刻关注最终产品(Web 界面和日志),发现 Bug 和可以改善的地方。









原文转载:http://www.shaoqun.com/a/606597.html

跨境电商:https://www.ikjzd.com/

tradekey:https://www.ikjzd.com/w/1630

俄罗斯灰色清关:https://www.ikjzd.com/w/1409


1、引言这个标准是衡量代码本身的缺陷,也是衡量一个研发人员本身的价值。华为作为一家全球化的IT公司,十几万员工,无论是人事管理,还是代码管理,都是一件不容易的事情,没有规范的约束,想想都是件可怕的事情。下面挑选了一些网上流传的编程规范,一起来学习下,以下内容不涉及基础的语法规范(请见Refer),更侧重于一些编程习惯,如何提高程序的健壮性、可维护性等。(PS:以下内容未经官方考证,如阅读者出现不适
mav:https://www.ikjzd.com/w/2414
易联通:https://www.ikjzd.com/w/1854.html
跨国采购网:https://www.ikjzd.com/w/2270.html
站外引流太难?电子邮件营销了解一下:https://www.ikjzd.com/home/9150
亚马逊卖家如何用Facebook打广告,为店铺引流?:https://www.ikjzd.com/home/23245
土耳其这片浪漫国土,中国跨境卖家们快来围观一下!:https://www.ikjzd.com/home/9913

眼睛有皱纹怎么消除

核心提示:在每天洗完脸之后,要用含有胶原蛋白或者玻尿酸成分的眼霜或者眼部精华液,对眼睛周围进行涂抹按摩。这样的方式可以给眼睛周围的皮肤增加营养,也可以使皮肤细胞得到活化,只要细胞恢复弹性,面部的小细纹就会消除,选择护肤品的时候一定要选择正规厂家生产的,因为一些假冒伪劣的产品会导致皮肤过敏。

人的眼睛周围是很容易生出皱纹的,因为人的眼部皮肤比其他部位的皮肤要更敏感更娇嫩,而且孕检率比较高的年代,脸部皮肤也容易干燥,人在笑的时候眼睛周围就会出现褶皱,这些原因都会导致眼睛周围皱纹比较多,那么今天就来带大家了解一下眼睛有皱纹怎么消除?

消除眼部皱纹方法一:面部皮肤护理

在每天洗完脸之后,要用含有胶原蛋白或者玻尿酸成分的眼霜或者眼部精华液,对眼睛周围进行涂抹按摩。这样的方式可以给眼睛周围的皮肤增加营养,也可以使皮肤细胞得到活化,只要细胞恢复弹性,面部的小细纹就会消除,选择护肤品的时候一定要选择正规厂家生产的,因为一些假冒伪劣的产品会导致皮肤过敏。

消除眼部皱纹方法二:激光祛皱

激光去除皱纹的效果非常好,可以抚平面部表层的小细纹,即使是川字纹和法令纹这些深纹通过激光的方式都可以去除掉,只要在做完激光祛皱纹之后做好皮肤护理,不要让皮肤过早的碰触到水,也不要吃辛辣刺激的食物,这样做完激光祛皱不会留下任何疤痕,可以在两周左右看到祛皱的效果。


消除眼部皱纹方法三:玻尿酸填充

少量的玻尿酸填充可以使眼睛周围的小细纹彻底消除,玻尿酸是一种可以增强皮肤细胞活性的营养物质,这种营养液在年龄比较小时候是可以靠自身的新陈代谢的,但是到了一定年纪之后,人自己的身体就不能再生成玻尿酸了,所以通过一些提取出来的营养物质进行补充,可以使面部小细纹消失。

看了上面的介绍,相信大家都明白了,眼睛有皱纹怎么消除?希望所有眼睛有皱纹的朋友,都能通过正确的方式来去皱,平时在饮食上多吃一些含有胶原蛋白的食物和维生素C的食物,也有助于去除面部的皱纹。


原文转载:http://lady.shaoqun.com/a/267507.html

跨境电商:https://www.ikjzd.com/

Zozo:https://www.ikjzd.com/w/2180

aca:https://www.ikjzd.com/w/1371


核心提示:在每天洗完脸之后,要用含有胶原蛋白或者玻尿酸成分的眼霜或者眼部精华液,对眼睛周围进行涂抹按摩。这样的方式可以给眼睛周围的皮肤增加营养,也可以使皮肤细胞得到活化,只要细胞恢复弹性,面部的小细纹就会消除,选择护肤品的时候一定要选择正规厂家生产的,因为一些假冒伪劣的产品会导致皮肤过敏。 人的眼睛周围是很容易生出皱纹的,因为人的眼部皮肤比其他部位的皮肤要更敏感更娇嫩,而且孕检率比较高的年代,脸部
海维:https://www.ikjzd.com/w/1891
bsci 认证:https://www.ikjzd.com/w/2339
logo免费制作:https://www.ikjzd.com/w/1998
姐夫"抢滩"东南亚岛国,下一片新蓝海?:https://www.ikjzd.com/home/108492
过去几个月里,又有一款亚马逊产品被网友抵制!:https://www.ikjzd.com/home/133674
wish加拿大蓝海产品类目:https://www.ikjzd.com/tl/107558

身上水肿的原因是什么 什么原因会导致水肿

核心提示:水肿的问题其实是非常让人头疼的一个问题,而女性群体更是水肿问题的高发群体。然而作为天生爱美的女性朋友来说,她们必然是不会喜欢自己臃肿的样子的,为此她们一定会想方设法找出原因,再针对性地应对改善的。

水肿的问题其实是非常让人头疼的一个问题,而女性群体更是水肿问题的高发群体。然而作为天生爱美的女性朋友来说,她们必然是不会喜欢自己臃肿的样子的,为此她们一定会想方设法找出原因,再针对性地应对改善的。那身上水肿的原因是什么?什么原因会导致水肿?下面我们一起来详细了解一下!

身上水肿的原因是什么?

(1)生理因素引起的水肿

说到身上水肿的原因是什么这个问题,日常生活中一些女性朋友在生理期来临之前一个星期左右,身体会出现某些部位水肿的问题,其实出现这种情况是一种正常的生理现象,一般来说等到生理期过去之后症状就会有所好转,这是体内激素水平变化引起的。如果出现这种问题,女性朋友不要过分担忧,这个时候建议不要再食用一些辛辣具有刺激性味的食物,尽量做到低脂低盐的饮食即可。

(2)久坐导致血液循环不畅

身上水肿的原因是什么?长时间久坐就可能会使自身下肢血液循环不畅,增加自身出现水肿问题的几率,会严重影响到个人的外表形象。建议大家在日常久坐两小时之后一定要加强必要的有氧运动锻炼,在运动的过程中可以有效的促进体内的新陈代谢,都可以帮助自身很好的促进体内的血液循环。

(3)日常摄入盐分过多


其实身上出现浮肿问题也与个人的饮食也有很大的关系,如果我们在日常特别喜欢吃一些重口味的食物,例如长期食用大量的盐分,就可能会导致体内钠元素摄入过多,增加自身出现面部浮肿或者是身体某些部位浮肿问题的几率。建议大家日常一定要养成一个良好的饮食习惯,尽量少食用一些辛辣具有刺激性味的食物,日常多喝一些热水,有助于促进体内的新陈代谢。


以上就是关于身上水肿的原因是什么的相关内容介绍,其实导致身上水肿的原因是非常多的,大家一定要根据自己的实际情况来合理应对处理,切不可吊儿郎当的,最终导致不良风险损害的出现。


原文转载:http://lady.shaoqun.com/a/267489.html

跨境电商:https://www.ikjzd.com/

文化衫事件:https://www.ikjzd.com/w/1932

retriever:https://www.ikjzd.com/w/773


核心提示:水肿的问题其实是非常让人头疼的一个问题,而女性群体更是水肿问题的高发群体。然而作为天生爱美的女性朋友来说,她们必然是不会喜欢自己臃肿的样子的,为此她们一定会想方设法找出原因,再针对性地应对改善的。 水肿的问题其实是非常让人头疼的一个问题,而女性群体更是水肿问题的高发群体。然而作为天生爱美的女性朋友来说,她们必然是不会喜欢自己臃肿的样子的,为此她们一定会想方设法找出原因,再针对性地应对改善
amazon go:https://www.ikjzd.com/w/67
史泰博办公用品:https://www.ikjzd.com/w/2112
声网:https://www.ikjzd.com/w/2176
一张"报关单"牵出跨境制假售假大案,案值近18亿元!:https://www.ikjzd.com/home/111024
亚马逊运营QA集锦(904-913):https://www.ikjzd.com/home/126079
黑科技新升级,亚马逊查库存3.0版(附:免费插件):https://www.ikjzd.com/tl/91074

能瘦身的办法有哪些

核心提示:经历过减肥的人一定知道,想减肥瘦身方法真的很重要,盲目减肥只会浪费自己的时间以及精力,甚至可能会浪费人民币。只有正确瘦身的办法,长期坚持下来才能收获真正的减肥成果,主要也能减少走弯路,避免浪费时间。

经历过减肥的人一定知道,想减肥瘦身方法真的很重要,盲目减肥只会浪费自己的时间以及精力,甚至可能会浪费人民币。只有正确瘦身的办法,长期坚持下来才能收获真正的减肥成果,主要也能减少走弯路,避免浪费时间。

有助于瘦身的办法推荐:

1、必须参与运动!想管理身材,每周必须要通过运动燃烧不低于2000大卡的热量才有机会完成个人瘦身目标。对于运动项目的选择没有太高要求,完全根据个人喜好以及个人运动能力,采取一定运动方式,比如每天快走5~6公里,或者每天慢跑30~60分钟,将运动强度从简单到难,慢慢提升,只要身体完全适应就没有问题。运动强度、速度、时间长度,通通会影响到运动对瘦身的作用。不管平时有没有运动习惯,只要需要瘦身都必须要开始计划参与运动。


2、为自己设定减肥目标,比如今天要运动多长时间?需要消耗多少热量,这些基本要求设定好以后才有利于监督自己的行为,如果当天没有完成,是表选择时间进行补充,千万不要有任何拖延行为。

3、成功瘦身控制体重,管理身材,在饮食方面也要做好规律化,比如规律每天的用餐时间,包括每天饮食结构该怎么安排,这些都是瘦身成功的关键因素。千万不要出现过度节食这种行为,不吃只会为身体带来负面影响,只要保证规律用餐,比如每天三餐的时间要固定,饮食摄入量要固定,饮食结构安排保证以清淡为主,做到热量低脂肪的要求。每天15:00给我安排要有蔬菜、有肉、有水果、有主食,不要挑食,不要偏食,每种食物营养成分均衡搭配,能保证健康为基础的条件下瘦身减肥。

有助于瘦身的办法,主要是在饮食和运动这两方面,当然作息时间良好,情绪同样会干预到瘦身效果,但是只有将饮食控制到位,将运动锻炼到位才能有机会将体内脂肪消除,达到瘦身目的。


原文转载:http://lady.shaoqun.com/a/267487.html

跨境电商:https://www.ikjzd.com/

递四方:https://www.ikjzd.com/w/1066

vat:https://www.ikjzd.com/w/109


核心提示:经历过减肥的人一定知道,想减肥瘦身方法真的很重要,盲目减肥只会浪费自己的时间以及精力,甚至可能会浪费人民币。只有正确瘦身的办法,长期坚持下来才能收获真正的减肥成果,主要也能减少走弯路,避免浪费时间。 经历过减肥的人一定知道,想减肥瘦身方法真的很重要,盲目减肥只会浪费自己的时间以及精力,甚至可能会浪费人民币。只有正确瘦身的办法,长期坚持下来才能收获真正的减肥成果,主要也能减少走弯路,避免浪
东西网:https://www.ikjzd.com/w/1238
淘粉8:https://www.ikjzd.com/w/1725
sgshop:https://www.ikjzd.com/w/1982
纯干货!速卖通产品上新技巧与快速出单的方法:https://www.ikjzd.com/home/132123
口述:献出初夜后 我进入噩梦游戏噩梦孩子:http://lady.shaoqun.com/m/a/33239.html
跨境电商独立站该怎样有效的研究竞争对手并实现模仿超越!!:https://www.ikjzd.com/home/15708