使用键盘录入数据通过UDP发送端发送至接收端

发送端代码实现

public class UdpSend {public static void main(String[] args) {//UDP发送端可以不断键盘录入数据//创建发送端的socketDatagramSocket ds = null ;try {ds = new DatagramSocket() ;//键盘录入可以使用BufferedReader--->读一行BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;String line = null ;//一次读一行内容System.out.println("请您输一个数据");while((line=br.readLine())!=null){if("over".equals(line)){break;}//创建数据报包,将数据存储在数据包中DatagramPacket dp = new DatagramPacket(line.getBytes(),line.getBytes().length,InetAddress.getByName("10.35.162.121"),6666) ;//发送数据报包ds.send(dp) ;}} catch (IOException e) {e.printStackTrace();}finally {if(ds!=null){ds.close() ;}}}
}

接收端代码实现

public class UdpReceive {public static void main(String[] args) {try {//创建接收端的Socket对象DatagramSocket ds = new DatagramSocket(6666) ;while(true){//创建一个接收容器//自定义一个字节数组缓冲区byte[] buffer = new byte[1024] ;int bufferLength =  buffer.length ;DatagramPacket dp = new DatagramPacket(buffer,bufferLength) ;//接收数据容器ds.receive(dp) ;//解析接收容器中真实内容byte[] bytes = dp.getData();int length = dp.getLength();//每次0开始读取字节数---转成StringString receiveMsg = new String(bytes,0,length) ;//获取ip地址字符串String ip = dp.getAddress().getHostAddress() ;//展示数据System.out.println("data from-->"+ip+",conent is :"+receiveMsg);}} catch (IOException e) {e.printStackTrace();}}
}

TCP客户端和服务器端的代码实现

客户端

 /* 有关TCP客户端 使用步骤* 1)创建客户端的Socket对象,指定ip和端口* 2)获取客户端通道内容字节输出流对象,写数据* 3)释放资源*/
public class TcpClientDemo {public static void main(String[] args) throws IOException {//1)创建客户端的Socket对象,指定ip和端口//Socket(String host, int port)Socket socket = new Socket("10.35.162.121",1888) ;//2)获取客户端通道内容字节输出流对象,写数据//public OutputStream getOutputStream()OutputStream outputStream = socket.getOutputStream();outputStream.write("hello,TCP我来了".getBytes());//客户端获取通道字节输入流对象,读服务器端的反馈的数据InputStream in = socket.getInputStream();byte[] bytes = new byte[1024] ;int length = in.read(bytes);String fkMsg = new String(bytes,0,length) ;System.out.println(fkMsg);//3)释放资源outputStream.close();}
}

服务器端

/* TCP服务器端的代码实现* 1)创建服务器端的Socket对象* 2)监听客户端的连接* 3)获取监听到的客户端的通道内的自节输入流对象,读数据* 4)释放服务器端的资源*/
public class TcpServerDemo {public static void main(String[] args) throws IOException {//1)创建服务器端的Socket对象//public ServerSocket(int port)ServerSocket ss = new ServerSocket(1888) ;System.out.println("服务器正在等待客户端连接请求...");//2)监听客户端的连接// public Socket accept()throws IOExceptionSocket socket = ss.accept();//阻塞式方法,没有客户端连接,一直等待System.out.println("客户端已连接");//3)获取监听到的客户端的通道内的字节输入流对象,读数据//public InputStream getInputStream()InputStream inputStream = socket.getInputStream();//一次读取一个字节数组byte[] bytes = new byte[1024] ;int length = inputStream.read(bytes);//转换成StringString receiveMsg =  new String(bytes,0,length) ;//获取ip地址对象,同时ip地址字符串形式// public InetAddress getInetAddress()String ip = socket.getInetAddress().getHostAddress();System.out.println("data from --->"+ip+",content is-->"+receiveMsg);//服务器端反馈给客户端数据//服务器端可以获取监听客户端通道内字节输出流,写数据OutputStream out = socket.getOutputStream();out.write("我这边已经收到数据!".getBytes());//        * 4)释放服务器端的资源ss.close();}
}

TCP三次握手的原理—>SYNC+ACK

  • SYNC同步序列编号
  • ACK:消息确认字符(当客户端发送数据到服务器端,服务器需要 确认并反馈)

TCP的应用

TCP方式,客户端可以不断键盘录入数据,服务器端不断展示数据

客户端

