摘要 :

本周感觉学的好多,网络编程UDP/TCP网络协议,通信读取传输文件,反射的思想,相关方法,JDK动态代理,数据库DDL数据库定义语句,DML数据库操作语句,DQL数据库查询语句,以及6种约束和级联;
让我们放弃前行的到底是[懦弱]还是[满足]. 我跑啊跑啊就是为了追上曾经那个被赋予众望的自己.

文章目录

  • 网络编程(Socket 编程)
    • Properties 属性集合列表(回顾)
    • 网络编程的三要素
    • java.net.InetAddress:代表的是互联网ip地址对象
    • UDP发送端和接收端代码实现
    • UDP接收端代码实现
    • UDP发送端代码实现
    • TCP客户端和服务器端代码实现(重点)
    • TCP服务器端步骤
    • TCP客户端:
    • UDP和TCP的区别?
    • 练习
  • 反射的核心思想---以后会被封装到框架里(掌握格式)Spring(IOC技术)
    • 反射的第二个应用(通过读取配置文件,优化代码)
    • JDK动态代理
  • MySQL数据库
    • 针对表的操作里面涉及的数据类型
    • DDL数据库定义语句
    • DML语句:数据库操作语句
    • DQL语句:数据库查询语句
    • 数据库的备份和还原
    • 数据库的约束
    • 数据库的三大范式(设计层面--- 理论) 面试题
    • 多表关系以及多表查询
    • 数据库的事物 transaction

网络编程(Socket 编程)

所谓 Socket 编程,其实就是在串联 应用层传输层以达到我们的需求目的。主要就是在操作 传输层的协议,而我们主流的传输层协议就是 TCP 和 UDP 所以重点关注这两个协议即可。

Properties 属性集合列表(回顾)

继承自Hashtable,实现一个接口Map,它比较特殊,它没有泛型,它里面的键和值都是
String; 最大特点:它和流息息相关
它首先能够使用的功能就map的功能:
添加键值对 :put(K k,V v)
遍历属性列表:
Set<Object> keySet():获取所有的键集
V get(K key):通过键获取值
特有功能:
setProperty(String key,String value):添加属性的键和值
Set<String> stringPropertyNames() :获取所有的键
String getProperty(String key):通过键获取值
还可以将文件的内容加载到属性列表中(当前项目基本传统文件.txt/src下面
的.properties配置文件)
void load(InputStream in)
void load(Reader r)
还可以将属性列表中的内容保存到指定的文件中
void strore(OutputStream out,String commenets):参数2:属性列表的描述
void strore(Writer w,String comments)
//如何读取src下面的配置文件(project的src)
//1)在src下面有一个xxx.properties --->里面记录了key=value键值对
class MyTest{public static void main(String[] args){//需要 项目下的在MyTest中读取src下面的xxx.properties
//分步走
//1)Class 字节码文件对象= 当前类名.class;
//2)类加载器 类加载器对象 = 字节码文件对象.getClassLoader();
//3)InputStream inputStream = 类加载器对
象.getResourceAsStream("资源文件名称.properties") ;
//一步走
InputStream inputStream =
MyTest.class.getClassLoader().getResourceAsStream("xxx.properties") ;
//通过集合列表对象
Properties prop = new Properties() ;
prop.load(inputStream) ;
//属性列表中就有内容了,配置文件中就可以通过key获取vlaue,获取每一
个内容
// zhangsan=30
// lisi=40
}
}

网络编程的三要素

ip地址:----->点分十进制法 192.168.1.10
分类:
A类 :前面一个号段为网络号段,后面三个主机号段
B类:前面两个号段为网络号段,后面两个主机号段
C类:私人地址:前面三个是网络号段,后面一个主机号段
port端口:
范围:0-65535
物理端口和逻辑端口
物理端口:网卡口号
逻辑端口: 常说的具体的端口—360软件可以看到每一个电脑上的软件
的端口
端口直接不能冲突
协议
UDP协议和TCP协议
UDP协议:
1)不需要建立连接通道
2)不可靠连接
3)发送内容有限制的 不超过64kb(数据包不能太大)
TCP协议:
1)需要建立连接通道
2)可靠连接
3)发送内容无限制

java.net.InetAddress:代表的是互联网ip地址对象

Jdk提供的api文档有这样一个类:
java.net.InetAddress 互联网协议的Ip地址的表示,不是String是InetAddress类型
一个类如果没有构造方法,如何创建当前类实例呢?
这个类一定要静态的公共访问法---->返回值类型是自己类本身,方法的底层一定有该类对象的

常用的功能:

public static InetAddress getByName(String host)throws UnknownHostException通过主机名称获取ip地址对象,参数可以指定你自己电脑上的ip地址字符串(ip4地址)或者是计算机的主机名称public String getHostAddress():获取ip地址字符串形式(一直要用的方法获取ip地址字符串)public String getHostName():获取当前ip地址对象的主机名
public class InetAddressDemo {public static void main(String[] args) throws UnknownHostException {// public static InetAddress getByName(String host)throws UnknownHostException//通过主机名称获取ip地址对象,//参数可以指定你自己电脑上的ip地址字符串(ip4地址)或者是计算机的主机名称// InetAddress inetaddress = InetAddress.getByName("DESKTOP-Q62EUJH");//主机名称InetAddress inetaddress = InetAddress.getByName("192.168.1.5");//主机名称System.out.println(inetaddress);// DESKTOP-Q62EUJH/192.168.1.5//获取的ip地址对象中包含的字符串形式的ip地址(String类型的)// public String getHostAddress():获取ip地址字符串形式// public String getHostName():获取当前ip地址对象的主机名System.out.println("-----------------------------------------------------") ;System.out.println(inetaddress.getHostAddress());System.out.println(inetaddress.getHostName());}
}

UDP发送端和接收端代码实现

UDP接收端代码实现

1)创建接收端的Socket对象
2)创建一个接收容器(数据报包DatagramPacket)(字节数组长度1024个长度或者它的整数倍),自定义字节缓冲区,将数据报包放进去
3)接收端的socket对象,接收数据报包
4)解析接收容器中的真实的缓冲区的字节数组以及实际长度---->转换成字符串(发送端实际发来的内容)
5)展示发送的ip地址以及发送的内容,表示 “某个发送发送的数据是什么…”
先开启接收端,接收端不能开多个,因为一个端口只能只能绑定一次,所以会出现BindException:绑定一次端口号被占用 (address alread in use)

