跳到主要内容

DML数据操纵语言

· 阅读需 3 分钟
季冠臣
后端研发工程师

mysql表数据的插入、删除、修改以及中文编码问题

1、mysql新增表数据

普通的插入表数据

insert into 表名(字段名) values(字段对应值);

insert into employee (empno,ename,job,mgr,hiredate,sal,deptnu) values ('1000','小明','经理','10001','2019-03-03','12345.23','10');
insert into 表名 values(所有字段对应值);

# 一次性插入多个数据
insert into employee values ('1001','小明','经理','10001','2019-03-03','12345.23','10');

蠕虫复制(将一张表的数据复制到另一张表中)

insert into 表名1 select * from 表名2;

insert into 表名1(字段名1,字段名2) select 字段名1,字段名2 from 表名2;

insert into emp (empno,ename) select empno,ename from employee;

建表复制

create table 表名1 as select 字段名1,字段名2 from 表名2;

create table emp as select empno ,ename from employee;

创建sql

某个公司的员工表
CREATE TABLE employee(
empno INT PRIMARY KEY comment '雇员编号',
ename VARCHAR(20) comment '雇员姓名',
job VARCHAR(20) comment '雇员职位',
mgr INT comment '雇员上级编号',
hiredate DATE comment '雇佣日期',
sal DECIMAL(7,2) comment '薪资',
deptnu INT comment '部门编号'
);

2、mysql表数据的修改和删除

表数据的修改/更新

update 表名 set 字段名1=值1 where 字段名=值;

update 表名 set 字段名1=值1,字段名2=值2 where 字段名=值;

删除

delete from 表名 where 字段名=值;
truncate table 表名;
delete from 表名;
drop table 表名;

面试时:面试官问在删改数据之前,你会怎么做?
答案:会对数据进行备份操作,以防万一,可以进行数据回退

面试时:面试官会问,delete与truncate与drop 这三种删除数据的共同点都是删除数据,他们的不同点是什么?
delele 会把删除的操作记录给记录起来,以便数据回退,不会释放空间,而且不会删除定义。
truncate不会记录删除操作,会把表占用的空间恢复到最初,不会删除定义
drop会删除整张表,释放表占用的空间。

删除速度:
drop > truncate > delete

3、乱码问题

查看当前mysql使用的字符集:show variables like 'character%';

a972dff99984198529bae877356409acharacter_set_client:客户端请求数据的字符集 character_set_connection:客户端与服务器连接的字符集 character_set_database:数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将默认使用配置 上的字符集 character_set_results:返回给客户端的字符集(从数据库读取到的数据是什么编码的) character_set_server:为服务器安装时指定的默认字符集设定。 character_set_system:系统字符集(修改不了的,就是utf8) character_sets_dir:mysql字符集文件的保存路径

临时:set names gbk;

永久:修改配置文件my.cnf里边的

[client]
default-character-set=gbk
作用于外部的显示
[mysqld]
character_set_server=gbk
作用于内部,会作用于创建库表时默认字符集

修改库的字符集编码

alter database xiaoxiao default character set gbk;

修改表的字符集编码

alter table employee default character set utf8;
浏览量:加载中...

HTTP请求方法和响应状态码

· 阅读需 2 分钟
季冠臣
后端研发工程师

介绍了九种HTTP请求方法和常见响应码HTTPCode

http1.0定义了三种: GET: 向服务器获取资源,⽐如常⻅的查询请求 POST: 向服务器提交数据而发送的请求 Head: 和get类似,返回的响应中没有具体的内容,用于获取报头

http1.1定义了六种: PUT:⼀般是用于更新请求,比如更新个人信息、商品信息全量更新 PATCH:PUT ⽅法的补充,更新指定资源的部分数据 DELETE:⽤用于删除指定的资源 OPTIONS: 获取服务器支持的HTTP请求方法,服务器性能、跨域检查等 CONNECT: 方法的作用就是把服务器作为跳板,让服务器代替用户去访问其它网页,之后把数据原本的返回给用户,网页开发基本不用这个方法,如果是http代理就会使⽤这个,让服务器代理用户去访问其他网页,类似中介 TRACE:回显服务器收到的请求,主要用于测试或诊断

