Linux编译过程

1.安装gcc,g++ 在终端输入以下命令: sudo apt install gcc sudo apt install g++ 就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件类型,调用对应的GUN编译而已。 更准确的说法:gcc调用了C编译器,而g++调用了C++编译器。 gcc和g++的主要区别 1)对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的); 2) 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译; 3)使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL; 4)gcc在编译C文件时,可使用的预定义宏是比较少的; 5)gcc在编译cpp文件时或者g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下: #define __GXX_WEAK__ 1 #define __cplusplus 1 #define __DEPRECATED 1 #define __GNUG__ 4 #define __EXCEPTIONS 1 #define __private_extern__ extern 6)在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个,主要参数: -g - turn on debugging (so GDB gives morefriendly output) -Wall - turns on most warnings -O or -O2 - turn on optimizations

TypeError:‘tuple‘ object is not callable

报错:Type错误:元组不可调用 == 存在元组在调用参数; 出现该错误就要考虑是不是有的地方写成元组了,也就是多半是逗号 “,” 的问题,删除逗号即可! 实例: 存在错误的代码: class Net(nn.Module): def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim): super(Net, self).__init__() self.linear1 = nn.Linear(in_dim, n_hidden_1), self.Relu1 = nn.ReLU(True), self.linear2 = nn.Linear(n_hidden_1, n_hidden_2), self.Relu2 = nn.ReLU(True), self.linear3 = nn.Linear(n_hidden_2, out_dim) def forward(self, x): x = self.linear1(x) x = self.Relu1(x) x = self.linear2(x) x = self.Relu2(x) x = self.linear3(x) return x 报错:Type错误:元组不可调用 == 存在元组在调用参数; 原因:在pytorch中定义网络的时候,将定义的网络层转变成元组了 解决方法:采用逐层定义网络而不是nn.sequential()进行定义,则需要把每一层定义后不添加逗号 正确的代码如下: class Net(nn.Module): def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim): super(Net, self).

Vim修改配色方案

1. 查看本机vim支持的配色方案: - cd /usr/share/vim/vimXX[vim版本、自行替换]/colors && ls *.vim 输出: blue.vim default.vim desert.vim evening.vim morning.vim pablo.vim ron.vim slate.vim zellner.vim darkblue.vim delek.vim elflord.vim koehler.vim murphy.vim peachpuff.vim shine.vim torte.vim 2. 修改~/.vimrc,添加行 colorscheme [配色方案,为步骤1得到的文件名去掉.vim后缀的部分],如添加一行: colorscheme ron 保存退出即可

使用Ajax接收到Servlet返回的boolean类型数据时的字符串比较问题