public class UDPReceiver {public static void main(String[] args) throws Exception {// 1)创建接收端的Socket对象,指定绑定的端口号//public DatagramSocket(int port) throws SocketExceptionDatagramSocket ds = new DatagramSocket(10086) ;//2)创建一个接收容器(数据报包DatagramPacket)(字节数组长度1024个长度或者它的整数倍)// 自定义字节缓冲区,将数据报包放进去//public DatagramPacket(byte[] buf,  参数1:用于保存传入数据报的缓冲区。//int length) 参数2:要读取的字节数。byte[] bytes = new byte[1024] ;int length = bytes.length ;DatagramPacket dp = new DatagramPacket(bytes,length) ;//3)接收端的socket对象,接收数据报包//底层会将的发送端的内容填充到这个数据报包的缓冲区中//public void receive(DatagramPacket p) throws IOExceptionds.receive(dp);//4)填充进去之后,从数据报包的缓冲区中解析实际的内容//public byte[] getData():获取缓冲区中真实的字节数组//public int getLength():返回接收的真实字节数 的长度byte[] bytes2 = dp.getData();int length2 = dp.getLength();//转换成字符串String receiverStr = new String(bytes2,0,length2) ;//从0开始解析真实内容//5)展示ip地址(发送端的)以及现在接收的内容//数据报包---public InetAddress getAddress()  获取ip地址对象//InetAddress  ---->String getHostAddress() ip地址字符串String ip = dp.getAddress().getHostAddress();System.out.println("data is--->"+receiverStr+",data from---->:"+ip);//接收端释放资源ds.close(); //在真实场景中,接收端不关闭的}
}

UDP发送端代码实现

Udp协议 ---->数据包的形式发送 (发送和接收端的数据传输)
发送端的代码步骤

1)创建发送端的Socket对象
2)创建数据报包对象
3)使用发送的端的socket对象调用发送方法发送数据报包
4)释放资源

public class UDPSend {public static void main(String[] args) throws Exception {//1)创建Udp协议发送端的Socket对象//DatagramSocket 用于发送和接收数据报数据包的套接字//public DatagramSocket()throws SocketExceptionDatagramSocket ds = new DatagramSocket() ;//2)创建数据报包对象//DatagramPacket:数据报包,用于udp里面数据传输//public DatagramPacket(byte[] buf,  用于发送的数据---字符串---转换成字节数组// int length,  数据长度//InetAddress address,  ip地址对象// int port) 端口号//参数1:字节数组//byte[] bytes = "hello,UDP我来了".getBytes() ;//参数2:字节数组长度// int length = bytes.length ;//参数3:ip地址对象//InetAddress inetAddress = InetAddress.getByName("192.168.1.5");//参数4:端口号 0-65535    0-1024保留端口// int port = 10086 ;//一步走DatagramPacket dp = new DatagramPacket("hello,UDP我来了".getBytes(),"hello,UDP我来了".getBytes().length,InetAddress.getByName("192.168.1.5"),10086) ;//3)使用发送的端的socket对象调用发送方法发送数据报包//public void send(DatagramPacket p) throws IOException:发送端的socket对象发送数据报包ds.send(dp);//4)释放资源ds.close() ;}
}

TCP客户端和服务器端代码实现(重点)

TCP服务器端步骤

1)创建服务器端的Socket对象
2)监听客户端连接----阻塞式方法,只要客户端绑定端口和服务器端不一致,不会建立连接一旦一致,会建立连接通道,获取连接的通道的Socket(客户端对象)
3)获取监听到的客户端Socket的通道内的字节输入流
4)读数据:一次读取一个字节数组
5)展示数据 先运行服务器端,监听客户端连接,在运行客户端

public class TcpServer {public static void main(String[] args) throws Exception {System.out.println("服务器正在监听...");//1)创建服务器端的Socket对象 ServerSocket// public ServerSocket(int port)throws IOExceptionServerSocket ss = new ServerSocket(8888) ;//2)监听客户端连接----阻塞式方法,只要客户端绑定端口和服务器端不一致,不会建立连接// 一旦一致,会建立连接通道,获取连接的通道的Socket(客户端对象)//public Socket accept() throws IOExceptionSocket s = ss.accept();System.out.println("服务器监听到客户端了....建立通道");//3)获取2)中的客户端的所在的通道内的字节输入流//public InputStream getInputStream() throws IOExceptionInputStream inputStream = s.getInputStream();//4) 读数据      :一次读取一个字节数组//自定义缓冲区byte[] bytes = new byte[1024] ;int len = inputStream.read(bytes);//转换成StringString str = new String(bytes,0,len) ; //从0开始读取实际字节数--->String//获取ip地址//Socket客户端类中---->public InetAddress getInetAddress()String ip = s.getInetAddress().getHostAddress();// 5)展示数据System.out.println("data is---->"+str+",date from-->:"+ip);//释放资源 :服务器端(真实场景不需要关闭)ss.close();}
}

TCP客户端:

TCP协议方式, 客户端和服务器端的传输

客户端要发送的数据的步骤
1)创建TCP协议 客户端的Socket对象,指定ip地址以及端口
2)从客户端所在的通道获取的字节数出流对象
3)写数据过去
4)关闭客户端资源

public class TcpClient {public static void main(String[] args) throws Exception {//    1)创建TCP协议 客户端的Socket对象,指定ip地址以及端口//public Socket(String host,int port)throws UnknownHostException,IOException//参数1:指定的ip地址或者主机名  参数2:端口号 0-65535(0-1024属于保留端口)Socket socket = new Socket("192.168.1.5",8888) ;//2)从客户端所在的通道获取的字节数出流对象//Socket--->成员方法://public OutputStream getOutputStream() throws IOExceptionOutputStream out = socket.getOutputStream();//3)写数据过去out.write("hello,TCP,我来了".getBytes());//4)关闭客户端资源socket.close();}
}

UDP和TCP的区别?

1)是否建立连接通
UDP:不可靠连接,不需要建立连接通道
TCP:可靠连接,需要建立连接通道
2)是否安全
UDP:线程不安全的,效率高
TCP:线程安全,需要建立通道(三次握手),效率低(需要等待服务器监听客户端连接)
3)发送数据大小是否有限制
UDP:不适合发送大数据,限制的大小64KB
TCP:适合发送大数据相对udp来说
4)从代码角度考虑:都是socket对象,区别?
UDP:DatagramSocket–>通过数据包的形式,将ip地址以及端口号绑定(是在数据包中) 是一数据包的填充方式—>接收端接收
TCP:Socket和ServerSocket—>客户端Socket就指定了端以及主机的ip地址 是一种字书流的方式写和读

练习