Http常见的响应状态码讲解 浏览器向服务器请求时,服务端响应的消息头里面有状态码,表示请求结果的状态 分类 1XX: 收到请求,需要请求者继续执行操作,比较少用 2XX: 请求成功,常用的 200 3XX: 重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到⼀一个新的URL地址,这个地址可以从响应的Location首部中获取; 好处:⽹站改版、域名迁移等,多个域名指向同个主站导流 必须记住: 301:永久性跳转,比如域名过期,换个域名 302:临时性跳转

​ 4XX: 客服端出错,请求包含语法错误或者无法完成请求 ​ 必须记住: 400: 请求出错,比如语法协议 403: 没权限访问 404: 找不到这个路径对应的接口或者文件 405: 不允许此方法进行提交,Method not allowed,比如接口一定要POS⽅方式,⽽而你是用了GET ​ 5XX: 服务端出错,服务器在处理理请求的过程中发⽣生了错误必须 ​ 记住: 500: 服务器内部报错了,完成不了这次请求 503: 服务器宕机

浏览量:加载中...

HTTP请求头和响应头

· 阅读需 3 分钟
季冠臣
后端研发工程师

介绍了Http响应头和响应头的知识点

常见Http请求头知识点

http请求分为三部分:请求行,请求头, 请求体

请求头: 报文头包含若干个属性 格式为“属性名:属性值”, 服务端据此获取客户端的基本信息

常见的请求头

Accept: 览器支持的 MIME 媒体类型, 比如 text/html,application/json,image/webp,/ 等

Accept-Encoding: 浏览器发给服务器,声明浏览器支持的编码类型,gzip, deflate

Accept-Language: 客户端接受的语言格式,比如 zh-CN

Connection: keep-alive , 开启HTTP持久连接

Host:服务器的域名

Origin:告诉服务器请求从哪里发起的,仅包括协议和域名 CORS跨域请求中可以看到

response有对应的header,Access-Control-Allow-Origin

Referer:告诉服务器请求的原始资源的URI,其用于所有类型的请求,并且包括:协议+域名+查询参数;很多抢购服务会用这个做限制,必须通过某个⼊来进来才有效

User-Agent: 服务器通过这个请求头判断用户的软件的应⽤用类型、操作系统、软件开发商以及版本号、浏览器器内核信息等; 风控系统、反作弊系统、反爬⾍虫系统等基本会采集这类信息做参考

Cookie: 表示服务端给客户端传的http请求状态,也是多个key=value形式组合,比如登录后的令牌等

Content-Type: HTTP请求提交的内容类型,⼀一般只有post提交时才需要设置,比如文件上传,表单提交等

常见Http响应头知识点

响应头: 报⽂头包含若干个属性 格式为“属性名:属性值”

常见的响应头:

Allow: 服务器支持哪些请求方法

Content-Length: 响应体的字节⻓度

Content-Type: 响应体的MIME类型

Content-Encoding: 设置数据使用的编码类型

Date: 设置消息发送的日期和时间

Expires: 设置响应体的过期时间,一个GMT时间,表示该缓存的有效时间

cache-control: Expires的作用一致,都是指明当前资源的有效期, 控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据,优先级高于Expires,控制粒度更细,如max-age=240,即4分钟

Location:表示客户应当到哪里去获取资源,⼀般同时设置状态代码为3xx

Server: 服务器名称

Transfer-Encoding:chunked 表示输出的内容长度不能确定,静态网页一般没,基本出现在动态网页里面

Access-Control-Allow-Origin: 定哪些站点可以参与跨站资源共享
浏览量:加载中...

HTTP的content-type媒体类型

· 阅读需 1 分钟
季冠臣
后端研发工程师

介绍了Http里面的content-type媒体类型

Content-type: 用来指定不同格式的请求响应信息,俗称MIME媒体类型常见的取值

text/html :HTML格式 text/plain :纯文本格式

text/xml : XML格式

image/gif :gif图片格式 image/jpeg :jpg图片格式 image/png:png图片格式

application/json:JSON数据格式 application/pdf :pdf格式
application/octet-stream :二进制流数据,一般是文件下载

application/x-www-form-urlencoded:form表单默认的提交数据的格式,会编码成key=value格式

multipart/form-data: 表单中需要上传文件的文件格式类型

Http知识加深文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP

浏览量:加载中...

Servlet

· 阅读需 3 分钟
季冠臣
后端研发工程师

介绍了什么是Servlet、Servlet常用方法、生命周期等

这是一个JavaWeb Servlet文档:https://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html

1、什么是Servlet