 /*  TCP客户端不断键盘录入数据,服务器端不断展示数据*/
public class TcpClient {public static void main(String[] args) throws IOException {//1)创建客户端SocketSocket socket  = new Socket("10.35.162.121",8888) ;//2)可以创建BufferedReader 一次读取一行,录入数据BufferedReader br=  new BufferedReader(new InputStreamReader(System.in)) ;//获取通道字节输出流对象,写数据--->字节输出流---->包装字符流OutputStream out = socket.getOutputStream();//可以使用字符流把上面的通道内的字节数出流包装BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out)) ;String line = null ;while((line=br.readLine())!=null){/*if("886".equals(line)){break;}*///录入一行,给封装到通过的字符流写一行进去bw.write(line) ;bw.newLine();bw.flush();}socket.close();}
}

服务器端

/* 服务器端不断展示数据*/
public class TcpServer {public static void main(String[] args) throws IOException {//创建服务器端的SocketServerSocket ss = new ServerSocket(8888) ;System.out.println("服务器正在等待连接");// int i= 0 ;while (true){//监听多个客户端了解//   i++;//监听客户端连接Socket socket = ss.accept();//  System.out.println("第"+i+"个客户端已连接");//获取监听客户端所在的通道内的字节输入流InputStream in = socket.getInputStream();//将桶内的字节输入流封装成字符流读BufferedReader br = new BufferedReader(new InputStreamReader(in)) ;//一次读取一行String line = null ;while((line=br.readLine())!=null){if("886".equals(line)){break;}System.out.println(line) ;//展示数据}}//模拟真实场景,服务器端不关}
}

TCP客户端的读取文本文件(将文本文件写入通道中)

客户端

/* 需求:*      TCP客户端的文本文件(当前项目下的UdpReceive.java文件)*              分析:TCP创建字符缓冲输入流--->读UdpReceive.java文件  一次读一行*                  TCP客户端获取通道字节输入流--->封装字符缓冲输出流--->写一行---发给服务器端***/
public class TcpClientTest {public static void main(String[] args) throws IOException {//创建客户端的Socket对象Socket s = new Socket("10.35.162.121",2222) ;//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("UdpReceive.java")) ;//获取客户端通道的字节输出流---->包装成BufferedWriter:字符缓冲输出流BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())) ;//每次从.java文件读取一行,给通道流的流中写一行String line = null ;while((line=br.readLine())!=null){bw.write(line) ;bw.newLine();bw.flush();}System.out.println("文件读完,发送过去了...");//释放资源br.close();s.close();}
}

服务器端

 /* TCP服务器端将复制客户端的文件内容,复制到D://2211//day27_code_resource//Copy.java里面*                 分析:*                        TCP获取监听客户端的字节输入流--->封装字符缓冲输入流--->一读取一行*                        创建字符缓冲输出流--->写一行D://2211//day27_code_resource//copy.java到这个文件中*/
public class TcpServerTest {public static void main(String[] args) throws IOException {//创建服务器端的Socket对象ServerSocket ss = new ServerSocket(2222) ;//监听客户端连接Socket s = ss.accept();//获取监听客户端所在的通道内字节输入流对象---->包装成字符缓冲输入流BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())) ;//将监听客户端的通道内的字节流(已经被包装了字符缓冲输入流)的内容----通过的字符缓冲输出流写入到文件中BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\EE_2211\\day27_code_resource\\copy.java")) ;//一次读取一行,写一行到文件中String line = null ;while((line=br.readLine())!=null){bw.write(line);bw.newLine();bw.flush();}System.out.println("复制完毕");//释放资源bw.close();ss.close();}
}

TCP客户端读取文本文件,服务器端复制文本文件,现在服务器端反馈给客户端,“已经复制完毕”

客户端

/* 需求*  TCP客户端的文本文件(当前项目下的UdpReceive.java文件),*  TCP服务器端复制文本文件到:D:\EE_2211\day27_code_resource\Copy.java文件中*  TCP服务器端需要响应给客户端数据 "文件复制完毕"*  TCP客户端展示服务器反馈的这个数据!*  发现问题:*          两个端都出现了互相等待了*          因为客户端的文本文件读完,是null作为结束条件,但是服务器端不断的从通道内的输入流去读数据,*   两端的通道不知道文件是否完了(服务器端不知道客户端的文件完没完),等待着写数据过来,* 解决方案:*  通知服务器端,别等了,文件读完了*  1)自定义结束条件 ,服务器端读到自定义结束条件,就反馈!*      弊端:如果文件第一句话恰好是自定义的结束条件,就不好**  2)推荐:在客户端这边有个终止通道内的流 没有数据写过去了!禁止输出流输出!*      public void shutdownOutput()   throws IOException*/
public class Tcp_ClientTest2 {public static void main(String[] args) throws IOException {//创建客户端的Socket对象Socket s = new Socket("10.35.162.121",2222) ;//创建字符缓冲输入流对象BufferedReader br = new BufferedReader(new FileReader("UdpReceive.java")) ;//获取客户端通道的字节输出流---->包装成BufferedWriter:字符缓冲输出流BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())) ;//每次从.java文件读取一行,给通道流的流中写一行String line = null ;while((line=br.readLine())!=null){//阻塞式方法.一直等待为null文件完毕bw.write(line) ;bw.newLine();bw.flush();}//写一个数据//通道内的流写一句/* bw.write("over");bw.newLine();bw.flush();*///方案2: public void shutdownOutput()   throws IOExceptions.shutdownOutput();//客户端要读取服务器反馈数据//获取通道内的字节输入流InputStream inputStream = s.getInputStream();//读取一个字节数组byte[] bytes = new byte[1024] ;int len = inputStream.read(bytes);System.out.println("客户端接收到了反馈数据:"+new String(bytes,0,len));//释放资源br.close();s.close();}
}

服务器端

public class Tcp_ServerTest2 {public static void main(String[] args) throws IOException {//创建服务器端的Socket对象ServerSocket ss = new ServerSocket(2222) ;//监听客户端连接Socket s = ss.accept();//获取监听客户端所在的通道内字节输入流对象---->包装成字符缓冲输入流BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())) ;//将监听客户端的通道内的字节流(已经被包装了字符缓冲输入流)的内容----通过的字符缓冲输出流写入到文件中BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\EE_2211\\day27_code_resource\\copy.java")) ;//一次读取一行,写一行到文件中String line = null ;while((line=br.readLine())!=null){//阻塞式,null也是表示客户端的通道内的字节输入流读完了/*  if("over".equals(line)){break;}*/bw.write(line);bw.newLine();bw.flush();}//加入反馈,服务器端反馈给客户端数据//获取字节输出流,写OutputStream out = s.getOutputStream();out.write("hello,文件复制完毕".getBytes());out.flush();//释放资源bw.close();ss.close();}
}

反射(重点)

什么是反射