1)客户端图片文件服务器端复制图片文---->当前项---->字节缓冲流
2)客厂端文本文件,服务器端复制义本文件—当前项目下加入服务器反馈告诉客户端
文件复制完-------可能出问题
文件是否读完---- 宁符缓冲输入流–readLine( —null文件已完毕)

代码实现
1)文本文件实现

import java.io.*;
import java.net.Socket;//客户端
public class ClientDemo {public static void main(String[] args) throws Exception{//创建客户端的Socket对象Socket s = new Socket("192.168.198.1",13909);//创建字符缓冲流对象读取一个文件BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\123.jpg"));//创建客户端通道内字节输出流对象BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());//每次读取一个字节数组byte[] bytes = new byte[1024];int line ;while ((line= bis.read(bytes))!=-1){bos.write(bytes,0,line);//按行读取bos.flush();//刷新}//通知服务器端没有数据了s.shutdownOutput();//客户端需要接收服务端的反馈InputStream is = s.getInputStream();//一次读取一个字节数组int length = is.read(bytes);//输出反馈的数据String s1 = new String(bytes, 0, length);System.out.println(s1);//释放资源bos.close();s.close();}
}import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;//服务器端
public class ServerDemo {public static void main(String[] args) throws Exception{//创建客户端对象ServerSocket ss = new ServerSocket(13909);//监听客户端连接Socket s = ss.accept();//创建字符缓冲流对象,写客户端发送过来的数据 //封装通道内的字节输入流BufferedInputStream bis = new BufferedInputStream(s.getInputStream());//创建字符缓冲流对象,将读取到数据写到指定的文件中BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\A.jpg"));//每次读取一个字节数组byte[] bytes = new byte[1024];int length ;while ((length= bis.read(bytes))!=-1){bos.write(bytes,0,length);bos.flush();}//读取完了给客户端反馈OutputStream os = s.getOutputStream();os.write("图片读取完成:".getBytes());//释放资源bos.close();s.close();}
}

2)图片文件代码实现

import java.io.*;
import java.net.Socket;//客户端
public class ClientTest {public static void main(String[] args) throws Exception{//创建Tcp客户端对象Socket s = new Socket("192.168.198.1",12121);//创建字符缓冲流对象 -->读取某个.java文件BufferedReader br = new BufferedReader(new FileReader("D:\\qq聊天数据\\2985992008\\Image\\Group2\\${\\UD"));//获取客户端通道内的字节输出流对象//封装字节流对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//一次读取一行String line = null;while((line= br.readLine())!=null){//读一行,写一行到封装的通道的字符缓冲输流中bw.write(line);bw.newLine();bw.flush();}System.out.println("文件传输完成");//通知服务器端没有数据了s.shutdownOutput();//客户端需要接收服务端的反馈InputStream is = s.getInputStream();//一次读取一个字节数组byte[] bytes = new byte[1024];int length = is.read(bytes);//输出反馈的数据String s1 = new String(bytes, 0, length);System.out.println(s1);s.close();br.close();}
}import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;//服务器端
public class ServerTest {public static void main(String[] args) throws Exception{//创建服务器端对象ServerSocket ss = new ServerSocket(12121);//监听客户端的连接Socket s = ss.accept();//封装通道内的字节输出流对象,BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//创建支付缓冲输出流对象,将读到的数据写到当前项目的文件中BufferedWriter bw = new BufferedWriter(new FileWriter("E://Copy.java"));//读写复制String line = null;while((line=br.readLine())!=null){bw.write(line);bw.newLine();bw.flush();}System.out.println("接收完成");//读取完了给客户端反馈OutputStream os = s.getOutputStream();os.write("图片读取完成:".getBytes());bw.close();ss.close();}
}

反射的核心思想—以后会被封装到框架里(掌握格式)Spring(IOC技术)

反射思想:

通过类加载器---校验语法以及类的初始化,获取类的字节码文件对象
通过字节码文件对象1 获取这个类的构造器的类Constructor,创建类实例                    2 获取这个类的成员方法所在Method类,调用成员方法3 获取这个类的成员变量Field,可以给成员变量(类中方法外)

面试题:

获取字节码文件对象有几种方式?   字节码文件(.Class)--->正在运行的Java类对象1)Object类的getClass()方法 :任意Java类对象的.getClass()--->Class2)任意Java类型的.class属性    类名.class------->Class3)Class:就是代表字节码文件对象(正在运行的java应用程序的类或者接口)public static Class<?> forName(String className)  参数:包名.类名

Person类

public class Person {public String name  ; //姓名private int age ; //私有的年龄private String gender ; //默认修饰的性别//无参构造public Person(){}//私有修饰的带两个参数的构造方法private Person(String name,int age){this.name= name ;this.age = age ;}//默认修饰符的带三个参数的构造方法Person(String name,int age,String gender){this.name = name ;this.age = age ;this.gender = gender ;}//成员方法//带参,没有返回值public void show(String s){System.out.println(s) ;}//带参,有返回值private String myFunction(int number){return "helloworld"+number ;}//不带参,没有返回值的void myMethod(){System.out.println("myMethod...");}//不带参,有返回值的protected String function2(){return "hello,JavaEE" ;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}
}

三种获取字节码文件的方式(引出反射);

public class PersonDemo {public static void main(String[] args) throws Exception{//获取字节码文件的方法有几种//方式1,对象名调用getClassPerson p = new Person();Class<?> a = p.getClass();System.out.println("第一种方法:"+a);//方式2,任意的java类型.classClass<Person> B = Person.class;System.out.println("第二种方式:"+B);//方式3,通过反射获取//public static Class<?> forName(String className)Class<?> c = Class.forName("com.qf.Demo.test_02.Person");System.out.println("第三种方式:"+c);}
}

获取这个类的构造器的类Constructor,创建类实例

1)通过反射的方式获取类的字节码文件对象Person类
2)获取指定的公共的构造器对象-->获取指定的构造方法,如果这个构造方法带参数,一定要参数类型的.class---获取参数类型的字节码文件对象
3)通过构造器创建当前类实例
4)直接通过newInstance()方法初始化或者使用
如果构造器是私有的 -->使用setAccessible取消java语言访问检查 创建当前类实例

1.1创建实例中用到的方法

getConstructors(): 获取这个类字节码文件对象中所有公共构造的方法
getDeclaredConstructors():获取所有的构造方法,包括私有等等
getConstructor():获取指定的公共的构造器对象 存在参数 属性.class
newInstance(Object...init):通过构造器创建当前类实例
getDeclaredConstructor():获取指定的构造方法,如果这个构造方法带参数,一定要参数类型的.class---获取参数类型的字节码文件对象
setAccessible(boolean flag):参数为true,取消Java语言访问检查,私有可以访问