**简介:**是JavaServlet的简称,用Java编写的运行在Web服务器或应用服务器上的程序,具有独立于平台和协议的特性, 主要功能在于交互式地浏览和生成动态Web内容 **作用:**接收用户通过浏览器传来的表单数据,或者读取数据库信息返回给浏览器查看,创建动态网页 **接口路径:**package javax.servlet 有两个常见的⼦子类:HttpServlet、GenericServlet

2、重写doGet和doPost方法

doGet方法 doPost方法

3、讲解Servlet的生命周期(面试)

实例化->使用构造方法创建对象

初始化->执行init方法:Servlet 的生命期中,仅执行一次 init() 方法,它是在服务器装⼊Servlet 时执行的,即第一次访问这个Servlet才执行

服务->执行service方法,service()方法是 Servlet的核心。每当一个客户请求一个HttpServlet 对象,该对象的service()方法就要被调用

销毁-> 执行destroy方法,destroy() 方法仅执行一次,即在服务器停止且卸装 Servlet 时执行该方法

public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws
ServletException, IOException;
String getServletInfo();
void destroy();
}

HttpServlet里面实现了service方法,里面会根据不同的http method调用不同的方法,所以我们自定义servlet只要重写对应的doXXX方法即可

查看继承和实现关系 XXXServlet->HttpServlet->GenericServlet->implements Servle

4、新版Servlet3.0~5.0和旧版配置

旧版Servlet,在xml里面配置类目和路径,比较不方便

//XML配置
<servlet>
<servlet-name>userServlet</servlet-name>
<servlet-class>net.xdclass.web.UserServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>

新版Servelt,也就是3.0之后,支持注解的方式

@WebServlet(name = "userServlet",urlPatterns = {"/user1","/user2","/test"})
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doGet");
//实战响应内容
resp.setContentType("text/html;charset=utf-8");
PrintWriter printWriter = resp.getWriter();
printWriter.write("<div> doGet jiguanchen.space 你好!
</div>");
}
}


//配置项
//servlet名称,若不指定,则为Servlet的完整类名
String name() default "";
//路径映射,配置多个,需要/开头
String[] value() default {};
//路径映射,⽀持配置多个,需要/开头
String[] urlPatterns() default {};
//标记容器是否在启动应用时就加载Servlet,默认或数值为负数时表示第一次请求Servlet时再加载;0或正数表示启动应用就加载
int loadOnStartup() default -1;
//配置初始参数
WebInitParam[] initParams() default {};
//是否支持异步操作模式
boolean asyncSupported() default false;
浏览量:加载中...

线程基础

· 阅读需 1 分钟
季冠臣
后端研发工程师

一个程序至少一个进程,一个进程至少一个线程

一、进程与线程的区别

...待续

浏览量:加载中...

迭代器Iterator

· 阅读需 3 分钟
季冠臣
后端研发工程师

迭代器是一种设计模式,在链式结构中经常使用。本篇主要介绍什么是Iterator?Iterator的主要方法及其注意事项?

什么是迭代器?

terator是java中的一个接口,核心作用就是用来遍历容器的元素,当容器实现了Iterator接口后,可以通过调用Iterator()方法获取⼀个 Iterator对象。

为什么调用容器里面的Iterator方法? 因为容器的实现有多种,不同的容器遍历规则不⼀样,比如ArrayList/LinkedList/ HashSet/TreeSet等,所以设计了Iterator接口,让容器本身去实现这个接⼝,实现里面的方法,从而让开发人员不用关系容器的遍历机制,直接使用对应的方法即可

三个核⼼方法 boolean hashNext():用于判断iterator内是否有下个元素,如果有则返回true,没有则false Obejct next():返回iterator的下一个元素,同时指针也会向后移动1位 void remove():删除指针的上⼀个元素(容易出问题,删除元素不建议使用容器器自己的方法)

迭代器的集合遍历

public static void testSet(){
Set<String> set = new HashSet<>();
set.add("jack");
set.add("tom");
set.add("marry");
set.add("tony");
set.add("jack");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String str = iterator.next();
System.out.println(str);
}
}
public static void testList(){
List<String> list = new ArrayList<>();
list.add("jack");
list.add("tom");
list.add("mary");
list.add("tim");
list.add("tony");
list.add("eric");
list.add("jack");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String str = iterator.next();
System.out.println(str);
}
}