  • 编译某个类的时候---->获取这个类的字节码文件,然后去加载,调用里面的成员方法,访问成员变量,
  • 通过构造方法创建对象!

编译过程

  • 对这个类的属性/成员/构造其进行校验---->类加载器(负责类的加载过程)
  • BoostrapClassLoader:启动类加载器,负责java核心库,rt.jar

如何获取一个类的字节码文件?

  • java.lang.Class:代表正在运行的java类或者接口,通过静态方法
  • public static Class forName(String classname):
  • 参数:代表就是当前类或者接口的全限定名称 (包名.类名)
  • String---->全限定名称 java.lang.String
  • Person---->自定义的---->全限称:com.qf.reflect_06.Person
代码实现(先创造实体类(有参构造及无参构造方法))
public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {//如何获取一个类的字节码文件?//第一种//任意Java对象的getClass方法Person p = new Person() ;Class clazz = p.getClass();System.out.println(clazz); //class com.qf.reflect_06.Person//第二种//任意Java类型的class属性Class clazz2 = Person.class ;System.out.println(clazz2);//第三种 推荐// java.lang.Class:代表正在运行的java类或者接口,通过静态方法// public static Class forName(String classname)Class clazz3 = Class.forName("com.qf.reflect_06.Person");System.out.println(clazz3) ;System.out.println(clazz==clazz3);System.out.println(clazz2==clazz3);System.out.println("----------------------------");Person p1 = new Person() ;Person p2 = new Person() ;System.out.println(p1==p2);}
}

反射获取成员方法并调用

/* 在反射中如何调用成员方法**      之前的写法:无参构造方法是公共的*      Person p = new Person();*      p.show() ;*/
public class ReflectDemo4 {public static void main(String[] args) throws Exception {//之前的写法// Person p = new Person();//p.show() ;System.out.println("----------------------------------");//反射的写法//1)获取类的字节码文件对象Class clazz = Class.forName("com.qf.reflect_06.Person") ;//2)通过无参构造器创建器Constructor创建当前类实例//如果你这个类没有提供任何构造方法(系统提供无参)或者无参构造方法是公共的---->此时可以直接使用Class类的newInstacne()创建当前类实例//等价于下面这个写法Object obj = clazz.newInstance();System.out.println(obj);//System.out.println(obj);/*Constructor con = clazz.getConstructor();Object obj = con.newInstance() ;*/// System.out.println(obj);// Method getMethods() ;//获取本类中所有的成员的method// Method getDeclaredMethods() ;//获取本类中所有的成员的method以及父类的Object//3)获取指定的成员方法所在的Method类对象// public Method getDeclaredMethod(String name, Class<?>... parameterTypes)获取指定的成员方的method类对象// public Method getMethod(String name, Class<?>... parameterTypes):获取指定的公共的成员方法的Method对象//第一个参数都是方法名//第二个参数是可变参数,方法的形式参数类型的Class(字节码文件对象)Method method = clazz.getMethod("show");//方法本身就是空参System.out.println(method);//调用方法,Method类---提供的invoke//public Object invoke(Object obj, Object... args)//第一个参数:当前类实例//第二个参数:给方法的形式参数赋的实际参数//调用方法到时候将指定的方法实际参数作用在当前类实例上method.invoke(obj) ; //本身这个方法没有返回值,单独调用System.out.println("----------------------------------------------------------");/*** 反射调用这个* private void method(String str){*         System.out.println(str);*     }*/Method m1 = clazz.getDeclaredMethod("method", String.class);// System.out.println(m1);//private void com.qf.reflect_06.Person.method(java.lang.String)//私有方法取消Java语言检查m1.setAccessible(true) ;m1.invoke(obj,"hello,高圆圆") ;}
}

通过反射获取一个类的成员变量的类对象Field并去赋值

public class ReflectDemo2 {public static void main(String[] args)  throws Exception{//现在要通过反射获取成员变量的Field类对象并且去赋值//1)获取当前类的字节码文件对象Class clazz = Class.forName("com.qf.reflect_01.Person") ;//2)创建当前类实例Object obj = clazz.newInstance() ;System.out.println(obj) ;//3)通过字节码文件对象获取成员变量的Field类对象//获取公共的字段(成员变量)Field类对象//public Field getField(String name)throws NoSuchFieldException,SecurityException//参数是属性名称//获取指定的成员变量的Field类对象//public Field getDeclaredField(String name)throws NoSuchFieldException,SecurityException//private String name ; //私有的成员变量Field nameField = clazz.getDeclaredField("name");//取消Java语言访问检查nameField.setAccessible(true) ;
public class ReflectDemo {public static void main(String[] args) throws Exception {//需要使用Student类的love/* Student student = new Student() ;student.love();*///下一次业务代码需要更改----使用Worker类的功能Worker w = new Worker() ;w.love();//上面代码随着需求变化,可能需要用到不同类的某个的功能//导致代码改来改去,不灵活//设计原则---->"开闭原则" :对修改关闭,对扩展开放!// (对现有代码修改不好的,对现有带提供优化,扩展!)System.out.println("-------------------------------------------");//1)在当期类中读取src下面的xx.propertiesInputStream inputStream = ReflectDemo.class.getClassLoader().getResourceAsStream("classname.properties");//2)创建一个空的属性集合列表Properties prop = new Properties() ;//System.out.println(prop);//3)加载资源文件输入流的内容到属性集合列表中prop.load(inputStream);//System.out.println(prop);//{methodName=love, className=com.qf.reflect_02.Student}//4)通过属性集合列表中key获取valueString className = prop.getProperty("className");//System.out.println(className);String methodName = prop.getProperty("methodName") ;// System.out.println(methodName);//反射//获取当前类的字节码文件对象Class clazz = Class.forName(className) ;//创建当前类实例 无参构造方法系统提供Object obj = clazz.newInstance() ;//通过字节码文件对象获取类的成员方法Method类对象Method method = clazz.getMethod(methodName);//调用方法method.invoke(obj) ;}
}

日志的生成