1.2代码实现:用的也是上面Person类

import java.lang.reflect.Constructor;
@SuppressWarnings({"all"})
public class ReflectDemo {public static void main(String[] args) throws Exception{//通过字节码文件对象  获取这个类的构造器的类Constructor,创建类实例//1)通过反射的反射的方式获取类的字节码文件对象 Person类Class<?> a = Class.forName("com.qf.Demo.test_02.Person");System.out.println(a);//class 包名.类名//2)获取指定的公共的构造器对象//获取Person的无参构造方法Constructor<?> con = a.getConstructor();//3)通过构造器创建当前类实例Object obj = con.newInstance();System.out.println(obj);//通过反射创建当前类对象,获取私有的构造方法并且给成员变量赋值//4)通过当前字节码文件对象获这个类的私有的带两个参数的构造方法Constructor<?> dec = a.getDeclaredConstructor(String.class, int.class);//5)Constructor构造器对象中继承了AccessibleObject,取消Java语言访问检查,私有可以访问dec.setAccessible(true);Object o1 = dec.newInstance("章若楠", 24);System.out.println(o1);//通过反射获取默认修饰带三个参数的构造方法//6)通过当前类的字节码文件对象获取指定的构造方法的Constructor类对象Constructor<?> c = a.getDeclaredConstructor(String.class, int.class, String.class);//取消java语言的访问检查c.setAccessible(true);//创建当前类的实例Object o = c.newInstance("章若楠", 18, "女");System.out.println(o);}
}

获取这个类的成员方法所在Method类,调用成员方法

1)获取Person类的字节码文件对象 Class类对象
2)Person类无参构造方法本身就是公共的构造方法,直接创建当前类实例
3)获取公共的成员方法所在的类对象Method
-->私有的默认的被保护的  取消Java语言访问检查
4)调用成员方法

2.1 获取成员成员方法,调用成员方法

getMethod(方法名,参数类型的字节码文件对象 可变参数)
invoke(实例对象,实际参数,...)调用成员方法  如果有返回值用object接收
getDeclaredMethod(方法名,参数类型的字节码文件对象 可变参数)私有的方法

2.2 代码实现–>具体类Person

import java.lang.reflect.Method;//获取这个类的成员方法所在Method类,调用 成员方法   (重点)
public class ReflectDemo03 {public static void main(String[] args) throws Exception{//创建Person类的字节码文件对象Class<?> c = Class.forName("com.qf.Demo.test_02.Person");//创建实例化对象Object obj = c.newInstance();//获取公共的成员方法所在的类对象Method m = c.getMethod("show", String.class);//直接传参调用成员方法m.invoke(obj,"章若楠");//默认的方法获取Method myMethod = c.getDeclaredMethod("myMethod");//取消java语言访问检查myMethod.setAccessible(true);//直接调用myMethod.invoke(obj);//私有的方法获取Method myFunction = c.getDeclaredMethod("myFunction", int.class);//取消java语言访问检查myFunction.setAccessible(true);//传参且直接调用方法Object invoke = myFunction.invoke(obj, 18);System.out.println(invoke);//被保护的方法的获取Method function2 = c.getDeclaredMethod("function2");//取消java语言访问检查function2.setAccessible(true);//直接调用 有返回值需要接收Object invoke1 = function2.invoke(obj);System.out.println(invoke1);}
}

获取这个类的成员变量Field,可以给成员变量(类中方法外)

1)获取Person类的字节码文件对
2)通过字节码文件对象获取这个类构造方法并且创建当前类实例
3)需要获取到指定的字段(属性)所在的类对象Field  (代表成员变量)
如果是私有的被保护的默认的用getDeclaredField指定
4)将指定的实际值value作用在指定的实例上

3.1 Field 成员变量对象赋值中用到的方法

getField(String name):获取这个类的指定的(公共)的成员变量的Field对象
set(Object obj, Object value):将指定的实际值value作用在指定的实例上
getDeclaredField(String name):获取这个类的指定成员变量的Field对象(私有的,默认的,受保护的)Constructor构造器/Field成员变量类对象/Method成员方法: 都继承自AccessibleObject --->setAccessible(boolean flag):true:抑制java语言检查

3.1 代码实现–>具体类也是Person

import java.lang.reflect.Field;//通过字节码文件对象, 获取这个类的成员变量Field,可以给成员变量(类中方法外)
public class ReflectDemo02 {public static void main(String[] args) throws Exception{//1)获取Person类的字节码文件对象Class<?> c = Class.forName("com.qf.Demo.test_02.Person");//2)通过字节码文件获取这个类构造方法并且创建当前类实例Object o1 = c.newInstance();//3)需要获取到指定的字段(属性)所在的类对象Field  (代表成员变量)Field name = c.getField("name");//4)将指定的实际值value作用在指定的实例上name.set(o1,"章若楠");//年龄  私有的默认的被保护的成员变量对象用getDeclaredField指定Field age = c.getDeclaredField("age");//私有的默认的被保护的需要抑制java语言检查age.setAccessible(true);//直接赋值age.set(o1,18);//性别 默认的成员变量Field gender = c.getDeclaredField("gender");//需要抑制java语言检查gender.setAccessible(true);//直接赋值gender.set(o1,"女");System.out.println(o1);}
}

反射的第二个应用(通过读取配置文件,优化代码)

Java设计原则:
开闭原则
对现有代码的修改关闭,对扩展开放!
想办法在的不修改现有代码基础上,进行代码的扩展!
1)获取配置文件所在的输入流对象
2)创建集合属性列
3)将资源文件所在输入流对象内容架子啊到属性列表中
4)获取类的全限定名称和方法名
5)通过className--->获取当前类的字节码文件对象
6)直接创建当前类的实例
7)获取这个类的成员方法的Method类对象
8)调用方法

代码实现:

