知识点总结(网络编程 ,MYSQL)

1:网络三要素:

ip地址/端口号/协议

2:使用UDP协议发送数据

1)创建发送端的socket对象

2)创建"数据报包"--里面包括:数据内容,ip地址,端口号

3)使用发送端的Socket对象发送"数据报包"

4)释放资源

public class UdpSend {
    public static void main(String[] args) throws Exception {
        //1)创建发送端的socket对象 ---java.net.DatagramSocket:此类表示用于发送和接收数据报数据包的套接字
        //public DatagramSocket()throws SocketException
        DatagramSocket ds = new DatagramSocket() ;

        //public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
        byte[] bytes = "hello,udp我来了".getBytes() ;
        int length = bytes.length ;
        InetAddress inetAddress = InetAddress.getByName("10.35.165.17") ;
        int port = 6666 ;
        DatagramPacket dp = new DatagramPacket(bytes,length,inetAddress,port) ;

   
        ds.send(dp) ;

        //释放资源
        ds.close();
    }
}

3:UDP优化

发送端不断键盘录入数据,接收端不断展示数据,在一个窗口中聊天!

使用多线程的方式:开启两条线程,一条线程:发送端发送数据

另一条线程:接收端不断接收数据,展示数据

public class ChatRoom {
    public static void main(String[] args) {
        try {
            //创建发送端Socket
            DatagramSocket sendDs = new DatagramSocket() ;
            //创建接收端的Socket
            DatagramSocket receiveDs = new DatagramSocket(10086) ;
            //创建发送端的线程所在的资源类对象
            SendTread st = new SendTread(sendDs) ;
            //创建接收端的线程所在资源类对象
            ReceiveThread rt  =  new ReceiveThread(receiveDs) ;

            //创建线程
            Thread t1 = new Thread(st) ;
            Thread t2 = new Thread(rt) ;

            //启动线程
            t1.start();
            t2.start();
         } catch (SocketException e) {
            e.printStackTrace();
        }
    }
}
 接收端的资源类
 */
public class ReceiveThread  implements Runnable{
    private DatagramSocket ds ;
    public ReceiveThread(DatagramSocket ds){
        this.ds = ds ;
    }
    @Override
    public void run() {
        try {
            //不断的展示数据
            while(true){
                //接收数据:接收容器
                byte[] buffer = new byte[1024] ;
                DatagramPacket dp = new DatagramPacket(buffer,buffer.length) ;
                //接收
                ds.receive(dp) ;

                //解析缓冲区(接收容器)的数据
                String message = new String(dp.getData(),0,dp.getLength()) ;
                //获取ip地址
                String ip = dp.getAddress().getHostAddress() ;
                System.out.println("data from --->"+ip+",content is--->"+message);

            }
        } catch (IOException e) {
            e.printStackTrace();

        }
        //接收端不需要释放资源,一直开启状态
    }
}
 发送端的资源类
 */
public class SendTread  implements Runnable{

    private DatagramSocket ds ;
    public SendTread(DatagramSocket ds){
        this.ds = ds ;
    }

    @Override
    public void run() {
        try {
            //键盘录入数据--->BufferedReader
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(System.in)) ;
            String line = null ;
            while((line=br.readLine())!=null){
                //数据报包:将数据发送接收端
                DatagramPacket dp = new DatagramPacket(
                        line.getBytes(),
                        line.getBytes().length,
                        InetAddress.getByName("10.35.165.17"),
                        10086) ;

                //发送数据
                ds.send(dp) ;

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ds.close();
        }
    }
}

4:TCP和UDP的区别

1)是否建立连接通道

        TCP需要建立连接通道的

        UDP不需要建立连接通道

2)是否是可靠连接

        TCP是可靠连接,---同步的---执行效率低

        UDP是不可靠连接,---不同的--->执行效率高

3)是否传输数据大小有限制

        TCP是无限制传输,以一种"字节流"的方式

        UDP有数据大小限制(理论值64kb),以一种"数据报包"的方式

5:TCP方式来发送和接收数据

1)创建TCP协议这种方式的客户端的socket对象