void remove()强调: ​ 1、删除指针的上⼀个元素 ​ 2、只有当next执⾏行行完后,才能调⽤用remove函数 ​ 3、如要删除第⼀个元素,不能直接调⽤用 remove(),要先next⼀下()否则调⽤用remove方法是会抛出异常的

迭代器遍历元素时不能通过Collection接口中的remove⽅法删除元素,只能⽤用Iterator的remove方法删除元素; 原因 某个线程在 Collection 上进行迭代时,不允许另一个线程修改该 Collection

public static void testList(){
List<String> list = new ArrayList<>();
list.add("jack");
list.add("tom");
list.add("mary");
list.add("tim");
list.add("tony");
list.add("eric");
list.add("jack");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String str = iterator.next();
if("jack".equals(str)){
list.remove(str);//ConcurrentModificationException并发修改异常
}
System.out.println(str);
}
}

迭代出的对象是引用的拷贝,如果修改迭代中的元素,那么就是修改容器对象的本身

和for循环对⽐

  • for循环适合顺序访问,或者通过下标进⾏访问的
  • 迭代器适合链式结构
  • 最终看使⽤场景,性能会有轻微差别,但是可以忽略
浏览量:加载中...

集合工具类Collections

· 阅读需 4 分钟
季冠臣
后端研发工程师

介绍了不能被实例化的集合工具类Collections

1、Collections包含有多种集合操作的静态多态方法,不能把构造函数私有化(即实例化)

public class Collections {
// Suppresses default constructor, ensuring non-
instantiability.
private Collections() {
}

2、与Collection的区别 Collection是接口,提供了对集合对象进行基本操作的通用接⼝方法,List、Set等多种具体的实现类 Collections是工具类,专门操作Collection接口实现类里面的元素

3、常见方法

排序sort(List list)

//按自然排序升序
List<String> list = new ArrayList<>();
list.add("aaaa");
list.add("zzz");
list.add("gggg");
System.out.println(list);
Collections.sort(list);
System.out.println(list);

/*sort(List list, Comparator c) 自定义排序规则,由Comparator控制排序逻辑*/
List<String> list = new ArrayList<>();
list.add("aaaa");
list.add("zzz");
list.add("gggg");
System.out.println(list);
//默认升序
Collections.sort(list, Comparator.naturalOrder());
System.out.println(list);
//降序
Collections.sort(list, Comparator.reverseOrder());
System.out.println(list);

随机排序 shuffle(List list)
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
list.add("10");
list.add("J");
list.add("Q");
list.add("K");
System.out.println(list);
Collections.shuffle(list);
System.out.println(list);

获取最大元素 max(Collection coll) 默认比较,不适合对象比较

//获取最大元素 max(Collection coll, Comparator comparator)
//获取最小元素 min(Collection coll)

public class CollectionsTest {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("jack", 26));
list.add(new Student("tom", 29));
list.add(new Student("mary", 32));
list.add(new Student("tony", 19));
list.add(new Student("smith", 41));
System.out.println(list);
Student maxAgeStudent = Collections.max(list, new
Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});

Student mixAgeStudent = Collections.mix(list, new
Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(maxAgeStudent.toString());
}
}
class Student {
public Student(String name, int age) {
this.name = name;
this.age = age;
}
private int age;
private String name;
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}

4、创建不可变集合unmodifiablleXXX()

    List<String> list = new ArrayList<>();
list.add("SpringBoot课程");
list.add("架构课程");
list.add("微服务SpringCloud课程"); //设置为只读List集合
list = Collections.unmodifiableList(list);
System.out.println(list);
Set<String> set = new HashSet<>();
set.add("Mysql教程");
set.add("Linux服务器器器器教程");
set.add("Git教程");
//设置为只读Set集合
set = Collections.unmodifiableSet(set);
System.out.println(set);
Map<String, String> map = new HashMap<>();
map.put("key1", "课程1");
map.put("key2", "课程2");
//设置为只读Map集合
map = Collections.unmodifiableMap(map);
System.out.println(map);

5、元素排序接口Comparable

//什么是Comparable
public interface Comparable<T> {
public int compareTo(T o);
}
//是一个接口,定制排序规则
//对它的每个类的对象进行整体排序,里面compareTo方法是实现排序的具体方法
//比如TreeSet、SortedSet、Collections.sort()方法调用进行排序
//String、Integer等类默认实现了这个接口,所以可以排序(看源码)