//工人类
public class Worker {public void love(){System.out.println("爱生活爱高圆圆");}
}
//学生类
public class Student {public void love(){System.out.println("学生爱学习");}
}
//配置文件内容
className=com.qf.Reflect_01.Student
methodName=lovepublic class ReflectTest {public static void main(String[] args) throws Exception {//1)获取配置文件所在的输入流对象InputStream i = ReflectTest.class.getClassLoader().getResourceAsStream("myClass.properties");//2)创建集合属性列Properties prop = new Properties();//3)将资源文件所在输入流对象内容架子啊到属性列表中prop.load(i);//4)通过key获取value---使用特有功能String className = prop.getProperty("className");//类的全限定名称System.out.println(className);String methodName = prop.getProperty("methodName");//方法名System.out.println(methodName);//5)通过className--->获取当前类的字节码文件对象Class c = Class.forName(className);//6)直接创建当前类的实例Object o = c.newInstance();//7)获取这个类的成员方法的Method类对象Method method = c.getMethod(methodName);//8)调用方法method.invoke(o);}
}

JDK动态代理

代理设计模式—>代理角色帮助真实角色增强功能

代理设计模式---->结构型设计模式
代理描述:让代理角色帮助真实角色完成一件事情!(业务代码)静态代理代理角色和真实角色必须同一个接口!创建线程的方式第二种:自定义一个类 实现Runnable接口class Thread implements Runnable弊端:结构组成太繁琐,真实角色,代理角色,必须实现同一个接口动态代理jdk动态代理:jdk提供的java.lang.reflet.Proxy前提:必须有一个接口通过反射的方式直接将接口的方法进行调用,然后产生代理对象静态方法:public static Object newProxyInstance(//当前代理实例要实现接口的类加载器ClassLoader loader,//当前代理实例要实现的接口列表的字节码文件对象Class<?>[] interfaces,//代理实例调用接口的方法的处理程序!这个类型接口--->里面需要将增强代码和业务代码分离InvocationHandler h)throws IllegalArgumentException
public interface UserDao {//增void add();//修改void update();//删除void delete();//查询void select();
}public class UserDaoImpl implements UserDao{@Overridepublic void add() {System.out.println("添加");}@Overridepublic void update() {System.out.println("修改");}@Overridepublic void delete() {System.out.println("删除");}@Overridepublic void select() {System.out.println("查询");}
}public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}//参数1:代理实例//参数2:要调用真实角色的里面method---->//参数3:调用方法里面传递实际参数,如果没有参数不用传参@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("----------------------");System.out.println("权限校验");Object invoke = method.invoke(target, args);//真实角色方法的调用System.out.println("产生日志");return invoke;}
}
/*** 动态代理* jdk动态代理: jck提供的java. Lang. reflet . Proxy* 前提:必须有一个接口* 通过反射的分t直接将接口的方法进行调用,然后产生代理对象* cglib动态代理:第三方jor包---- 自己的核心的类*/
public class ReflectDemo {public static void main(String[] args) {//单独测试,, 接口多态UserDao u = new UserDaoImpl();u.add();//添加u.update();//修改u.delete();//删除u.select();//查询//接口多态InvocationHandler handler = new MyInvocationHandler(u);UserDao u2 = (UserDao) Proxy.newProxyInstance(u.getClass().getClassLoader(),u.getClass().getInterfaces(),handler);u2.add();u2.update();u2.delete();u2.select();}
}

MySQL数据库

存储数据的仓库
之前早期存储数据—>
1)定义一个变量 存储数据,这个变量类型可能是基本类型或者引用类型,变量使用完毕,最终的归宿被gc回收调,释放内存;
2)数组 也是一个容器可以存储基本类型数据,也可以存储引用数据
弊端:长度固定
3)StringBuffer:字符串缓冲区,也是一个容器,存储任意类型的元素
最终要求:需要将StringBuffer转换为String,我们的需求不断变化,不一定为String类型
4)集合:相对比数组优秀,因为长度可变
但是并非永久存储,使用完毕将集合对象从内存中释放掉
上面四种方法都是临时存储
5)Io流,Input输入 Output输出
可以实现文件永久存储,将读取的文件内容,通过输出流写入到某个磁盘上文件中,然后即使关闭,文件永久保存
IO流存储大字节类型,但是IO流存储比较耗时
6)数据库:
永久保存,即使关闭数据也在
数据库可以支持"事物",对数据操作(具体的业务),原子性支持(数据的操作:要么数据同时成功,要么同时失败)
存储大量数据(批量操作)
数据库支持mysql数据库,INNODB 引擎:支持行级锁)

针对表的操作里面涉及的数据类型

关于msyql中常见字段类型 :使用最频繁的就是varchar和int
varchar :字符串 — 类似于Java的String
varchar(字符长度)
int:整数类型 ----默认里面字符长度 int(11) 推荐这个int
举例: 描述这个人年龄 20—值所占的实际字符数
类似于Java的数据类型 整数默认int
int(指定字符长度): 描述的某个人的编号 :int(3) :不要
用这种写法 id – 1 ----001
double:小数类型 类似于Java中的ddouble
double(值1,值2) :
举例:double(4,2) :这个是小数类型,4位数,小数点后保留2位
date日期类型 ---- “2022-8-31”
datetime:日期时间类型 ----- “2022-8-31 16:01:50”
timestap:时间戳 :
举例:在2022年8月31 16:02:30 插入一条数据的时
候,那个瞬时时间的具体的日期+时间

DDL数据库定义语句

# DDL针对库操作
show databases; -- 查询有哪些数据库
create database 库名; -- 直接创建数据库
create database if not exists 库名; 如果不存在这个库名 则创建!
show create database 库名; --查询指定数据库的信息(包含字符集信息)
alter database 库名 default character set 字符集名称;-- 修改数据库的默认的字符集
drop database 库名;  -- 直接删除
drop database if exists 库名; --判断删除
# 针对表操作
use 库名; ---- 选择指定的库; 意思进入到磁盘上的文件夹中(库)
语法:
create table 表名(
字段名称1 字段类型1,
字段名称2 字段类型2,
字段名称3 字段类型3,
...
...
...
字段名称n 字段类型n
) ;-- 创建表
show tables ;-- 查询库中的有哪些表
desc 表名; -- 查询表的结构
alter table 表名 change 以前的字段名称 新的字段名称 以前的字段类型; -- 修改表的字段名称
alter table 表名 modify 字段名称 新的字段类型;-- 修改表的字段类型
alter table 表名 add 字段名称 字段类型; -- 给表添加一个新的字段
alter table 表名 drop 字段名称; --删除表中的某个字段
alter table 以前的表名 rename to 新表名;-- 给表重命名
create table 新表名 like 以前表名; -- 复制一张一模一样,新的表和以前的表字段都一样
drop table 表名; -- 直接删除
drop table if exists 表名; -- 询问删除

DML语句:数据库操作语句