2)写数据---写给服务器

3)关闭资源

public class TCPClient {
    public static void main(String[] args) throws IOException {
        //1)创建TCP协议这种方式的客户端的socket对象
        //java.net.Socket -->public Socket(String host,int port)
        Socket socket = new Socket("10.35.165.17",6666) ;

        //2)写数据---写给服务器
        //获取客户端通道内的输出流对象,写数据
        //public OutputStream getOutputStream()
        OutputStream out = socket.getOutputStream() ;
        out.write("hello,TCP我来了".getBytes());

        //3)释放资源
        socket.close();

    }
}
/**
 * TCP服务器端
 *  1)创建服务器端的Socket对象-->绑定端口
 *  2)服务器端监听客户端连接--->获取到指定客户端的Socket对象
 *  3)获取通道的内输入流--->读数据
 *  4)关闭服务器端的Socket对象
 */
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1)创建服务器端的Socket对象-->绑定端口
        //public ServerSocket(int port)throws IOException
        ServerSocket ss = new ServerSocket(6666) ;
        System.out.println("正在等待客户端连接......");

        //2)服务器端监听客户端连接--->获取到指定客户端的Socket对象
        //public Socket accept()throws IOException:
        Socket socket = ss.accept();
        System.out.println("客户端已连接...");

        //3)获取监听到当前客户端的通道的内输入流--->读数据
        //public InputStream getInputStream()throws IOException
        InputStream inputStream = socket.getInputStream();
        //一次读取一个字节数组
        byte[] bytes = new byte[1024] ;
        int len = inputStream.read(bytes);

        //4)展示数据
        String message = new String(bytes,0,len) ;
        //获取ip地址
        //public InetAddress getInetAddress()
        String ip = socket.getInetAddress().getHostAddress() ;

        System.out.println("data from is ---->"+ip+",data is--->"+message) ;

        //5)释放资源
        ss.close();

    }
}

6:TCP客户端不断的去发送消息,服务器端不断的去接收数据,展示数据(服务器端不关闭)

public class TCPClient {