 /* 自定义一个类----->代理实例 调用处理程序实现的接口** //就完成真实角色的里面的add(),update(),findAll(),detete()这些方法调用并进行增强*/
public class MyInvocationHandler  implements InvocationHandler {//目标对象--->真实角色private Object target ;public MyInvocationHandler(Object target){this.target = target ;}/*** 具体实现UserDao接口,调用里面的方法!完成业务方法增强* @param proxy* @param method 调用的方法 add(),update(),findAll(),detete()* @param args 这些方法实际参数* @return 从代理实例上的方法调用返回的值* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("权限校验") ;//反射调用Object obj = method.invoke(target, args);System.out.println("产生日志");return obj;}
}

mysql初步了解及应用

注释

– 单行注释
/多行注释/
#特殊注释

– 创建库

CREATE DATABASE 库名;
USE 库名;

– 创建表

CREATE TABLE student(
id INT , – 学生的编号
NAME VARCHAR(10), – 姓名
age INT , – 年龄
gender VARCHAR(3), – 性别
avg_socre DOUBLE(3,1), – 分数
adderss VARCHAR(50)
) ;

– 查询表的结果显示列名信息

DESC student ;

– DML语句:数据库操作语句

  • – 1.插入数据
    – 1)插入全表数据insert into 表名 values(值1,值2,值3,值3…值n);
    – 2)插入全表数据也支持一次插入多条
    – insert into 表名 values(值1,值2,值3,值3…值n),(值1,值2,…值n),(…) ;
  • – 2.修改数据
    – 2.1)带条件修改(一次修改一个或者多个)—>条件:一般都是非业务字段去修改
    – update 表名 set 字段名称= 值 where 字段名称= 值;
    – update 表名 set 字段名称1= 值1,字段名称2=值2,… where 字段名称= 值;
    修改的时候如果不带where条件,属于批量修改
  • – DML语句删除表的记录
    – 1)带条件删除
    – delete from 表名 where 字段名称 = 值; (条件一般使用非业务字段删除)
    – delete from 表名 where 字段名称1 = 值1 and 字段名称2 = 值2 …多个条件删除
    – 2)删除全表数据
    – delete from 表名; 是删除全表数据,表结构还在
    DELETE FROM student ;

– 删除全表数据:truncate table 表名;
TRUNCATE TABLE student ;
– 基本的查询:查询全表
– select * from 表名; – 代表全部字段 (实际开发中禁用)
– 模糊查询数据库每个端字符集
– show variables like ‘%character%’ ;
– set character_set_clinet/server/results=gbk ;在dos窗口就不乱码了
– 查询语句DQL语句—使用最频繁的
– 基本查询
– 1)查询全表:select 全部字段名称 from表名; 自己玩的—使用 select * from 表名;
– 2)带条件查询