# 插入
1) insert into 表名 values(值1,值2,值3......值n);-- 语法1:插入全表数据 ,插入的值要和字段类型匹配
2) insert into 表名 values(值1,值2,值3......值n),(值1,值2,值3.....值n),(.....); -- 语法2:插入全表数据,一次插入多条
3) insert into 表名(字段名称1,字段名称2,...部分字段) values(值1,值2,...其他部分字段对应的值);-- 语法3:插入部分字段,没有插入的字段的值,默认值是null(没有值),字段里面也没显示null,空字符
4) insert into 表名(字段名称1,字段名称2,...部分字段) values(值1,值2,...其他部分字段对应的值),(值1,值2,...其他部分字段对应的值),(值1,值2,...其他部分字段对应的值);-- 语法4:插入部分字段,也可以一次插入多条
插入表的记录语法注意事项
-- 1)如果全表数据,字段值一定要和类型匹配
-- 2)插入全表数据(或者插入部分字段),字段值总数量和表的字段数量对应上
# 修改
5) update 表名 set 字段名称1 = 值1 where  字段名称2 = 值2 ;-- 带条件修改 :修改单个字段
6) update 表名 set 字段名称1 = 值1 ,字段名称2=值2 ,,, where 字段名称n =值n; -- 修改多个字段 带条件修改: 条件和条件中间 and (并列关系)
UPDATE student
SETNAME = '老王',age = 32,address = '南窑国际'
WHERE id = 3 ;
# 删除
delete  from 表名  where  字段名称 = 值;  -- 带条件删除
delete from 和 truncate  table  有什么区别?(面试题)
-- delete from 表名和 truncate  table 表名 有什么区别?(面试题)
-- 前者:-- 1)仅仅只是删除全表数据,表还是存在---表的结构还在;-- 2)针对非业务字段id   一般:主键(非空且唯一)自增长约束(字段会自动在上一次基础不断自增1)-- 不会影响这个主键自增长约束的值; -- 后者      -- 1)它不仅仅是删除全表数据,会将表干掉,而且同时会新建一模一样的空表-- 2)直接会影响自增长主键 id值

DQL语句:数据库查询语句

# 基本查询
select * from 表名; -- 查询全表数据  查询全表字段,给定别名 as ,as可以省略 *:代表所有的
SELECTid AS '学号',NAME AS '姓名',gender AS '性别',age AS '年龄',address AS '地址',birthday AS '出生日期'
FROM student ;
select (字段1 别名1,字段2 别名2...) from 表名; -- 查询指定字段
SELECT DISTINCT 字段 '别名' FROM 表名;-- 字段去重distinct
(字段1+字段2+...) '和的别名'; -- 字段求和 字段类型一致
-- 如果有null值,mysql有自己的函数,ifnull(字段名称,给一个值); 如果这个字段名称是null,给一个固定值# 带条件查询
基本格式: select 字段列表  from 表名  where 条件;
--  1)条件查询
-- 条件查询里面使用基本运算符,比较运算符:<,>=,<=,==,!=(mysql的不等于可以使用这个<> )(!= mysql中用 is not 代表)
-- 赋值运算符: =
-- 逻辑运算符:java中的&&,||  mysql提供:and并列 , or或
-- 某个范围的数据: 字段名称>=值1  and  字段名称<=值2;
--  mysql 提供了between 值1 and 值2;  意思是值1和值2俩者之间
-- 查询或的关系:字段名称 = 值1 or 字段名称= 值2 or 字段名称= 值3
-- mysql提供:字段名称 in(值1,值2,值3...):相当于字段名称是值1或值2的或者值3的
--  2)模糊查询 like
select 字段列表 from 表名 where  字段名称 like  '模糊的语法';
-- a) like 后面使用  '%其他字符%' 或者 '字符%'  %:代表任意多个或者单个字符(开发中模糊搜索最频繁的)
-- b)_: 一个下划线 代表单个字符,
-- 全部变成utf8--->如果要在dos出窗口去查询表的数据,就出现乱码
-- 在dos窗口临时更改character_set_client/character_set_results/character_set_server改成gbk就可以在dos展示中文
--  3)聚合函数 --->查询出的结果是一个单行单列的数据
-- count(非业务字段:比如id字段,在实际开发中非空并且唯一) 查询(统计)总条数
-- count(业务字段:比如 具体信息字段):可能是null值,不会统计
-- avg(字段名称):求平均分
-- max(字段名称):求这列的最大值
-- min(字段名称):求这列最小值
-- sum(字段名称):这列求和-- 4)排序查询 order by
select 字段列表 from order by 字段名称 排序规则;
-- 排序规则不写:默认asc 升序  ,desc 降序
SELECT *
FROM    student2
ORDER BYmath DESC ,   -- 数学降序排序english ASC ; -- 英语升序排序
--  5)分组查询group by
select 字段列表 from 表名 group by 分组字段;
-- 分组字段可以在 select 后面查询的 ,group by的后面不能使用聚合函数
-- 带条件进行分组查询, where关键字,还有group by 关键字
-- goup by 后面不能使用where条件,where 条件必须放在group by 前面,先满足条件,再参与分组
--  6)筛选查询having
where,group by,having :先是满足条件,然后参与分组,在进行筛选!
-- 需求: 按照性别分组,统计每个组的总人数,条件:数学成绩不大于70分的不参与分组, 筛选出总人数大于2的这一组
SELECT sex '性别',COUNT(id) '总人数'
FROMstudent2
WHERE math > 70
GROUP BY sex
HAVING COUNT(id)>2 ;
--  7)分页查询
分页查询 **limit**  mysql数据库的分页查询关键字**limit**
语法格式: select  字段列表 from 表名 limit 起始行数,每页显示的条数; 起始行数从0开始
起始行数=(当前页码-1)*每页显示的条数-- 现在每页显示两条,查询第一页数据
SELECT * FROM student2 LIMIT 0,2;
-- 查询第二页数据
SELECT * FROM student2 LIMIT 2,2;
-- 查询第三页数据
SELECT * FROM student2 LIMIT 4,2;
-- 查询第四页数据
SELECT * FROM student2 LIMIT 6,2;
-- 查询第五页数据
SELECT * FROM student2 LIMIT 8,2 ;
-- 模糊查询like
-- 聚合函数select count(非业务字段) from 表名;
GROUP BY -- 不能使用聚合函数
HAVING -- 后面可以使用聚合函数GROUP BY 必须在 WHERE 的后面使用,如果存在条件, HAVING 是放在 GROUP BY 的后面
GROUP BY 后面都是分组字段 可以 SELECT 查询 的时候查询分组字段
HAVING 后面可以是聚合函数

数据库的备份和还原

两种方式

方式1:图形界面化方式 直接sqlyog就行了

备份:鼠标选中备份的库名, 右键-----> backup/export---->选中sql脚本 backupdatabase  as sql dump最上面选中structure and data以及选中备份本地磁盘路径----执行即可还原:新建库---->use 库名----> 在库上面右键 ---->import导入---选择要执行的sql脚本文件