    public static void main(String[] args) {

        BufferedReader br = null ;
        Socket s  = null ;
        try {
            //创建客户端的Socket
            s = new Socket("10.35.165.17",10086) ;

            //客户端不断键盘录入数据--->BufferedReader一次读取一行
            br = new BufferedReader(
                    new InputStreamReader(System.in)) ;

            //获取客户端所在的通道内的字节输出流----OutputStream-->封装成字符缓冲输出流
            OutputStream outputStream = s.getOutputStream();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream)) ;
            //一次读取一行
            String line = null ;
            while((line=br.readLine())!=null){

                bw.write(line) ;//写一行,通过封装后的通道的字符输出流写进去
                bw.newLine() ; //换行
                bw.flush() ; //刷新
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(s!=null){
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/**
 *服务器端不断的去接收数据,展示数据(服务器端不关闭)
 */
public class TCPServer {
    public static void main(String[] args) {
        try {
            //创建服务器端的Socket对象
            ServerSocket ss = new ServerSocket(10086)  ;
            //监听客户端连接
            Socket s = ss.accept();
            //封装通道内的字节输入流
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(s.getInputStream())) ;
            String line = null ;
            while((line=br.readLine())!=null){
                //服务器自定义结束条件
                if("886".equals(line)){
                    break ;
                }
                //展示数据
                System.out.println("数据来自于"+s.getInetAddress().getHostAddress()+"内容是:"+line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

7:多线程进行图片上传 不断发送不断接收

public class TCPClient {
    public static void main(String[] args) {
        Socket s  = null ;
        FileInputStream fis = null ;

        try {
            //创建客户端的Socket
            s = new Socket("10.35.165.17",10086) ;

            //客户端创建一个字节输入流--->FileInputStream
            fis = new FileInputStream("D:\\高圆圆.jpg") ;

            //获取通道内的字节输出流,写数据
            OutputStream outputStream = s.getOutputStream();
            //一次读取一个字节数组
            byte[] bytes = new byte[1024] ;
            int len = 0 ;
            while((len=fis.read(bytes))!=-1){
                outputStream.write(bytes,0,len) ;
                outputStream.flush() ;
            }

            s.shutdownOutput(); //告知服务器,文件已经完成写入完毕,没有流数据过去了

            //读取服务器端反馈的数据
            InputStream inputStream = s.getInputStream();
            byte[] buffer = new byte[1024] ;
            int length = inputStream.read(buffer);
            String fkMsg = new String(buffer,0,length) ;
            System.out.println("fkMsg:"+fkMsg);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(s!=null){
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}
/**
 * 接收多个客户端的图片文件,并给出反馈 "图片上传完毕"
 */
public class Server {
    public static void main(String[] args) {

        try {
            //创建服务器端的Socket
            ServerSocket ss = new ServerSocket(10086) ;
            //监听多个客户端连接
            while(true){
                Socket socket = ss.accept();
                //开启线程---->完成读取客户端上传的图片文件,保存到指定的磁盘上
                new Thread(new UploadImageThread(socket)).start();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class UploadImageThread  implements Runnable{
    //声明Socket
    private Socket s ;
    public UploadImageThread(Socket s){ //传入获取到监听到多个客户端对象
        this.s = s ;
    }
    @Override
    public void run() {

        FileOutputStream fos = null ;

        try {
            //获取通道内的字节输入流
            InputStream in = s.getInputStream();
            //处理---同一个客户端上传的图片内容一致,但是图片名称不一致,导致之前的图片可以覆盖
            //解决上面这个问题
            String ip = s.getInetAddress().getHostAddress();
            File file = new File(
                    "D:\\EE_2302\\day29\\code\\images"+
                            ip+".jpg")  ; //10.35.165.30.jpg
            //定义一个统计变量
            int num = 1 ;
            //判断:如果file存在,---路径形式已经有了                   10.35.165.30(1).jpg
            if(file.exists()){
                file = new File("D:\\EE_2302\\day29\\code\\images"+ip+"("+(num++)+").jpg") ;
            }

            //指定保存的目录
            fos = new FileOutputStream(file) ;
            //一次读取一个字节数组
            byte[] bytes  = new byte[1024] ;
            int len = 0 ;
            while ((len=in.read(bytes))!=-1){
                fos.write(bytes,0,len) ;
                fos.flush() ;
            }


            //反馈给客户端
            //获取通道内的输出流
            OutputStream out = s.getOutputStream();
            out.write("图片上传完成".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(s!=null){
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

8:什么是反射?

一个类在加载运行状态的时候,可以动态获取正在运行的类(Class)

创建正在运行类的对象(构造器-Constructor)

使用正在运行的这个类的对象去给 成员变量赋值(Field)

调用正在运行的这个类中成员方法(Method)

9:现在通过反射获取指定的类的字节码文件对象并去给类的成员变量进行赋值

public class ReflectDemo3 {

    public static void main(String[] args) throws Exception {

        //获取当前类的字节码文件对象
        Class c = Class.forName("com.qf.reflect_02.Person") ;
        //Person类的无参构造方法本身就公共的
        //两种方案创建类的实例
        //1)获取这个类的无参构造方法所在的Constructor--->T newInstance()
       /* Constructor constructor = c.getConstructor();
        Object obj2 = constructor.newInstance();
        System.out.println(obj2);*/
        //2)可以直接使用当前类的字节码文件对象Class--->public T newInstance()
        Object obj = c.newInstance();
        System.out.println(obj);


        //通过这个类Class字节码文件对象获取当前类的指定的成员变量的Field类对象
        //public Field getDeclaredField(String name) 参数:这个类的属性名称
        Field nameField = c.getDeclaredField("name");
        //System.out.println(nameField);

        //取消Java语言访问检查功能
        nameField.setAccessible(true) ;
        //Field:代表类的字段(成员变量)
        //public void set(Object obj,Object value):将指定的value实际参数作用在指定的当前类的实例上
        nameField.set(obj,"高圆圆") ;//java.lang.IllegalAccessException:非法访问:name 是私有的
        System.out.println(obj) ;

        System.out.println("-------------------------------------------") ;
        //age/address进行赋值
        //获取指定age字段的Field类对象
        Field ageField = c.getDeclaredField("age");
        //取消Java语言访问检查
        ageField.setAccessible(true) ;
        //赋值
        ageField.set(obj,44) ;
        System.out.println(obj);

        System.out.println("--------------------------------") ;
        Field addressField = c.getDeclaredField("address");
        //取消Java语言访问检查
        addressField.setAccessible(true) ;
        //赋值
        addressField.set(obj,"鄠邑区") ;
        System.out.println(obj) ;
    }
}

10:动态获取指定类的字节码文件对象,创建当前类实例,调用里面的指定的成员方法!

public class ReflectDemo4 {

    public static void main(String[] args) throws Exception{
        System.out.println("-------------之前的写法-----------") ;
        Person p = new Person() ;
        p.show("helloworld") ;

        System.out.println("------------------反射的方式-------------------------");

        //1)获取指定类的字节码文件对象
        Class c = Class.forName("com.qf.reflect_02.Person") ;
        //2)无参构造方法公共的,Person类中,字节创建当前类实例
        Object obj = c.newInstance() ;
        //public Methods[] getMethods():获取这个类的所有的公共的成员方法的类对象Method(包括继承过来的以及实现接口的方法)
        //public Methods[] getDeclaredMethods():获取类所有的的指定的成员方法的类对象Method,不包括继承过来的

        //3)获取指定的公共成员方法
        //public Method getMethod(String name,Class<?>... parameterTypes)
        //参数1:方法的名称
        //参数2:当前方法中参数类型的Class
        Method m = c.getMethod("show", String.class);//参数2:java.lang.String
        //System.out.println(m);

        //4)调用方法
        //Method--->public Object invoke(Object obj,Object... args)
        //参数1:这个类的实例
        //参数2:方法中传入的实际参数
        m.invoke(obj, "helloworld");//本身这个方法没有返回值,可以不写;有返回值,使用Object类型接收

        System.out.println("-------------------------------------------------") ;
        //调用method方法
        //获取指定的成员方法所在的类对象Method
        //public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
        Method m2 = c.getDeclaredMethod("method", int.class) ;
        //System.out.println(m2) ;

        //取消Java语言检查
        m2.setAccessible(true) ;
        //调用方法
        Object returnObj = m2.invoke(obj, 100);
        System.out.println(returnObj);

        //其他方法调用



    }
}

11:MYSQL语句

1:启动MYSQL
net start mysql57
2:关闭MYSQL
net stop mysql57
3:进入MYSQL
mysql -uroot -p
密码:123456
4:查询所有库
mysql> show databases;
5:创建一个新的数据库
create database 库名;  直接创建
 6:判断不存在库才创建
create database if not exists 库名;  
7:查看创建指定库的字符集编码格式
show create database 库名;
8:修改指定库的字符集格式
alter database 库名 (default) character set 字符集格式;
9:删除库
drop database 库名; 直接删除
10判断存在库名,直接删除
drop database if exists 库名;
11:进入到指定的库中--使用这个库
use 库名;
12:字段的查询正在使用库的函数
select database() ;
13:创建表的语法----创建表之前,选库(use 库名;)
create table 表名(
字段名称1 字段类型1,
字段名称2 字段类型2,
字段名称3 字段类型3,
...,
字段名称n 字段类型n) ;
创建一个学生表
create table student(
-> id int,
-> name varchar(10),
-> age int,
-> gender varchar(3),
-> address varchar(50),
-> birthday date);
14:查询库中的所有表
show tablse;
15:查询表的结构:查询这个表的"列"有哪些
desc 表名;
16:修改表---修改的表的字段名称(列的名称)
alter table 表名 change 以前的字段名称 现在的新的字段名称 以前的字段类型;
17:修改表---修改表的字段类型
alter table 表名 modify address 对应的新的字段类型;
18:修改表---给表中添加一个新的字段名称(新的列)
alter table 表名 add 字段名称 字段类型;
19:修改表---将表中的字段名称删除
alter table 表名  drop 字段名称;
20:复制一张一模一样的表
create table 新的表名 like 旧表名;
21:删除表
drop table 表名 ;直接删除
22:如果存在这个表,删除
drop table if exists 表名;
23:给表中插入全表记录: 每一个值需要和当前字段类型一致
insert into 表名 values(值1,值2,值3,....值n) ;
例子:INSERT INTO student VALUES(1,'张三丰',50,'1997-03-10','西安市南窑国际','男') ;
24:插入全表记录:一次性插入多条
-- insert into 表名 valeus(值1,值2,值3...值n),(值1,值2,值3...值n),(...) ;
INSERT INTO student VALUES(2,'高圆圆',44,'1981-10-30','鄠邑区','女'),
(3,'李国栋',23,'1996-11-20','南窑国际','男') ;
25:插入部分字段,没有插入字段的值默认值null
-- insert into 表名(字段名称1,字段名称2,部分字段) values(值1,值2,部分字段值),(值1,值2,部分字段值) ;
例子:INSERT INTO student (id, NAME, age, birthday)
VALUES
(4, '王宝强', 35, '1985-02-28'),
(5, '文章', 34, '1982-10-11') ;
26:删除id为6的学生信息
DELETE FROM student WHERE id = 6 ; -- id:非业务字段(每一个表都有id:唯一的)
27:删除名称为高圆圆的学生信息 (通过业务字段删除)+附件条件   同时年龄20 的
DELETE FROM student WHERE NAME = '高圆圆'  &&  age = 20 ;
DELETE FROM student WHERE NAME = '高圆圆'  AND  age = 20 ;
28:不带条件删除
-- delete from 表名; :删除全表记录
DELETE FROM student ;
29:删除全表记录的:truncate table 表名
TRUNCATE  TABLE student ;
30:面试题
删除全表
delete from 表名和truncate table 表名的区别?
共同点:
    delete from 表名和truncate table 表名都是删除全表的数据
不同点:
    delete from 表名:仅仅只是删除表的记录,表的结构还在(约束相关的信息也就在)
    不影响自增主键id的值,下一次插入数据之后,id值在上一次基础上继续自增!
    truncate table 表名:不仅仅删除全表的记录,
    会将表删除(表的结构都存在了),会自己创建一张结构一一的空表
    直接影响自增长主键id 的值;
31:mysql内置函数:可以获取最后一次自增长的id值
-- 插入之后,记录最后一次自增长id的值
SELECT LAST_INSERT_ID() ;
32:修改表的记录 update关键字
-- 1)不带条件(where)修改,属于 "批量修改" (不推荐)
-- update 表名 set 字段名称 = 值 ;或者 update 表名 set 字段名称1= 值1 ,字段名称2 = 值2;
33:修改name是"高圆圆"
UPDATE student SET NAME = '高圆圆' ,age= 18  ;
34:推荐:带条件修改
-- update 表名 set 字段名称 = 值;
-- update 表名 set 字段名称1 = 值1,字段名称2=值2,...字段名称n = 值n where 非业务字段名称= 值;
-- 需求:需要修改id为3的姓名是"张佳宁",年龄是33,地址是"鄠邑区",性别为女
UPDATE
student
SET
NAME = '张佳宁',
age = 33,
address = '鄠邑区',
gender = '女'
WHERE id = 3 ;
35:查询的时候给字段名称起别名
-- select 字段名称1 as 别名1,字段名称2 as 别名2...from 表名; (as可以省略不写)
SELECT
id '学号',
NAME '姓名',
age '年龄',
sex '性别',
address '地址',
math '数学成绩',
english '语文成绩'
FROM
student3 ;
36:基本select查询,去除重复的字段值
-- (字段名称前面加上DISTINCT:去除重复字段值)
-- 或者distinct(字段名称)
-- 查询adress信息
SELECT DISTINCT address '地址' FROM student3;
37:int类型字段进行求和,如果某个字段值是null,结果是null(没有意义)
使用mysql自带的函数:
ifnull(字段名称,预期值) ;如果当前字段值是null,给一个预期值
SELECT
NAME '姓名',
(math + IFNULL(english,0)) '总成绩'
FROM
student3 ;
38:DQL之条件查询
1)基本条件 where条件
赋值运算符    
比较运算符:<,><=,>=,!=,<>,BETWEEN 值1 AND 值2
逻辑运算符:&& ||  and  or
39:需求:年龄是20岁的学生所有信息
SELECT
id '编号',
NAME '姓名',
age '年龄',
sex '性别',
address '地址',
math '数学',
english '英语'
FROM
student3
WHERE age = 20 ;
40:需求:年龄是20岁的学生所有信息
SELECT 
  id '编号',
  NAME '姓名',
  age '年龄',
  sex '性别',
  address '地址',
  math '数学',
  english '英语' 
FROM
  student3 
WHERE age = 20 ;
41:查询年龄小于等于20岁的学生信息
SELECT 
  * 
FROM
  student3 
WHERE age < 20 || age = 20 ; -- ||逻辑符号以及比较运算符

SELECT 
  * 
FROM
  student3 
WHERE age < 20 OR age = 20 ;  
42:查询年龄 30岁到55岁之间的所有学生信息
SELECT 
    *
FROM
    student3
WHERE 
    age >= 30 && age <=55 ;
-- 建议连接并列条件,and 连接
SELECT 
    *
FROM
    student3
WHERE 
    age >= 30 AND age <=55 ;
    
-- between 值1 and 值2;
SELECT 
  * 
FROM
  student3 
WHERE age BETWEEN 30 
  AND 55 ;

43:查询年龄不是20岁的学生信息
SELECT 
  * 
FROM
  student3 
WHERE age != 20 ;


SELECT 
    *
FROM 
    student3 
WHERE 
    age <> 20 ;
44:聚合函数:查询出来结果:单行单列的数据
-- count(字段名称):统计总条数 --->count(非业务字段) :统计总记录数
-- max(字段名称):最大值
-- min(字段名称):最小值
-- avg(字段名称):平均分
-- sum(字段名称):求和
45:需求:查询学生的总人数
select
count(id) '总记录数
from
student3;
46:是99分的学生信息
SELECT
*
FROM 
    student3
WHERE 
    math = 99 ;
47:英语平均分是多少
SELECT
AVG(IFNULL(english,0)) '英语平均分'
FROM
student3 ;
48:模糊查询(重点)
-- 应用场景:前端搜索框---输入 "关键字"---进行搜索
-- select 字段列表 from 表名 where 字段名称 like '%关键字%' ;     '关键字%'
-- %:代表任意字符
-- _:代表一个字符
49:查询student3中所有的姓马的人
SELECT
*
FROM
student3
WHERE NAME LIKE '马%' ;-
50:查询student3中姓名是3个字符的人
SELECT 
  * 
FROM
  student3 
WHERE NAME LIKE '___' ;

51:mysql 查询全局的字符集的命令
SHOW VARIABLES LIKE '%character%' ;
1:DQL语句其他的语法
-- 条件查询---in关键字 (值1,值2,值3,,,值n) ; 代表多个or连接(多个并集查询)
-- 需求:查询student3表中年龄是18或者30或者45岁的学生的所有信息
SELECT 
  * 
FROM
  student3 
WHERE age IN(18,30,45) ; 
2:条件查询:查询指定的字段是null的信息
-- select 字段列表 from 表名 where 某个字段名称 is null ;
-- 需求:查询student3表中english是null的学生的所有信息
SELECT 
*
FROM 
student3
WHERE english IS NULL ;
3:查询某个字段不是null的信息: is not null
-- 需求: 查询英语成绩不是null的学生的所有信息
SELECT 
  * 
FROM
  student3 
WHERE english IS NOT NULL ;

4:DQL语句之排序查询
-- select 字段列表 from 表名 order by  字段名称  排序规则;
-- 排序规则:默认值asc :升序
--        desc:降序
-- 多个排序条件
-- select 字段列表 from 表名 order by 字段名称1 排序规则,字段名称2 排序规则...;
-- 需求:查询学生的所有信息,同时 数学成绩降序,英语成绩升序 获取学生所有信息
SELECT 
  * 
FROM
  student3 
ORDER BY math DESC,
  english ASC ;
  
   需求:查询数学成绩大于70分的学生的所有信息并且进行升序排序
-- where 在 order by的前面 
SELECT 
*
FROM 
student3
WHERE math > 70
ORDER BY math ASC ;

5:筛选having
一个sql语句,where条件,有分组group by ,有having(它的后面可以跟聚合函数)
依次先后顺序,先满足where,在分组,分组基础上进行筛选
-- 需求:查询(分组信息/数学平均分/人数大于2的) 学生的数学成绩大于70分的参与分组(按照性别分组)
-- 同时,筛选出某组人数大于2的一组!
SELECT 
  sex '性别', -- 查询分组字段
  AVG(math) '数学平均分',
  COUNT(id) '总人数'  -- 查询满足筛选条件的信息
FROM
  student3 
  
WHERE math > 70 
GROUP BY sex 
HAVING 
COUNT(id)> 2 ;
6:DQL语句分页查询
-- limit关键字
-- 语法:select 字段列表 from  表名 limit 起始行数,每页显示的条数;
-- 起始行数:从0开始 --- = (当前页码数-1)*每页显示的条数;
-- 实际开发中:页码数currentPage/每页显示的条数pageSize (必须已知数据:前端传来的)
-- student3:9条数据,已知:每页显示2条,
student3的第一页的数据;
SELECT * FROM student3  LIMIT 0,2 ;
-- 第二页数据
SELECT * FROM student3 LIMIT 2,2 ;
-- 第三页数据
SELECT * FROM student3 LIMIT 4,2;
-- 第四页数据
SELECT * FROM student3 LIMIT 6,2 ;
-- 第五也数据
SELECT * FROM student3 LIMIT 8,2;
查询 这个表的时候限制指定的条数
-- select * from 表名 limit 值;
SELECT * FROM student3 LIMIT 4;
7:数据库的备份和还原
DBA(数据库管理员) 设计完数据库,对库中的所有的数据以及结构进行备份;
防止数据库的信息丢失等等
数据库还原:就是将备份库 加载已知存在的库中(使用备份好.sql脚本文件,执行这个sql脚本)
备份和还原:
1)命令行方式的备份(dos管理员的运行)
mysqldump -uroot -p输入密码 库名称 > 指定磁盘路径 "d:\mysql_dump\xx.sql文件"
1)命令行方式的还原:
1.1)dos登录mysql,将之前的库删除
1.2)新建一个新的库,使用库
1.3)source  执行本地或者远程路径上的.sql文件 (加载指定的sql脚本文件)
    2)使用图形界面化工具去备份和还原
    任何的图形界面化工具都是一样的
    备份:
        在已知的库上右键---backup--->backup SQL 备份到本地磁盘上的sql脚本
     还原:删除已知库,新建库,使用库,  存在库上右键--->import--->选择执行 execute SQL script 本地sql文件
8:数据库的约束
-- 约束:限制用户操作数据库的行为
-- 举例:插入数据的时候,直接插入null值(这个字段是业务字段,是null,,没有意义)
-- 通过约束将上面的用户插入非法数据的行为进行限制!
9:默认约束:default
CREATE  TABLE test(
    id INT,    -- 编号
    NAME VARCHAR(10), -- 姓名
    gender VARCHAR(3) DEFAULT '女' -- 性别  使用默认约束default关键字
) ;
INSERT INTO test(id,NAME) VALUES(3,'张佳宁') ; 性别默认女
INSERT INTO test(id,NAME,gender) VALUES(4,'刘亦菲',NULL) ; -- 直接插入null值,default无法约束

10:非空约束not null
CREATE TABLE test(
    id INT ,       -- 编号
    NAME VARCHAR(10) NOT NULL , -- 姓名 不能为空
    address VARCHAR(50) NOT NULL -- 地址 不能为空
);

INSERT INTO test VALUES(1,'张三丰','武当山'),(2,'令狐冲','泰山') ;
-- 用户直接插入null值(非法数据),加入约束之后:Column 'name' cannot be null
INSERT INTO test VALUES(3,'王五','西安') ;
-- insert into test(id,name) values(4,'李国栋') ;-- 非空约束,不给字段数据,会出现错误
11:唯一约束unique不能重复
CREATE TABLE test(
id INT,        -- 编号
NAME VARCHAR(10), -- 姓名
telephone VARCHAR(11) UNIQUE -- 手机号 创建表,给手机号添加唯一
12:通过sql语句更改表,删除唯一删除
正常语法:alter table 表名 drop index 唯一约束的名称 (默认和当前的字段名称一致)
ALTER TABLE test DROP INDEX telephone ;
13:通过sql添加唯一约束
alter table 表名 add constraint(声明) 唯一约束索引的名称  unique(给哪个字段名称);
ALTER TABLE testADD CONSTRAINT unique_telephone UNIQUE (telephone) ;
14:主键约束 primary key
特点:非空且唯一
不能直接插入null值,不能重复
primary key 作用每一张表的id(非业务字段,设置为主键)
CREATE TABLE test(
    id INT PRIMARY KEY AUTO_INCREMENT,  -- 创建表的时候添加主键,同时自增长
    NAME VARCHAR(10)
);
INSERT INTO test(NAME) VALUES('张三'),('李四') ;
INSERT INTO test VALUES(1,'王五') ;-- id重复 无法添加
INSERT INTO test VALUES(NULL,'赵六') ;-- 直接插入null值 .无法获取
sql语句直接主键删除
-- alter table 表名 drop primary key ; -- 将唯一删除,not null非空还存在
ALTER TABLE test DROP PRIMARY KEY  ;

-- sql语句添加主键约束(唯一特性加上)
-- alter table 表名 modify id int PRIMARY KEY ;
ALTER TABLE test MODIFY id INT PRIMARY KEY ;

-- 一般主键约束和自增长约束auto_increment,一块用
-- 插入数据insert into 之后,id值不断自增1!

15:员工表的 dept_id关联dept部门表id字段---外键约束
外键所在的表---从表的某个字段依赖于主表的主键字段
部门表:主表
员工表:从表
CREATE TABLE employee (
  id INT PRIMARY KEY AUTO_INCREMENT,
  -- 员工编号
  NAME VARCHAR (10),
  -- 员工姓名
  gender VARCHAR (3),
  -- 员工性别
  salary DOUBLE,
  -- 工资
  dept_id INT,
  -- 所在的部门编号
  -- 声明 
  CONSTRAINT -- 外键名称:主表名_从表名_fk
  dept_emp_fk -- 外键作用在哪个字段上
  FOREIGN KEY (dept_id) -- 关联
  REFERENCES -- 主表的主键字段(就是id)
  dept(id)
) ;
(NAME,gender,salary,dept_id)
VALUES('高圆圆','女',8000.0,1),
('文章','男',6500.0,2),
('李国栋','男',10000.0,3),
('马保国','男',6000.0,4),
('张三丰','男',9500.0,2),
('邓超','男',7000.0,3),
('张佳宁','女',9500.0,2);
删除id为4号部门
-- delete from dept where id = 4;  -- 4号部门有员工--Cannot delete or update a parent row:

-- 将4号部门的员工先删除,(没有关联了),在删除主表数据
DELETE FROM employee WHERE dept_id = 4 ;
DELETE FROM dept WHERE id = 4 ;

-- 将1号部门修改为5号部门
-- update dept set id = 5 where dept_name = '运维部' ; -- 也不能直接修改
-- 将2号部门的员工修改为 "其他部门"
UPDATE employee SET dept_id = 2 WHERE  NAME = '高圆圆' ;
-- 修改主表将1号--5号
UPDATE dept SET id = 5 WHERE dept_name = '测试部' ;
UPDATE employee SET dept_id = 5 WHERE NAME = '高圆圆' ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值