 where 比较运算符 <=,>=,<,>,!=(在mysql使用 <>)and  && /or  ||between 值1 and  值2where 模糊条件 like关键字排序查询聚合函数查询分组查询筛选查询

– 查询指定字段如何去重呢?关键字distinct
– 查询住址字段
SELECT
DISTINCT address ‘住址’
FROM
student2;

基本带条件查询
where 比较运算符 <=,>=,<,>,!=(在mysql使用 <>),=赋值and  && /or  ||between 值1 and  值2

查询指定字段并指定别名

select
字段名称1 as 别名名称1,
字段名称2 as 别名名词2,

from
表名;

MySQL的DQL语句---->数据库查询语句(带条件查询分类)

– 查询某个字段为null的信息---->is null
– 查询字段不为null---->is not null
– 查询某个字段不等于某个值 —使用!=或者mysql的 <>
– 模糊查询mysql中所有的带有character字符集
SHOW VARIABLES LIKE ‘%character%’ ;
– DQL之模糊条件查询 — 关键字 like
– 语法 select 字段列表 from 表名 where 字段名称 like ‘%xx%’

* %:代表任意多个字符  (开发中使用居多)
_:代表任意一个字符
'字符%'  '%字符%'  也可以
– DQL之聚合查询 —>结果是单行单例的

COUNT(字段名称) ---->使用最多 统计表的记录
count里面 字段名称:一般非业务字段 (id:一般主键字段)
如果字段某个值是null,不会统计
max(列名称):求最大值
min(列名称):求最小值
avg(列名称):求当前列的平均值
sum(列名称):求当前这列的总和

– DQL语句之排序查询 order by

– 单独使用order by
– select 字段列表 from 表名 order by 字段名称 排序规则;
/
排序规则:默认asc ,升序排序
desc 降序
如果有条件where,还有order by,where在前面满足条件,才排序!
/

– DQL语句之分组查询 group by

/*
注意:
1)分组查询里面可以select 查询分组字段
2)分组group by后面不能使用聚合函数

*/
单独使用
select 字段列表 from 表名 group by 分组字段名称;

– 筛选having

/*
注意
having的后面可以跟聚合函数,having在group by ,
where是gruop by的前面;

*/

– 分页查询limit

select 字段列表 from 表名 limit 起始行数,每页显示的条数;
起始行数= (当前页码数-1)*每页显示的条数;

数据库约束 (限定用户操作数据库的一种行为)

– 约束

约束用户操作数据库的一种行为(非法行为)