方式2:命令行方式 去备份和还原

备份:以管理员身份进入dos窗口,不需要登录mysql输入指令mysqldump -uroot -p密码 要备份的库名 > 指定本地磁盘上的路径D:\EE_2208\day33\code\指定sql脚本文件名称.sql还原: 在dos窗口,要登录mysqlmysql -uroot -p ---回车 输入密码登录成功之后将之前的库删除新建库使用库source 本地磁盘上的备份的sql脚本文件,自动会执行!

数据库的约束

约束: 是约束dba(数据库管理员)操作数据库的一种行为,插入null值,针对特殊字段出现重复了,数据库中出现冗余字段(员工表 – 显示人所在的部门)(不合规的数据)

1)默认约束:default

建表的时候创建

CREATE TABLE stu(id INT, -- 编号NAME VARCHAR(10), -- 姓名gender VARCHAR(3) DEFAULT '女' -- 性别   --加入默认约束
);

使用sql语句将默认约束删除

ALTER TABLE stu MODIFY gender VARCHAR(3) ;

通过sql语句加上默认约束

ALTER TABLE stu MODIFY gender VARCHAR(3) DEFAULT '女' ;

注意事项:

默认约束对于直接插入null值不起作用的,只有在没有插入字段的值才起作用
null值在数据库中没有值,没有意义;不合法数据;这个时候默认约束起作用,
当如果直接插入部分字段的时候,没有插入字段的值,默认约束

2) 非空约束:not null —字段值不能为空,不能直接插入null值

建表的时候创建

CREATE TABLE stu(id INT,NAME VARCHAR(10) NOT NULL, -- 非空约束age INT
);

通过sql修改name字段类型

ALTER TABLE stu MODIFY NAME VARCHAR(10);

通过sql语句加上默认约束

ALTER TABLE stu MODIFY NAME VARCHAR(10) NOT NULL ;

实际注册业务中 邮箱,电话,身份证信息(真实有效的信息必须唯一的,通过真实有效的信息查询用户的信息)

3)唯一约束: primary key:非空且唯一---- 重点

建表时直接创建

CREATE TABLE stu(id INT,NAME VARCHAR(10),telephone VARCHAR(11) UNIQUE -- 加入唯一约束
) ;

通过sql:修改表,加入唯一约束 (加唯一索引)

alter table 表名 add constraint 唯一约束名 unique(列名就是字段名称);
ALTER TABLE stu ADD CONSTRAINT my_telepehone UNIQUE(telephone) ;

4)主键约束:auto_inicrement----重点

一般情况都是作用在非业务字段上 (每一张表的id字段都主键)

CREATE TABLE stu(id INT  PRIMARY KEY,  -- 加入主键约束NAME VARCHAR(10)
);

通过sql语句删除键

-- alter table 表名 drop primary key ; -- 仅仅是删除了主键索引,非空约束还在
ALTER TABLE stu DROP PRIMARY KEY;

通过sql语句修改表:添加主键约束

alter table 表名 add CONSTRAINT(这个声明) 主键约束名 PRIMARY KEY(字段名称) ;
CONSTRAINT(这个声明) 主键约束名 这个可以省略
ALTER TABLE stu ADD CONSTRAINT my_pri PRIMARY KEY(id) ;

5)自增长约束auto_increment, 它一般都是和主键一块用(非业务字段id,一定是非空且唯一,还自增) id字段默认不插入值,那么从0开始一直逐次递增1

CREATE TABLE stu(id INT PRIMARY KEY AUTO_INCREMENT,-- id字段主键并且是自增长的NAME VARCHAR(10),age INT
);
-- mysql有一个函数: 查询到最后一次自增长的值是多少
SELECT LAST_INSERT_ID() ;
-- 自增长约束通过sql修改表的可以删除 :alter table 表名 modify 字段名称 字段类型 去掉auto_increment;

6)外键约束:foreign key 用在数据库表设计上面-----重点

直接创建表的时候添加外键约束

constraint   -- (声明) 外键约束名   -- 外键约束名:主表名_从表名_fk
foreign key    -- (作用在从表的字段名称)
references(关联)  -- 主表名(主键字段名);
-- 创建员工表
--  id员工编号,name员工姓名,gender员工性别,dept_id 部门id号
CREATE TABLE employee(id INT PRIMARY KEY AUTO_INCREMENT , -- 员工编号NAME VARCHAR(10),          -- 姓名gender VARCHAR(3),         -- 性别dept_id INT,                         -- 员工所在的部门的编号CONSTRAINT       -- 声明dept_emp_fk        -- 外键约束名FOREIGN KEY (dept_id)   -- 作用在从表的指定字段上REFERENCES              -- 关联dept(id)     -- 主表名(主键字段名) ;);

不能直接删除主表,必须先将从表数据没有关联

7)级联操作: cascade

加入级联修改和级联删除
在修改或者删除主表的时候,和主表相关联的从表数据随着改动

CREATE TABLE employee(id INT PRIMARY KEY AUTO_INCREMENT , -- 员工编号NAME VARCHAR(10),           -- 姓名gender VARCHAR(3),         -- 性别dept_id INT,                -- 员工所在的部门的编号CONSTRAINT                    -- 声明dept_emp_fk                -- 外键约束名FOREIGN KEY (dept_id)   -- 作用在从表的指定字段上REFERENCES              -- 关联dept(id)     -- 主表名(主键字段名) ;ON DELETE CASCADE  -- 级联删除ON UPDATE CASCADE  -- 级联修改);

数据库的三大范式(设计层面— 理论) 面试题

数据库的范式(-----是设计数据库的一种规范要求
标准规范:三大范式(规范):每个范式呈递次规范,范式级别越大,数据库中字段冗余度小
1NF,2NF,3NF
1NF:表中的每一列是不能再拆分原子数据项(最简单单独的一列,不能有复合列), 最基本的要求
2NF:在1NF基础之上
特点1)每一张表只能描述一件事情;不能一张表描述多个事情
特点2)非主键字段必须完全依赖于主键
3NF:在2nf的基础上,
核心思想:非主键字段中间不能产生传递依赖
c字依赖于b字段,b字段依赖于a字段,-- a依赖于c字段
举例:多对多的关系 学生表和选课表

多表关系(理论关系)

多表关系(理论的关系)
一对一一种特例(多对一的一种特例)
人和身份证
一个人对应一张身份证
一张身份证从属于某个人的

一对多的关系 (开发中很频繁的)
用户和订单
一个用户可以下多个订单
一个订单(在某刻下订单节点)从属于某个用户的
部门和员工
一个部门有多个员工
一个员工从属于某个部门的