//详解comparable方法
//⽤于比较次对象和指定对象的顺序,o为要比较的对象
//返回int类型
//大于0, 表示this大于传进来的对象o ,则往后排,即升序
//等于0,表示this等于传进来的对象o
//小于0,表示this小于传进来的对象o

//需求:根据学生的年龄进行排序
public class TestCom {
public static void main(String [] args) {
Set<Student> studentSet = new TreeSet<>();
studentSet.add(new Student("jack",32));
studentSet.add(new Student("tom",22));
studentSet.add(new Student("mary",35));
studentSet.add(new Student("tim",11));
studentSet.add(new Student("tony",49));
studentSet.add(new Student("dd",30));
System.out.println(studentSet);
}
}
class Student implements Comparable{
private int age;
private String name;
public void setAge(int age) {





this.age = age;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Student(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Object o) {
if(o instanceof Student){
Student student = (Student)o;
return this.age - student.age;
}
//返回的数是0代表两个对象相同
return 0;
}
}
浏览量:加载中...

集合Map

· 阅读需 2 分钟
季冠臣
后端研发工程师

记录了Map常见API和面试题

Map<String,String> map = new HashMap<>();

//往map里面放key - value;
map.put("小明","广东广州");
map.put("小东","广东深圳");

//根据key获取value
map.get("小东");

//判断是否包含某个key
map.containsKey("小明");

//返回map的元素数量
map.size();

//清空容器器
map.clear();

//获取所有value集合
map.values();

//返回所有key的集合
map.keySet()

//返回一个Set集合,集合的类型为Map.Entry,是Map声明的一个内部接口,接⼝为泛型,定义为Entry<K,V>,

//它表示Map中一个实体(一个key-value对),主要有getKey(),getValue方法
Set<Map.Entry<String,String>> entrySet = map.entrySet();

//判断map是否为空
map.isEmpty();

Map面试题 1、HashMap和TreeMap应该怎么选择? HashMap可实现快速存储和检索,但缺点是包含的元素是无序的,适用于在Map中插⼊、删除和定位元素. TreeMap能便便捷的实现对其内部元素的各种排序,但其⼀般性能比HashMap差,适用于按⾃然顺序或自定义顺序遍历键(key) eg:微信支付

2、jdk1.7和jdk1.8中HashMap的主要区别。 底层实现由之前的 “数组+链表” 改为 “数组+链表+红黑树”

3、什么时候开始转变? 当链表节点较少时仍然是以链表存在,当链表节点较多时,默认是大于8时会转为红黑树21b307238b899b7e5ea23f9d5cb1c98

  • Typora 换行间距最小 shift+enter
浏览量:加载中...

集合Set

· 阅读需 2 分钟
季冠臣
后端研发工程师

集合框架之Set及其子类

什么是Set数据结构? 1、Set相对于List是简单的一种集合,具有和 Collection 完全一样的接口,只是实现上不同,Set不保存重复的元素,存储一组唯一,⽆序的对象。 2、Set中的元素是不能重复的, 实现细节可以参考Map,因为这些Set的实现都是对应的Map的一种封装。比如HashSet是对HashMap的封装,TreeSet对TreeMap 3、Set底层是一个HashMap,由于HashMap的put()方法是一个键值对,当新放⼊HashMap的Entry中key 与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true),新添加的Entry的value会将覆盖原来Entry的value,但key不会有任何改变。 4、允许包含值为null的元素,但最多只能有一个null元素

常⻅的实现类。 HashSet HashSet类按照哈希算法来存取集合中的对象,存取速度比较快 对应的Map是HashMap,是基于Hash的快速元素插入,元素⽆顺序。 TreeSet TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序

//创建对象,HashSet和TreeSet api一样
Set<Integer> set = new HashSet<>();
//往容器里面添加对象
set.add("jack");
//清空元素
set.clear();
//返回⼤小
set.size();
//根据对象删除元素
set.remove("jack");
//是否为空
set.isEmpty();

两者常见区别 1、HashSet不能保证元素的排列列顺序,TreeSet是SortedSet接口的唯一实现类,可以确保集合元素处于排序状态 2、HashSet底层用的是哈希表,TreeSet采用的数据结构是红⿊树(红⿊树是⼀种特定类型的⼆叉树) 3、HashSet中元素可以是null,但只能有一个,TreeSet不允许放⼊null 4、一般使⽤用HashSet,如果需要排序的功能时,才使用TreeSet(性能原因)

浏览量:加载中...