  • 默认约束 default
    没有插入字段的值默认值null,为了防止这种数据出现,可以在创建表的时候
    加入默认约束default,当没有插入这个字段,默认约束起作用!
  • 非空约束 not null
    当前这个值不能为null,不能直接添加数据给一个null
  • 唯一约束 unqiue
    限制id字段/有效身份信息(邮箱/手机号/身份证…)
  • 删除唯一约束----(删除唯一索引的名称)
    alter table 表名 drop index 索引名(索引名如果没有起名字默认是列的名称);
  • 主键约束 primary key
    primary key —特点非空且唯一
    – 通过sql删除主键
    – alter table 表名 drop primary key ;
    ALTER TABLE test1 DROP PRIMARY KEY ;
    – 通过sql添加主键
    – alter table 表名 add primary key (列名称) ;
    ALTER TABLE test1 ADD PRIMARY KEY(id) ;
  • 自增长约束 auto_increment
    一般自增长约束都是在主键字段上,保证唯一
    指定插入数据的值,下次在之前的值上继续自增1
  • 外键约束 foreign key
    防止出现问题,添加外键约束—让两个产生关联关系
    有了外键之后,直接修改或者删除主表数据,前提需要让从表的数据跟主表没有关联
  • sql删除外键约束
    – alter table 表名 drop foreign key 外键名;
    ALTER TABLE employee DROP FOREIGN KEY dept_emp_fk ;
  • 级联操作cascade
    级联删除/级联修改 on delete cascade /on update casade
    – 当修改/删除主表的数据,从表数据随之改动

关于表和表的关系 / 数据库的三大范式(设计数据库)

1NF:第一范式 数据库表中每一列是不能在拆分的原子性!(最基本的要求)
(表中每一个列是单独的,不能在拆分)

2NF:第二范式
在满足1NF基础上,
1)一张描述一件事情
2)非主键字段必须完全依赖于主键字段
3NF:第三范式
在满足2NF基础上
非主键字段中间不能产生传递依赖
A字段—>依赖B字段—>依赖于C字段 A字段—>依赖C字段
学生表
学生id 学生的姓名 学生其他信息 学院id 学生所在的学院 系主任
学生表和选课

多表查询