多对多的关系(比较频繁的)
商品和订单---- 中间表:订单项表
一个订单里面有多个商品
一个商品在多个订单中包含
学生和选课

多表关系以及多表查询

1)内连接查询
1.1)隐式内连接(推荐:多去使用where条件,这个算sql优化的一种方式)
使用select 字段列表 from 表名1,表名名2 where 连接条件;
1.2)显示内连接inner join
语法:select 字段列表 from 表名1 (inner) join 表名2 on 连接条件; 如果有多个并列条件,后面and

2)外连接查询
左外连接(推荐:开发频繁使用的):将A表(左表)和B表的交集数据(有连接条件的数据)以及A表的所有全部查询
select 字段列表 from 表名1(左表) left outer join 表名2 on 连接条件;
outer可以省略不写
右外连接:将A表和B表(右表)的交集数据以及B表的所有数据查询出来
select 字段列表 from 表名1 right outer join 表名2(右表) on 连接条件;
outer可以省略不写

3)子查询
查询: select嵌意select语句
情况1:where条1件利用比较运草符
员I表和部]表查询1资最高的员I信息以及他的部]信息
情况2:利用in(值1,值2值3…)
情况3:多行多列的数据----
格某条select语句查询的当做个 "庙表;使用这个處表和其他表关联查询

数据库的事物 transaction

传统事物特点:acd原子性,一致性,隔离性,持久性
事物的隔开级别:安全性问题以及效率问题
级别:从小到大,安全从小到大,效率从大到小
read uncomitted ;读未提交 – 出现严重的问题 --脏读
read committed ; 读已提交 – 有校防止脏读,它会

结语: 以上是这周的总结内容,我们都在为了自己能够有更好的生活而奋斗着;

(006)网络编程,反射及其应用,MySQL数据库相关推荐

  1. qn模块java脚本_Qn271 对于网络编程 反射 IO 线程的一些一本入门程序 多多联系会加快 速度 WinSock-NDIS 269万源代码下载- www.pudn.com...

    文件名称: Qn271下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 673 KB 上传时间: 2015-05-13 下载次数: 0 提 供 者: 褚晓旦 详细 ...

  2. Properties类,InetAddress类,网络编程,反射,Mysql数据库

    文章目录 properties类 InetAddress类 网络编程 三要素: 反射 获取Person类字节码文件对象 获取指定的构造方法 创建该类实例 获取成员变量 获取成员方法 设计模式: Mys ...

  3. week_06_动态代理,工厂方法,单例,File,IO,网络编程,反射,数据库语句

    动态代理 动态代理核心思想: 再程序执行过程中通过一些特殊的方式产生代理 jdk动态代理: 前提必须有一个接口 java.lang.reflect.Proxy:提供了创建动态代理类和实例的静态方法 p ...

  4. Android之网络编程利用PHP操作MySql插入数据(四)

    因为最近在更新我的项目,就想着把自己在项目中用到的一些的简单的与网络交互的方法总结一下,所以最近Android网络编程方面的博文会比较多一些,我尽量以最简单的方法给大家分享,让大家明白易懂.如果有什么 ...

  5. 【SQL编程】Greenplum 与 MySQL 数据库获取周几函数及函数结果保持一致的方法

    1.问题说明 项目有两个不同的平台分别使用 Greenplum 和 MySQL 数据库,但是这两个数据库的函数是不相同的,所以需要维护两套查询 SQL. 2.根据周几获取数据 2.1 原始函数结果 M ...

  6. 如何将本地MySQL提交到网络_如何把本地MySql数据库移植到远程服务器上

    用dedecms做了一个女性网站,是仿爱丽女人网的.为了在本地测试,就要添加分类栏目,为了看首页和列表页面的效果,还得在网上采集大量的各个分类的内容.这样下来几十个栏目每栏目几十条信息,信息一下就是几 ...

  7. mysql中php编程实例_PHP连接MYSQL数据库实例代码

    现在做的项目需要php连接mysql数据库,虽然之前学过,但是现在基本上都给忘了,之后通过查找相关资料找到了解决方法,下面小编把具体方法分享在聚米学院平台供大家学习. 具体代码如下所示: <?p ...

  8. Linux网络编程小项目sqlite,嵌入式数据库sqlite

    *************************************** * 嵌入式数据库sqlite在LPC22XX上的应用 * ******************************* ...

  9. 计算机毕业设计 SSM网上跳蚤市场平台系统 校园跳蚤市场系统 网络跳蚤市场管理系统Java Vue MySQL数据库 远程调试 代码讲解

最新文章

  1. 预加载系列一:DNS Prefetching 的正确使用姿势
  2. django实现长链接
  3. 还觉得linux命令难吗,看这篇2w多字的linux命令详解,通俗易懂
  4. Yolo-v2_ Windows平台下如何配置darknet-yolov2?(安装CUDA)
  5. java数独最快解_[分享]数独的JAVA解法
  6. 如何提高lstm的预测精度_如何提高示波器的测试精度?五大因素助您了解!
  7. 【实验】综合实验-咔咔咔还是一顿整
  8. Apache Flink Meetup,1.13 新版本发布 x 互娱场景实践分享的开发者盛筵!
  9. Android Studio导入项目非常慢的解决办法
  10. java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误
  11. 掌握需求过程阅读笔记六
  12. python构造callable_Python callable内置函数原理解析
  13. cvpr2020 人脸检测与识别_CVPR2020 论文分类下载 「人脸识别+目标检测」
  14. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-5.开源工具的优缺点选择和抽象方法的建议...
  15. 后端图形验证码base64编码字符串及前端获取图形验证码base64编码字符串并解码显示图形验证码代码
  16. python反转整数的几种方法_小白python整数反转
  17. Gamecenter 测试失败的解决方案
  18. 计算机怎样保存文档,【2人回答】怎么在电脑上写文档并保存?-3D溜溜网
  19. java Optional操作
  20. 移动端登录页面-vue

热门文章

  1. csdn 涨粉攻略 方案设计(补充)
  2. TYVJ 1391 走廊泼水节
  3. 内存优化二Bitmap优化
  4. C# WebRequest GET/POST request
  5. CMD 命令速查手册
  6. 【实时数仓】DWS层的定位、DWS层之访客主题计算(PV、UV、跳出次数、计入页面数、连续访问时长)
  7. 阿里巴巴搜索系统总结(三)
  8. Opencv训练自己分类器
  9. gaussdb数据库 oracle,华为高斯GaussDB T数据库实战培训(7小时速成版)
  10. nt和win2k源码模块位置