当servlet向Ajax返回一个boolean类型的数据时,ajax接收到的是一个字符串类型的 ”true“ 或者 ”false“, 但是当我们直接使用ajax接收到的数据去做一个判断时,比如: $.ajax({ url: "xxxx", data: { xxx }, success: function (data) { if ( data == "true" ){ alert( "data = true" ); }else { alert( "data = false" ); } } }); 这时我们会发现无论servlet向ajax返回的时一个true还是一个false,这个请求成功函数中的 if 语句的结果始终为 false。 遇到这种情况时,我们需要将 if 语句里的条件修改为下面的代码就可以。 $.ajax({ url: "xxxx", data: { xxx }, success: function (data) { if ( data.toString().trim() == "true" ){ alert( "data = true" ); }else { alert( "

使用JQuery多次修改单选按钮的选中属性时不生效的解决办法

我定义了一组radio有两个选项: 但当我重复使用 attr("checked",true) 和 attr("checked",false) 来修改这组单选按钮的选中状态时,发现在第一次修改其状态成功以后,第二次执行这条修改选中状态的语句时并没有生效,后来将语句改为prop("checked",true) 和 prop("checked",false) 解决了这个问题 原来的代码 修改后的代码

python解决一元二次方程

题目:求一元二次方程ax*x+b*x+c=0的解 从键盘输入a,b,c的值,分多种情况输出解。 a等于0,b也等于0时,输出“方程无解”;a等于0,b不等于0时,输出“方程有1个解,x= ?”;?表示方程的解a不等于0时,计算判别式d=b*b-4*a*c的值: 若d小于0,输出“方程无实数解”; 若d等于0,解等于-b/2a,输出“方程有两个相同的解,x1=x2=?”;?表示方程的解 若d大于0,用求根公式 求两个解,并比较大小,使x1大于x2,输出“方程有两个实数解, x1=?,x2=?”。?表示方程的解 代码如下: a=float(input("请输入a")) b=float(input("请输入b")) c=float(input("请输入c")) if a==0 and b==0: print("方程无解") elif a==0 and b!=0: print("方程有一个解,x=",-c/b) elif a!=0: d=b*b-4*a*c if d==0: print("方程有一个解,x1=x2=",-b/(2*a)) elif d<0: print("方程无实数解") else: e=b*b-4*a*c x1=(-b+e**0.5)/(2*a) x2=(-b-e**0.5)/(2*a) if x1>x2: print("方程有两个实数解,x1=%.1f,x2=%.1f"%(x1,x2)) else: print("方程有两个实数解,x1=%.1f,x2=%.1f"%(x2,x1)) 这道题就很简单了就是对输入的a,b,c进行if操作去选择它们应该执行的操作。整体的思路就是只用到了选择语句最多就是选择里面再加上了一个选择,是一个比较简单的问题。这个特别适合初学者在掌握选择操作时学习,这个是很经典的选择操作的语句代码之一。 Tips:python里面开根号可以 变量**0.5当然仅限于变量是正数,这样就不用调用math库和sqrt函数了。

C语言——水仙花数

今日笔者突然有了兴致,便写一个很简单的适合于C语言初学者的程序。 水仙花数定义:一个三位数i它的百位十位个位分别为a,b,c。若是i=a^3+b^3+c^3那么该数称为水仙花数。 输出100-999以内的水仙花数 代码如下: #include<stdio.h> int main() { for(int i=100;i<1000;i++) ——循环条件 { int a,b,c; a=i/100; b=(i-100*a)/10; c=i-100*a-10*b; if(i==a*a*a+b*b*b+c*c*c) ——判断语句 printf("%d\t",i); } return 0; } 执行可以得到结果为 153 370 371 407 很简单的程序适合初学者掌握判断循环语句的书写。

Python Qt GUI设计:QPushButton、QRadioButton和QCheckBox按钮类(基础篇—12)

目录 1、QPushButton按钮类 2、QRadioButton按钮类 3、QCheckBox按钮类 在GUI设计中,按钮都是最重要的和常用的触发动作请求的方式,用来与用户进行交互操作。在PyQt中根据不同的使用场景将按钮划分为不同的表现形式。 按钮的基类是QAbstractButton,提供了按钮的通用性功能。但是它不能实例化,必须由其他的按钮类继承QAbstractButton类,来实现不同的功能、不同的表现形式。 常见的按钮类包括:QPushButton、QRadioButton和QCheckBox等。这些按钮类均继承自QAbstractButton类,根据各自的使用场景通过图形展现出来。 QAbstractButton提供的状态如下表所示: QAbstractButton提供的信号如下表所示: 1、QPushButton按钮类 QPushButton类继承自QAbstractButton类,其形状是长方形,文本标题或图标可以显示在长方形上。 QPushButton类是一种命令按钮,可以单击该按钮执行一些命令,或者响应一些事件,常见的有:“确认"、"申请"、"取消"、"关闭"、"是"、"否"等按钮。 QPushButton类中的常用方法如下表所示: 来看看QPushButton按钮类的示例,效果如下所示: 在这个例子中,创建了btn1、btn2、btn3和btn4四个按钮,这四个QPushButton对象被定义为类的实例变量。每个按钮都将clicked信号发送给指定的槽函数,以响应按钮点击事件。 第1个按钮btn1,通过toggle()函数来切换按钮状态。当点击这个按钮时,将clicked信号发送给槽函数btnstate(),通过btn.isChecked来获得按钮是否被点击或释放的状态。还可以通过lambda的方式来传递额外的参数btn1,将clicked信号发送给槽函数whichbtn()。第2个按钮btn2,上面显示一个图标。使用setlcon()方法接收一个QPixmap对象的图像文件作为输入参数。第3个按钮btn3,使用setEnabled()方法来禁用bnt3按钮。第4个按钮btn4,使用setDefault()方法来设置按钮的默认状态。快捷键是“&+文本”(&Download),通过“Alt+D”快捷键来调用槽函数。 实现代码如下所示: import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) layout = QVBoxLayout() self.btn1 = QPushButton("Button1") self.btn1.setCheckable(True) self.btn1.toggle() self.btn1.clicked.connect(lambda:self.whichbtn(self.btn1) ) self.btn1.clicked.connect(self.btnstate) layout.addWidget(self.btn1) self.btn2 = QPushButton('image') self.btn2.setIcon(QIcon(QPixmap("./python.png"))) self.btn2.clicked.connect(lambda:self.whichbtn(self.btn2) ) layout.addWidget(self.btn2) self.setLayout(layout) self.btn3 = QPushButton("Disabled") self.btn3.setEnabled(False) layout.addWidget(self.btn3) self.btn4= QPushButton("&Download") self.btn4.setDefault(True) self.btn4.clicked.connect(lambda:self.whichbtn(self.btn4)) layout.addWidget(self.btn4) self.setWindowTitle("Button demo"

集合,数组,列表,字典,元组有啥区别呀?

关于他们是什么、什么时候用、怎么用的一篇文章。 1.集合 什么是集合? 集合是一个或多个确定的元素构成的整体,集合的特点是不会统一类型,也没有确定的顺序。 举个例子:我是一个不爱整洁的人,衣柜里有衣服、鞋子、帽子、围巾等等,他们全都被塞在衣柜里,这些衣服、鞋子、帽子就组成了一个集合。 在python里,集合长啥样? 我们来定义一个名叫“衣柜”的集合,里面放一些衣服、裤子、鞋子等。 closet={'closes','pants','shoes','hat'} 什么时候用集合?怎么用集合? 集合的特点就是不会将每一个元素存放在一个内存地址中,如果定义的集合里有两个一模一样的元素,集合输出时,会自动删除重复的那个元素,所以集合适合用来去重。 list1=[1,2,3,4,2,3,4,5] my_set=set(list1) #把列表转换为集合 print(my_set) #打印集合 输出结果为:{1,2,3,4,5} 2.列表 什么是列表? 列表是按照固定顺序排列的一组元素,其类型可以不一样,长度是可以变化的。 举个例子,我是一个爱整洁的人,我的衣柜里,从左到右依次排列了西装,短裙,牛仔裤,如果我今天穿走了短裙,就会把牛仔裤往左排,这时候我的西装、短裙、牛仔裤就组成了一个列表。 在python里,列表长啥样? 定义一个带有西装,短裙、牛仔裤的衣柜列表吧! my_closet=['business suit','short skirt','jean'] 什么时候用列表? 列表是有顺序的,适合遍历。 列表常见的表现形式有数组(内存地址连续)和链表(内存地址不连续)。 3.数组 什么是数组? 数组是列表的一种类型,但是有自己的特性。 列表中的元素不是存在连续的内存空间中的,而数组是。 数组的定义 array=[1,2,3,4,5] 什么时候用数组呢? 需要访问一组元素中指定序号的元素时,如array=[1,2,3,4,5],我们想获得第三个元素,就写array[2]。 4.元组 什么是元组? 元组跟列表类似,用于按照顺序存放一组元素,但是元组里的元素一旦被创建就不可被修改和增删。 例如,我是一个爱整洁的人,我会给衣柜分区,每个区放不同的东西,我把衣柜分为上衣区、下装区、配饰区,这些区域是不会轻易修改的,这时候可以用元组。 元组的定义 我们还是来定义一个衣柜元组:closet=('closes','pants','accessory') 5.字典 什么是字典? 顾名思义,字典就是对某个概念的解释,概念就是键,解释就是值。元组的值是可以被修改的。 如我有一个衣柜,衣柜有材质、大小、颜色等属性,我的衣柜材质是玉,大小是2米,颜色是绿色。那我可以用元组定义一个衣柜。 closet={'material':'jade','size':'2',color:'green'} 当我想获取我衣柜的颜色时,我就写closet['color']

pandas进阶--Dataframe的drop_duplicates方法(数据去重)

文章目录 欢迎关注公众号【Python开发实战】,免费领取Python学习电子书!Dataframe的drop_duplicates方法drop_duplicates方法介绍用例1用例2用例3用例4用例5 欢迎关注公众号【Python开发实战】,免费领取Python学习电子书! Dataframe的drop_duplicates方法 在实际处理数据中,数据预处理操作中,常常需要去除掉重复的数据,这就用到了Dataframe的drop_duplicates方法。 drop_duplicates方法介绍 方法形式为 drop_duplicates(subset=None, keep=‘first’, inplace=False, ignore_index=False),返回删掉重复行的Dataframe。 参数解析: **subset:**列名或列名序列,对某些列来识别重复项,默认情况下使用所有列。 **keep:**可选值有first,last,False,默认为first,确定要保留哪些重复项。 first:删除除第一次出现的重复项,即保留第一次出现的重复项。last:保留最后一次出现的重复项。False:删除所有重复项。 **inplace:**布尔值,默认为False,返回副本。如果为True,则直接在原始的Dataframe上进行删除。 **ignore_index:**布尔值,默认为False,如果为True,则生成的行索引将被标记为0、1、2、…、n-1。 返回: 返回删除重复项的Dataframe或None,当inplace=True时返回None。 用例1 导入包 import pandas as pd import numpy as np df = pd.DataFrame({ 'brand': ['Yum Yum', 'Yum Yum', 'Indomie', 'Indomie', 'Indomie'], 'style': ['cup', 'cup', 'cup', 'pack', 'pack'], 'rating': [4, 4, 3.5, 15, 5] }) df 输出: 默认情况下,会根据所有列来删除重复的行。 df.drop_duplicates() 输出: 用例2 删除特定列上的重复项,使用subset参数。 df.drop_duplicates(subset=['brand']) 输出: df.drop_duplicates(subset='brand') 输出: 用例3 删除前两列的重复项,并保留最后一次出现的数据,使用keep。 df.drop_duplicates(subset=['brand', 'style'], keep='last') 输出:

Controller层通用返回类型之ResponseResult详解

JAVA开发大家都知道有经典三层,Controller, Service, Dao层. Controller层是为了返回给用户查看的,因此返回体的定义是必不可少的。 废话不多说,直接上代码: public class ResponseResult<T> implements Serializable { private static final long serialVersionUID = 958295628567280402L; /** * 结果编码 */ private int code; /** * 返回值 */ @ConvDict(type = Const.DICT_DATATYPE_CLASS) private T data; /** * 错误提示 */ private String msg; /** * 默认响应成功 */ public ResponseResult() { code = ResultCode.SUCCESS; } /** * 正常响应成功 * * @param data 响应数据 */ public ResponseResult(T data) { this(ResultCode.SUCCESS, data, null); } /** * 设置响应结果 * * @param code 响应码 * @param data 响应数据 */ public ResponseResult(int code, T data, String msg) { this.

idea中使用Git将本地项目提交到gitee仓库中

在idea中使用Git管理项目代码时一般都是克隆远程仓库到本地,进行项目代码的开发, 但有时在本地创建的项目需要提交到对应的gitee仓库中,步骤如下: 1.新建项目: 以及gitee上的远程仓库: 2.创建本地仓库: 3.将项目添加到暂存区: 4.配置远程仓库: 其中url地址为想上传到gitee的远程仓库的地址 5.将项目进行commit以及push: 5.在push到远程仓库的时候报错: 20:43:56.735: [gitdemo3] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false push --progress --porcelain origin refs/heads/master:master --set-upstream To https://gitee.com/Dames/gitdemo.git error: failed to push some refs to 'https://gitee.com/Dames/gitdemo.git' ! refs/heads/master:refs/heads/master [rejected] (fetch first) hint: Updates were rejected because the remote contains work that you do Done hint: not have locally. This is usually caused by another repository pushing hint: to the same ref.

numpy教程04---ndarray的索引

文章目录 欢迎关注公众号【Python开发实战】,免费领取Python学习电子书!工具-numpy一维ndarray与常规数组的区别多维ndarray花式索引更高维数组省略号布尔索引np.ix_ 欢迎关注公众号【Python开发实战】,免费领取Python学习电子书! 工具-numpy numpy是使用Python进行数据科学的基础库。numpy以一个强大的N维数组对象为中心,它还包含有用的线性代数,傅里叶变换和随机数函数。 一维ndarray 导入numpy import numpy as np 一维ndarray的访问和常规的Python数组类似。 a = np.array([1, 5, 3, 19, 13, 7, 3]) a[3] 输出: 19 a[2:5] 输出: array([ 3, 19, 13]) a[2:-1] 输出: array([ 3, 19, 13, 7]) a[:2] 输出: array([1, 5]) a[2::2] 输出: array([ 3, 13, 3]) a[::-1] 输出: array([ 3, 7, 13, 19, 3, 5, 1]) 当然,也可以修改ndarray的元素。 a[3] = 999 a 输出: array([ 1, 5, 3, 999, 13, 7, 3]) 也可以修改一个ndarray的切片。

本关任务:编程求以a、b、c为边长的三角形的面积area。

#include<stdio.h> #include<math.h> int main(void) { int a,b,c; float d; double e,S; scanf("%d %d %d",&a,&b,&c); d = (a + b + c) * 0.5; e = d*(d-a)*(d-b)*(d-c); S = sqrt(e); printf("%.3f\n",S); /*********End**********/ return 0; } 任务描述 本关任务:编程求以a、b、c为边长的三角形的面积area。 相关知识 三角形面积计算公式为: 假设三角形三条边长分别为a、b、c,其中s=(a+b+c)/2,则面积: 编程要求 根据提示,在右侧编辑器Begin-End处补充代码,编程求以a、b、c为边长的三角形的面积area。 输入:a b c三角形的三条边,可以是小数; 输出:三角形面积,保留3位小数。 测试说明 平台会对你编写的代码进行测试,若是与预期输出相同,则算通关。 样例输入: 3 4 5 样例输出: 6.000

完美解决lombok引用失效问题

1、安装lombok插件 在IDEA中的设置找到Plugins(插件设置),搜索lombok 如果未安装则点击安装,并在安装后开启为enable状态 2、开启Annotation Processors 3、确定引入了lombok相关jar包 <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> <scope>provided</scope> </dependency> </dependencies>

NCCL error in: /pytorch/torch/lib/c10d/ProcessGroupNCCL ,unhandled cuda error, NCCLversion 2.7.8

本文采用方法 pytorch 、cudatoolkit、cuda驱动的版本需一致 问题描述 使用多GPU训练 stylegan3 模型时: python train.py --outdir=training-runs --cfg=stylegan3-r \ --data=datastes/your_data.zip \ --cfg=stylegan3-r --gpus=4 --batch=32 --gamma=8 --kimg=1800 --snap=50 --tick=2 报错信息 torch.multiprocessing.spawn.ProcessRaisedException: …… RuntimeError: NCCL error in: /opt/conda/conda-bld/pytorch_1631630841592/work/torch/lib/c10d/ProcessGroupNCCL.cpp:911, unhandled cuda error, NCCL version 2.7.8 ncclUnhandledCudaError: Call to CUDA function failed. 本地环境 4xTeslaV100 显卡驱动及CUDA版本为11.0 stylegan3 默认环境 解决方法 去pytorch官网,搜索对应的 Cudatookit版本 conda install pytorch==1.7.0 torchvision==0.8.0 torchaudio==0.7.0 cudatoolkit=11.0 -c pytorch 探索过程 思路1 :安装nccl (本文没用) NCCL下载及安装教程https://developer.nvidia.com/nccl/nccl-legacy-downloadshttps://docs.nvidia.com/deeplearning/nccl/install-guide/index.html#usingnccl 思路2:pytorch 、cudatoolkit、cuda驱动的版本一致 https://github.com/ultralytics/yolov5/issues/4530

ClickHouse安装配置

一.安装官网介绍安装 https://clickhouse.com/#quick-start sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo sudo yum install -y clickhouse-server clickhouse-client sudo /etc/init.d/clickhouse-server start clickhouse-client # or "clickhouse-client --password" if you set up a password. 记得需要修改用户组 [root@Linux121 clickhouse-server]# chown -R clickhouse: '/var/run/clickhouse-server/' 集群方式配置 修改配置文件/etc/clickhouse-server/config.xml <listen_host>::</listen_host> <zookeeper> <node> <host>Linux121</host> <port>2181</port> </node> <node> <host>Linux122</host> <port>2181</port> </node> <node> <host>Linux123</host> <port>2181</port> </node> </zookeeper> <macros> <shard>01</shard> <replica>Linux121</replica> </macros> <perftest_3shards_1replicas> <shard> <internal_replication>true</internal_replication> <replica> <host>Linux121</host> <port>9000</port> </replica> </shard> <shard> <internal_replication>true</internal_replication> <replica> <host>Linux122</host> <port>9000</port> </replica> </shard> <shard> <internal_replication>true</internal_replication> <replica> <host>Linux123</host> <port>9000</port> </replica> </shard> </perftest_3shards_1replicas> 启动服务

树形结构和普通list数据的互换

树形结构和普通list数据的互换 1. list转树形结构 /** * list转树形List * @param list * @return */ public static List<RetTreePath> list2tree(List<RetTreePath> list) { List<RetTreePath> result = new ArrayList<>(); Map<Long, RetTreePath> map = list.stream().collect(Collectors.toMap(test -> test.getId(), test -> test)); for (RetTreePath test : list) { RetTreePath p = map.get(test.getParentId()); if (p == null) { result.add(test); } else { if (p.getChildren() == null) { p.setChildren(new ArrayList<>()); } p.getChildren().add(test); } } return result; } 二. 树形结构转list /** * 树形list转list * @param list * @return */ public static List<RetTreePath> tree2list(List<RetTreePath> list) { List<RetTreePath> result = new ArrayList<>(); for (RetTreePath retTreePath : list) { List<RetTreePath> c = retTreePath.

【Spring Boot】数据校验

文章目录 2. 数据校验1. Hibernate Validator2. JavaBean参数校验3. URL参数校验4. JavaBean 对象级联校验5.分组校验6. 声明自定义校验注解 2. 数据校验 对于应用系统而言,任何客户端传入的数据都不是绝对安全有效的,这就要求我们在服务端接收到数据时也对数据的有效性进行验证,以确保传入的数据安全正确。数据校验是Web开发中的重要部分,也是必须考虑和面对的事情。应用系统必须通过某种手段来确保输入的数据从语义上来讲是正确的。 目前数据校验的规范、组件非常多,有JSR-303/JSR-349、HibernateValidator、Spring Validation。 1. Hibernate Validator JSR(Java Specification Request)规范是Java EE 6中的一项子规范,也叫作Bean Validation。它指定了一整套基于bean的验证API,通过标注给对象属性添加约束条件。Hibernate Validator是对JSR规范的实现,并增加了一些其他校验注解,如@Email、@Length、@Range等。Spring Validation是Spring为了给开发者提供便捷,对Hibernate Validator进行了二次封装。同时,Spring Validation在SpringMVC模块中添加了自动校验,并将校验信息封装进了特定的类中。 所以,JSR定义了数据验证规范,而Hibernate Validator则是基于JSR规范,实现了各种数据验证的注解以及一些附加的约束注解。Spring Validation则是对Hibernate Validator的封装整合。 包含了Hibernate Validator实现的JSR-303定义的验证注解和HibernateValidator自己定义的验证注解,同时也支持自定义约束注解。所有的注解都包含code和message这两个属性。 Message定义数据校验不通过时的错误提示信息。code定义错误的类型。 使用Hibernate Validator校验数据需要定义一个接收的数据模型,使用注解的形式描述字段校验的规则。 2. JavaBean参数校验 Post请求参数较多时,可以在对应的数据模型(Java Bean)中进行数据校验,通过注解来指定字段校验的规则。 首先引入Validator依赖 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.20.Final</version> </dependency> 我们创建一个JavaBean 实体类 public class User { @NotBlank(message = "姓名不允许为空") @Length(min = 2,max = 10,message = "姓名长度错误,长度长度2-10!") private String name; @NotNull(message = "年龄不能为空") @Min(18,message = "

ShardingSphere简介与分表使用

一、ShardingSphere简介 1、简介 ShardingSphere 已于 2020 年 4 月 16 日成为 Apache 软件基金会的顶级项目。 ShardingSphere 是一套开源的分布式数据库中间件解决方案。 ShardingSphere 产品定位为 Database Plus,旨在构建异构数据库上层的标准和生态圈。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 ShardingSphere 站在数据库的上层视角,关注他们之间的协作多于数据库自身。 它由ShardingSphere-JDBC、ShardingSphere-Proxy 和 ShardingSphere-Sidecar这3款相互独立的产品组成。 ShardingSphere-JDBC:定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。ShardingSphere-Proxy:定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。ShardingSphere-Sidecar:定位为 Kubernetes 的云原生数据库代理,以 Sidecar 的形式代理所有对数据库的访问。 2、核心概念 2.1 表概念 1)真实表 在数据库中真实存在的物理表。例如:t_order_0、t_order_1 2)逻辑表 在分片之后,同一类表结构的名称(总成)。例如b_order。 水平拆分的数据库(表)的相同逻辑和数据结构表的总称。例如:订单表根据主键尾数拆分为10张真实表(t_order_0到t_order_9),他们的逻辑表名为t_order。 3)数据节点 在分片之后,由数据源和数据表组成。例如ds0.b_order1 数据分片的最小单元。由数据源名称和数据表组成,例如:ds_0.t_order_0。 4)绑定表 指的是分片规则一致的关系表(主表、子表)。 例如:t_order表和t_order_item表,均按照order_id分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。 举例说明,如果SQL为: SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11); 在不配置绑定表关系时,假设分片键order_id将数值10路由至第0片,将数值11路由至第1片,那么路由后的SQL应该为4条,它们呈现为笛卡尔积: SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.