 /*-- 多表查询-- 多张同时查询 /*
笛卡尔乘积
内连接
外连接
子查询:select 嵌套 select....情况1:单行单例的数据情况2  多行多列情况3:通过两个表的关系---查询出结果集---->当做"虚表"在和其他之间关联查询!*/CREATE DATABASE ee_2211_02;-- 设计一个部门表CREATE TABLE dept(id INT PRIMARY KEY AUTO_INCREMENT ,-- 部门编号NAME VARCHAR(10)                   -- 部门名称) ;INSERT INTO dept(NAME) VALUES('开发部'),('市场部'),("销售部") ;-- 设计员工表CREATE TABLE employee(id INT PRIMARY KEY AUTO_INCREMENT, -- 员工编号NAME VARCHAR(10),                  -- 姓名gender VARCHAR(3),                 -- 性别salary DOUBLE,                 -- 工资join_date DATE,                     -- 入职日期dept_id INT ,                      -- 部门编号-- 设置外键CONSTRAINT -- 声明dept_emp_fk  -- 外键名FOREIGN KEY (dept_id) -- 指定外键名作用从表的指定字段上REFERENCES  -- 关联dept(id));INSERT INTO employee(NAME,gender,salary,join_date,dept_id) VALUES('jojo','男',12000.0,'2021-11-11',1),('普奇神父','男',8000.0,'2022-05-28',1),('徐仑','女',7000.0,'2021-12-31',2),('汉库克','女',8000.0,'2021-10-30',3) ,('鸣人','男',3000.0,'2022-10-15',3),('黑崎一护','男',15000.0,'2022-9-30',1),('雏田','女',6000.0,'2021-10-10',3);-- 多表查询语法select 字段列表 from 表名1,表名2;-- 需求:查询员工表和部门表的所有信息
SELECT e.*,d.*
FROMemployee e,dept d ;
/*上面查询的结果不符合实际要求,7个员工,现在出现了21个
这个就是笛卡尔乘积,针对A表的记录 和B的记录数,两个表的记录相乘出现笛卡尔乘积的原因:没有设置连接条件!   针对多表查询1)查询哪张表!2)查询指定表的哪些字段!3)他们表和表之间的关系!
*/
-- 多表查之内连接()
/*隐式内连接:where条件---多去使用这种查!select    字段列表 from 表名1,表名2...表名nwhere    这些表之间的连接条件;
*/
-- 需求:查询员工表和部门表的所有信息
SELECT e.`id` '员工编号',e.`name` '姓名',e.`gender` '性别',e.`salary` '工资',e.`join_date` '入职日期',e.`dept_id` '员工所在的部门',d.id '部门编号',d.`name` '部门名称'
FROMemployee e,dept d
WHERE e.`dept_id` = d.`id` ;-- 内连接---显示内连接   (inner可以省略) join
/*select字段列表from 表名1(inner) join表名2on  连接条件
*/
-- 需求:查询员工的姓名,工资,入职日期以及各他的部门名称信息
SELECT e.`name` '姓名',e.`salary` '工资',e.`join_date` '入职日期',d.`name` '部门名称'
FROMemployee e JOIN dept d ON e.`dept_id` = d.`id` ;-- 插入一个员工
INSERT INTO employee(NAME,gender,salary,join_date)
VALUES('邓超','男',10000.0,'2022-10-20') ; -- 外连接
-- 左外连接(通用)
-- 将A表(左表)的和B表(右表)的交集以及A表(左表)中所有数据全部查询!
/*select 字段列表from左表名left (outer) join    -- outer可以省略   -- righter (outer) join 可以右外连接表名2on连接条件;
*/-- 查询所有的员工信息以及员工所在的部门名称信息,没有部门员工的也得查出来
/*
select e.*,d.`name` '部门名称'
from employee e,dept d
where e.`dept_id` = d.`id` ;*/
SELECT e.*,d.`name` "部门名称"
FROMemployee e LEFT OUTER JOIN dept d    -- outer可以省略ON e.`dept_id` = d.`id` ;-- 多表查询之子查询
-- 就是select去嵌套select
-- 情况1:使用where 后面条件表达式=,<=,>=.... -- 需求:查询员工工资最高的员工信息以及他的部门信息-- 1)查询最高工资是多少
SELECT MAX(salary) FROM employee ; -- 15000
-- 2)是15000的员工信息以及部门门信息
SELECT e.*,d.`name` '部门名称'
FROMemployee e,dept d
WHERE e.`dept_id` = d.`id` AND e.`salary` = 15000 ;-- 上面的sql一步走
SELECT e.*,d.`name` '部门名称'
FROMemployee e,dept d
WHERE e.`dept_id` = d.`id` AND e.`salary` = (SELECT MAX(salary) FROMemployee) ;-- 查询大于平均工资所有员工信息以及部门名称信息
-- 1)平均工资是多少
SELECT AVG(salary) FROM employee ; -- 8625
-- 2)查询员工表中员工工资大于8625的员工信息以及部门名称信息,没有部门的员工必须查(外连接)
SELECT e.*,d.`name` '部门名称'
FROM
employee e,
dept d
WHERE e.`dept_id` = d.`id` AND e.`salary` > 8625;-- 上面sql优化--一步走,查询出没有部门的员工---使用外连接
SELECT e.*,d.`name` '部门名称'
FROMemployee e,dept d
WHERE e.`salary` > (SELECT AVG(salary) FROMemployee) AND e.`dept_id` = d.`id` ;-- 情况2:利用in集合语句 (使用最多)
-- 需求:查询在"市场部"和销售部的员工信息-- 分步走
-- 1)查询市场部和销售部的部门编号SELECT id
FROMdept
WHERE NAME = '市场部' OR NAME = '销售部' ;
-- 2)查询员工表中在2或者3号部门的员工信息以及部门信息
SELECT e.*,d.`name` '部门名称'
FROM employee e,dept d
WHERE e.`dept_id` = d.`id` AND e.`dept_id` IN(2,3) ;-- 一步走
SELECT e.*,d.`name` '部门名称'
FROMemployee e,dept d
WHERE e.`dept_id` = d.`id` AND e.`dept_id` IN (SELECT id FROMdept WHERE NAME = '市场部' OR NAME = '销售部') ;-- 多表查询情况3:
-- 查询某个表的结果集----->
-- 当前"虚表"继续和其他进行关联查询(按照连接条件)
-- 查询入职日期大于"2021-11-11"后入职的员工信息以及部门名称信息-- 分步走
-- 1)查询入职日期大于"2021-11-11"后入职的员工信息
SELECT
*
FROM employee  e
WHERE e.`join_date` > '2021-11-11' ;
-- 2)在1)的结果集的基础上和部门表进行关联查询
SELECT t.name '员工姓名',t.join_date '入职日期',d.`name` '部门名称'
FROM(SELECT * FROMemployee e WHERE e.`join_date` > '2021-11-11') t LEFT JOIN dept d ON  t.dept_id = d.id ;   -- 左外连接,没有员工的部门需要查询-- 另一种写法(不考虑没有部门的员工)
SELECT e.*,d.`name` '部门名称'
FROMemployee e,dept d
WHERE e.`join_date` > '2021-11-11' AND e.`dept_id` = d.`id` ;

20221128-20221202周总结相关推荐

  1. 【OJ比赛日历】快周末了,不来一场比赛吗? #11.26-12.02 #13场

    CompHub 实时聚合多平台的数据类(Kaggle.天池-)和OJ类(Leetcode.牛客-)比赛.本账号同时会推送最新的比赛消息,欢迎关注! 更多比赛信息见 CompHub主页 或 点击文末阅读 ...

  2. 牛客网基础知识强化巩固-周结04

    链表强化训练 2022-11-28 打卡 知识点总结 磁盘字节和比特的问题 文件分配表FAT是管理磁盘空间的一种数据结构,用在以链接方式存储文件的系统中记录磁盘分配和跟踪空白磁盘块.整个磁盘仅设一张F ...

  3. Java 获取当前时间之后的第一个周几,java获取当前日期的下一个周几

    Java 获取当前时间之后的第一个周几,java获取当前日期的下一个周几 //获得入参的日期 Calendar cd = Calendar.getInstance(); cd.setTime(date ...

  4. 提高班第三周周记(中秋第一天)

    这是第三周,也是中秋节.没有月饼的中秋节.但我过得很充实.我很快乐,发自内心的. 中秋第一天早上贾琳师哥讲课.讲他为什么辞职来这里.他的确学成,有着令人羡慕的工资.可是他的问题让我触动. 提到了邓稼先 ...

  5. 《Java程序设计》第十一周学习总结

    20175334 <Java程序设计>第十一周学习总结 教材学习内容总结 第十三章 URL类 一个URL对象通常包含最基本的三部分信息:协议.地址.资源. URL对象调用 InputStr ...

  6. 20175320 2018-2019-2 《Java程序设计》第2周学习总结

    20175320 2018-2019-2 <Java程序设计>第2周学习总结 教材学习内容总结 本周学习了教材的第二章及第三章的内容.在这两章中介绍了Java编程中的基本数据类型与数组以及 ...

  7. 2018-2019-1 20165214 《信息安全系统设计基础》第六周学习总结

    20165214 2018-2019-1 <信息安全系统设计基础>第六周学习总结 教材学习内容总结 1.输入操作是从I/O设备复制数据到主存,而输出操作是从主存复制数据到I/O设备 2.U ...

  8. 2017-2018-1 20155204 《信息安全系统设计基础》第十一周学习总结

    2017-2018-1 20155204 <信息安全系统设计基础>第十一周学习总结 教材学习内容总结 9.1物理和虚拟地址 物理地址:计算机系统的主存被组织成一个人由M个连续的字节到校的单 ...

  9. 2017-2018-1 20155202 《信息安全系统设计基础》第9周学习总结

    2017-2018-1 20155202 <信息安全系统设计基础>第9周学习总结 第6章 存储器层次结构 教材学习内容总结 随机访问存储器(Random-AccessMem)分为两类:静态 ...

  10. 201621123030《Java程序设计》第4周学习总结

    1.本周学习总结 1.1写出你认为本周学习中比较重要的知识点关键词. 继承,多态,super关键字,final关键字,super关键字,Object,instanceof,重载 1.2 尝试使用思维导 ...

最新文章

  1. 边缘计算对于工业物联网的重要性
  2. 《算法竞赛入门经典》第一章1.5
  3. CSS 布局 - Overflow
  4. python单元格内换行_Python Pandas可防止单元格中的换行符
  5. Linux突然无法使用,是内存不足的问题
  6. IS-IS详解(十七)——IS-IS 区域迁移与路由汇总
  7. iOS 单个页面设置横屏
  8. Vite ---- 创建Vue3.0+TS项目
  9. google font 字体下载方式
  10. echarts考勤图表
  11. 自然辩证法小论文选题_★自然辩证法论文题目_自然辩证法毕业论文题目大全_自然辩证法论文选题参考...
  12. 几何图形经常使用的公式解读(三)
  13. Nginx配置带www域名转向无www域名
  14. NAND Flash(spi nand flash和nand flash)和emmc以及ufs通过uboot烧写固件的一些差异
  15. python考试名词解释_程序设计(python)_章节测验,期末考试,慕课答案查询公众号...
  16. Android:禁止APP录屏和截屏
  17. 获投5亿元E轮融资,百分点能否成为数据+AI领域的独角兽?
  18. Java如何判断一个上传文件的内容类型
  19. expdp和impdp需要注意的地方
  20. Common-Collections3

热门文章

  1. 基于virtuoso IC 618的LDO仿真实验
  2. 温州又一知名企业宣布倒闭破产
  3. iOS 获取当前时间之后N天的日期
  4. python 全栈开发,Day136(爬虫系列之第3章-Selenium模块)
  5. 【学术会议】如何rebuttal学术论文?
  6. arcgis如何打开tif_ArcGIS的目录、内容列表的布局
  7. 讨论-职场中年人,你的危机感都来源于哪里
  8. 面向对象程序设计实训——万年历
  9. 作为程序员,我到底在恐慌什么!
  10. ThinkSNS团队衍生产品你知道几个?