SE进阶笔记(IO流、线程、多线程、数据库、JDBC、类的反射和元注解)

1 篇文章 0 订阅
1 篇文章 0 订阅

知识点

个人整理的知识点,希望对你有所帮助( ^ _ ^ )

第一章IO流编程

字符和字节

Java采用unicode编码,每个字符占2个字节

数据源头

文件,键盘,网络流,字符串(内存)

File类

	File(String URL)
	String getName()---获取当前文件对象的名字
	1ong 1ength()---获取文件对象的太小单位:字节
	boolean isFile()/isDirectory()-一判断文件/文件夹
	boolean canRead()/canWriteO-判断文件可读/可写
	boolean isHidden()---判断file对象是否为隐藏
	1ong lastModified()---获取当前file对象最后修改时间

File类常用方法

	boolean exists()--判断文件是否存在
	void createNewFile()--创建新文件
	void mkdir()/mkdirs()-创建新文件夹
	delete()-删除文件或者文件夹
    File[]listFiles)-获取当前文件夹下所有的子项,如果当前文件下为空则返回null值
	mkdirs可以把不存在的父目录也创建出来
FileFilter和FilenameFilter
	文件过滤器来获取一个目录下满足条件的部分子选项(即只获取文件或只获取目录)文件过滤器更多是被用于1istFiles(FileFjlter filter)的参数中。
	FileFilter接口:
		public boolean accept(File pathname)
	FilenameFilter接口:
		public boolean accept(ile dir,String name)
RandomAccessFile类
	RandomAccessFile支持访问文件随机的读入和读取
	RandomAccessFile(File file,String mode)
	第一个参数:要访问的文件对象/交件路径
	第二个参数:读写模式(r:只读模式;w:可读可写)
	常用方法:
		read()-从此文件中读取一个数据字节
		write(int b)-向此文件中写入指定的字节
		read()和write()都有多个重载的方法,详见API
		
	利用RandomAccessFile类提供的方法可以进行对文件指针的操作
	long getFilePoint():获取该文件当前的指针位置
	void seek(long pos):该方法允许我们将指针移动到指定位置
	可以结合多线程对文件进行多点复制(例如迅雷下载)

InputStream

			以字节为基本单位
	子类:	
			FileInputStream 文件输入流
			FilterInputStream:过滤输入流
								BufferedInputStream 缓冲输入流
								DataInputStream	数据输入流
								PushbakInputStream	推回输入流
			ObjectInputStream	对象输入流
			PipedInputStream	管道输入流
			SequenceInputStream	合并流
			StringBufferInputStream	字符串输入流
			ByteArrayInputStream	字节数组输入流
	输入流的概念:输入的概念是指从外存读取数去输入到内存中
	方法:
			read()
				输入流提供的read方法是从输入流中读取数据的方法,InputStream提供多个重载的方法。
			close()
				输入流提供的close方法作用是在输入流用完后关闭流的动作。
			read():int 
			read(byte b[]):int 
			read(byte b[],int off,int len):int 
			skip(long n):long available():int 
			close():void 
			mark(int readlimit):void 
			reset():void 
			markSupported():boolean

FileInputStream

	作用:从实际磁盘中读取文件的内容,从文件系统中的某个文件获得输入字节(用于读取图像数据之类的原始字节流)
	构造方法:
			FileInputStream(File file)
			FileInputStream(String name)

OutputStream

	子类:
			FileOutputStream	文件输出流
			FilterOutputStream:过滤输出流
								BufferedOutputStream	缓冲输出流
								DataOutputStream	数据输出流
								PrintStream		打印输出流
			ObjectOutputStream	对象输出流
			PipedOutputStream	管道输出流
			ByteArrayOutputStream	字节数组输出流
	方法:	
			write(intb):void 
			write(byte b[]:void 
			write(byte b[],int off,int len):void 
			flush():void
			close():void

FileOutputStream

					把流写入到文件。
		构造方法
			FileOutputStream(File file)
			FileOutputStream(File file,boolean append)
			FileOutputStream(String name)
			FileOutputStream(String name,boolean append)
			append:如果文件已经存在,append-true表示往文件追加内容,否则会覆盖文件。
			举例:拷贝文件

流的套接

		流类可以分为
			底层流
				包含以字节的形式读写的方法
			高层过滤器流
				用于读写高层信息
		高层流要求底层流作为基础
		常用高层字节流:
			DataInputStream
			BufferedInputStream
			ObjectInputStream
		高级(过滤流)	
			FilterInputStream/FilterOutputStream 类的子类包括DataInputStream/DataOutputStream
				DataInputStream和DataOutputStream提供多种多样的readxxx和writexxx方法是对多种数据的读写。
			BufferedInputStream/BufferedOutputStream
				缓冲字节输入/输出流为InputStream/OutputStream对象增加了缓冲区功能,利用缓冲流可以增加字节读写的速率,提升应用程序的性能
			PushbackInputStream/PushbackOutputStream

DataInputStream/DataOutputStream

		提供读取/写入多种数据的能力
			readXXX();writeXXX()
		构造方法
			DataInputStream(InputStream in)
			DataOutputStream(OutputStream out)
		DatainputStream/Data0utputStream中文乱码问题
			数据流如果用read/write方法读写中文,有可能会出现乱码问题,解决方法:
				String构造方法可以指定对byte数组做其他编码方式的解码,如 new String(bytes,”gbk”);
				同时也可以使用readUTF和writeUT 方法解决乱码问题

BufferedInputStream/BufferedOutputStream

		缓冲输入/缓冲输出
		BufferedInputStream支持mark和reset方法
		构造方法:
				BufferedInputStream(InputStream in)
				BufferedInputStream(InputStream inint size)
		常用方法:
				read(bytes[]b,int offset,int fength)
					第一个参数:构建缓冲区数组
					第二个参数:读取文件的起始位置
					第三个参数:每次读取文件的长度
				mark方法和reset方法
					mark(int readlimit):
						在输入流的当前位置做标记,配合reset方法的后续调用将此流重新定位在最后标记的位置上,以便后续读取操作重新读取相同的字节
					reset():将此流重新定位到对此输入流最后使用mark方法时的位置

BufferedOutputStream

		常用方法:
				flush():这是每个输出流都有的方法,作用为刷新此输出流S write(bytes[]b,int offset,int length):
					第一个参数:构建缓冲区数组
					第二个参数:写入文件的起始位置·第三个参数:每次写入文件的长度
				write(int b):将指定字节b写入此缓冲的输出流中
PrintStream				
		方便地打印各种数据值表示形式
		与其他输出流不同,PrintStream不会抛出l0Exception;而是,异常情况仅设置可通过checkError方法测试的内部标志。
		支持自动刷新;这意味着可在写入字节数组之后自动调用flush 方法,可调用其中一个println 方法,或写入一个新行字符或字节(\n')。		

第二章IO流编程2

配置文件

		是一个文件,后缀一般为ini、properties或者xml文件作用:用户登录时定义加载环境所需的设置和文件的集合格式
		键=值
		例如
		user=qq password=123456

读取配置文件

		FilelnputStream fis =new FilelnputStream(“config.ini");
		Properties prop=new Properties();
		//从文件中加载配置
		prop.load(fis);
		//根据键名取值
		String user=prop.getProperty(“user");

修改并保存配置到文件

		//修改健名为user的健值admin,如果健名不存在,
		//则新增。
		prop.setProperty("user","admin");
		//把prop里的健值对保存到文件config.ini 
		FileOutputStream fos =new File0utputStream("config.ini");
		prop.store(fos,“备注”);

Reader

		字符输入流
		子类:
					BufferedReader	字符缓冲输入流
					InputStreamReader	字符输入流
										FileReader文件输入流
					StringReader字符串输入流
					PipedReader管道输入流
					ByteArrayReader字符数组输入流
					FilterReader	字符过滤输入流
										PushbackReader推回输入流
		抽象类
		读取字符
		方法:		
					Reader()
					Reader(Object lock)
					read():int 
					read(char cbuf[]):int 
					read(char cbuf[],int off,int len):int 
					skip(long n):long ready():boolean 
					markSupported():boolean 
					mark(int readAheadLimit):void 
					reset():void
					close():void

FileReader

		使读取字符文件成为可能
		构造方法
			FileReader(File file)
			FileReader(String fileName)

BufferedReader

		从字符输入流中读取文本,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
		构造方法:BufferedReader(Reader r)
		readLine()从流中读一行
		用法
		while((String str=bf.readLine())!=null)

Writer

		子类:	
					BufferedWriter字符缓冲输出流
					OutputStreamWriter字符输出流
										FileWriter文件输出流
					PrinterWriter打印输出流
					StringWriter字符串输出流
					PipedWriter管道输出流
					CharArrayWriter字符数组输出流
					FilterWriter字符过滤输出流
		写入字符类型
		方法:	
					Writer()
					Writer(Object lock)
					write(int c):void 
					write(char cbuf[]):void 
					write(char cbuf[],int off,int len):void 
					write(String str):void 
					write(String str,int off,int len):void 
					flush():void
					close():void

FileWriter文件输出流

		允许将字符类型数据写入文件
		构造方法
			FileWriter(File file);FileWriter(String fileName);

BufferedWriter

		将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
		newLine()
		write(Strings,int off,int 1en)
		除非要求提示输出,否则建议用BufferedWriter包装所有其 write()操作可能开销很高的Writer(如FileWriters和0utputStreamWriters)。例如,PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

字节流和字符流转换

		InputStreamReader把字节输入流转换成字符流
		0utputStreamWriter把字符流写到字节流
		例子:用字节流打开文件,然后转成字符流
		FilelnputStream fis= new FilelnputStream("e:/student.c");
		InputStreamReader isr=new InputStreamReader(fis);

获取键盘输入

		//System.in是键盘输入流
		//把键盘输入转成字符流
		InputStreamReader isr=new InputStreamReader(System.in);
		//用缓冲字符流封装,以允许读一行
		BufferedReader br=new BufferedReader(isr);
		//从键盘读取一行
		String line=br.readLine();

对象流

		序列化
				序列化是把一个对象的状态写入一个字节流的过程。
				如果一个对象引用到其它对象,而这些对象又引用另外的对象,那么所有这些对象都会被序列化。
		Serializable接口
				只有实现Serializable接口的对象才能被序列化工具存储或者恢复。
				声明为transient的变量不被序列化工具存储。
				static变量同样不被存储。
		ObjectOutputStream
				构造方法
					public ObjectOutputStream(OutputSteam os)
				负责向流写入对象
					public void writeOb ject(Object obj)
		ObjectInputStream
				构造方法
					public ObjectInputStream(InputSteam is)
				负责从流读出对象(反序列化)
					public Object readObject()

第三章多线程编程1

程序/进程/线程

			程序:
				一堆命令的集合,进程的静止的状态,包括了可执行文件、配置文件、数据文件等等软件文件集合
			进程:
				程序运行期间的动态状态,占用内存、占用CPU等系统资源线程:
			线程:
				进程下的最小的执行单元,多任务处理的最基本的执行单元

多任务处理

			进程是指一种“自包容”的运行程序,有自己的地址空间;线程是进程内部单一的一个顺序控制流
			基于进程的特点是允许计算机同时运行两个或更多的程序。
			基于线程的多任务处理环境中,线程是最小的处理单位。
			两种类型:基于线程和基于进程

基于线程的多任务处理的优点

			基于线程所需的开销更少
				在多任务中,各个进程需要分配它们自己独立的地址空间
				多个线程可共享相同的地址空间并且共同分享同一个进程
			进程间调用涉及的开销比线程间通信多
			线程间的切换成本比进程间切换成本低

多线程

			在Java中,一个应用程序可以包含多个线程。每个线程执行特定的任务,并可与其他线程并发执行
			多线程使系统的空转时间最少,提高CPU利用率
			多线程编程环境用方便的模型隐藏CPU在任务间切换的事实

主线程

			在Java程序启动时,一个线程立刻运行,该线程通常称为程序的主线程。
			主线程的重要性体现在两个方面:·它是产生其他子线程的线程。
					通常它必须(除了守护线程之外)最后完成执行,因为它执行各种关闭动作。
					主线程并不一定负责去关闭其他的子线程
					主线程并不一定是最后结束的(守护线程)

Thread

构造方法

					Thread()
					Thread(Runnable target)
					Thread(Runnable target,String name)
					Thread(String name)

创建线程

			通过以下两种方法创建Thread对象:
					声明一个Thread 类的子类,并覆盖run()方法。
					class mythread extends Thread{
						public void run(){/*覆盖该方法*/}
					}
					声明一个实现Runnable接口的类,并实现run()方法。
					class mythread implements Runnable{
						public void run(){/*实现该方法*/}
					}

创建线程-继承Thread

			继承Thread 
			public class ExtendsThead extends Thread{
					public void run){
					//线程要执行的代码
					}
			}
			创建并启动线程
			ExtendsThead et=new Extends Thread();
			et.start();				

创建线程一实现Runnable接口

			实现Runnable接口
			public class ImplRunnable implements Runnable{
				public void runO{
				//线程要执行的代码
				}
			}
			创建并启动线程
			ImplRunnable ir=new ImplRunnable();
			Thread thread=new Thread(ir);
			thread.start();

Thread重要方法

					start()启动线程;
					setPriority(int p)设置线程的优先级;
					interrupt()有条件中断线程;
					sleep(long s)(static)使线程睡眠;让出cpu资源;
					currentThread()(static)获取当前正在执行的线程;
					isAlive()判断线程是否在活动状态;
					yield()让出cpu资源;
					setDaemon(boolean b)是否是守护线程;
					join()等待线程消亡;

连接线程-join()

			//ExtendsThread和ImplRunnable是前面的例子
			ExtendsThread et= new ExtendsThread();
			ImplRunnable ir=new ImplRunnable();
			Thread thread=new Thread(ir);et.start();
			et.join();//把et加入到当前线程,等待et线程结束,才能继续执行后面的代码。
			thread.start();				

线程的状态

			新建(Born):新建的线程处于新建状态
			就绪(Ready):在创建线程后,它将处于就绪状态,等待 start()方法被调用
			运行(Running):线程在开始执行时进入运行状态
			睡眠(Sleeping):线程的执行可通过使用sleep()方法来暂时中止。在睡眠后,线程将进入就绪状态
			等待(Waiting):如果调用了wait)方法,线程将处于等待状态。用于在两个或多个线程并发运行时
			挂起(Suspended):在临时停止或中断线程的执行时,线程就处于挂起状态
			恢复(Resume):在挂起的线程被恢复执行时,可以说它已被恢复
			阻塞(Blocked)-在线程等待一个事件时(例如输入/输出操作),就称其处于阻塞状态
			死亡(Dead)-在run()方法已完成执行或其stop()方法被调用之后,线程就处于死亡状态				
			状态图:
						就绪->运行->死亡
						运行->挂起->就绪
						运行->堵塞->就绪
						运行->睡眠->就绪
						运行->等待->就绪

可能使线程暂停执行的条件

			线程优先级比较低,因此它不能获得CPU时间。
			使用sleep()方法使线程睡眠。
			通过调用Object.wait()方法,使线程等待。
			通过调用yield()方法,线程已显式出让CPU控制权。
			线程由于等待一个文件I/O事件被阻塞。

线程的优先级

			Java中的线程优先级是在Thread类中定义的常量:
					NORM_PRIORITY:值为5
					MAX_PRIORITY:值为10
					MIN_PRIORITY:值为1
			缺省优先级为NORM_PRIORITY
			有关优先级的方法有两个:
					final void setPriority(int newPriority):修改线程的当前优先级
					final int getPriority():返回线程的优先级								

Thread.yield

			Thread.yield方法:让出CPU的资源,让其它的线程执行。
			yield方法使当前线程让出CPU占有权,但让出的时间是不可设定的。实际上,yield()方法对应了如下操作:先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把CPU的占有权交给此线程,否则,继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程。				

守护线程

			守护线程是一类特殊的线程,它从属于创建它的线程,它和普通线程的区别在于它并不是应用程序的核心部分,当一个应用程序的所有非守护线程终止运行时,即使仍然有守护线程在运行,应用程序也将终止,反之,只要有一个非守护线程在运行,应用程序就不会终止。守护线程一般被用于在后台为其它线程提供服务。
			setDaemon(true)用于把一个线程设置成守护线程。				

守护线程示例

			public class DaemonThread extends Thread{
				public DaemonThread){
						setDaemon(true);//设置成守护线程
				}
				public void run){
						try{
								Thread.sleep(2000);
						}catch(InterruptedException e){}
						System.out.printIn("DaemonThread exit;");	
				}
			}

守护线程调用

			public static void main(String[]args){
						DaemonThread thread =new DaemonThread();
						thread.start();
						try{
							Thread.sleep(3000);
						}catch(InterruptedException e){}
			}

结束线程

			结束线程就是让线程的run方法执行完毕
			尽量不使用stop()或者destroy()方法来结束线程,应尽量让线程中run方法运行正常结束的方法
			结束线程可以使用以下三种方法:
			   修改标志
			   interrupt()/中断线程
			   引发异常

结束线程方法1-修改标志

			适用于停止不阻塞的线程
			public void run){
				//flag是个全局的布尔型变量
				while(flag){
					//运行的代码,没有阻塞的代码
					public void setFlag(boolean flag){
						this.flag=flag;
					}
				}
			}				
			此类线程可以通过修改flag的值来终止线程。

停止线程方法2-interrupt()

			适用于睡眠或者等待
				public void run){
					while(!this.islnterrupted)){
						try{
							Thread.sleep(2000);
						}catch(InterruptedException e){}
					}
				}

			此类线程只要调用interrupt()方法就可以终止线程。

停止线程方法3-引发异常

			适用于阻塞(如监听连接,读网络上发来的数据)
				public void run(){
						byte[]buf=new byte[2048];
						int len;
						while(true){
							try{
								//bi是缓冲输入流
								len=bi.read(buf);
								//其他代码
							}catch(l0Exception e){
								//异常处理
								break;//跳出循环,线程也就结束。
							}
						}
				}

第四章多线程编程2

同步

				当两个或多个线程需要访问同一资源时,它们需要以某种顺序来确保该资源某一时刻只能被一个线程使用的方式称为同步。

Java如何同步?

				同步基于“监视器”这一概念。“监视器”是用作互斥锁的对象;在给定时刻,只有一个线程可以拥有监视器。Java中所有的对象都拥有自己的监视器。
				两种方式实现同步:
						使用同步方法
						synchronized void methodA(){}
						使用同步块(同步块需要指定“同步监视器”,即上锁的对象)
						synchronized(object){
						//要同步的语句
						}
				注意:synchronized关键字是不继承的(synchronized f(){}在继承之后,会变成f(){},继承类需要显式指定它的某个方法为synchronized方法)

Java中“锁”的概念

				Java中每一个对象都有一个lock
				当访问一个对象的synchronized方法的时候,该对象就会被上锁
					注意:被上锁的是对象,而不是方法,举例来说,如果一个对象中有多个synchronized方法,如果线程访问到其中的一个synchronized方法时,此时不能同步访问其他的方法
				Java中的同步“锁”:
					同步锁
					静态锁
					死锁

同步锁(synchronized的互斥机制)

				当synchronized被加在多个方法或者成员变量的时候,并且我们用多个线程去访问任意一个用synchronized修饰的方法或者变量的时候,保证有且仅有一个线程在同一个时刻能够访问到synchronized资源。剩余的线程需要等带同步锁对象解锁之后才能够访问synchronized资源。
				注:非synchronized资源不受影响

静态锁

				静态锁:在静态方法中使用同步锁;
						如果在静态方法上使用synchronized修饰,该方法具有同步的效果,但是该锁和对象无关
				Synchronized和static synchronized的区别:
						synchronized相当于是this.synchronized,对象在访问synchronized资源的时候,会生成一个该类实例的监视块
						static synchronized相当于是类.synchronized,所有该类的实例共用一个监视块

死锁

				当两个线程循环依赖于一对同步对象时将发生死锁。
				例如:
					一个线程进入对象0bjA上的监视器,而另一个线程进入对象0bjB上的监视器。如果0bjA中的线程试图调用0bjB上的任何synchronized 方法,就将发生死锁。
				死锁很少发生,但一旦发生就很难调试。

第五章网络编程

网络通信基本概念-协议

				协议是一组在网络上发送信息的规则和约定。这些规则控制在网络设备间交换消息的内容、格式、定时、顺序和错误控制。
				0SI(Open System Interconnect)开放系统互连参考模型(低到高)
						物理层
						数据链路层
						网络层
						传输层
						会话层
						表示层
						应用层

网络通信基本概念-lP

				在Internet上有千百万台主机,为了区分这些主机,人们给每台主机都分配了一个专门的地址,称为IP地址。
				32位数字,四个用点号分隔的数字
				包括网络lD和主机ID
				网络的类包括A、B、C、D、E类				

网络通信基本概念-DNS

				DNS(Domain Name System)域名系统
				ip地址都是数字,太难记
				DNS将lP地址映射至字符串
				映射由域名服务器系统维护

网络通信基本概念一端口

				协议				端口
				Telnet协议 			  23
				简单邮件传输协议smtp  25
				文件传输协议ftp       21
				超文本传输协议http    80
				有别于设备端口,是用来理解的逻辑概念
				用于实现程序间的通信

URL

				URL(Uniformed Resource Location)指向Internet上的资源文件
				统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址
				URL类提供API来访问Internet上的信息
				URL的组件
				构造方法
						URL(String urlname)
						URL(String protocol,String hostname,int port,String path)
						URL(String protocol,String hostname,String path)
				URLConenction openConnection()

URLConnection

				抽象类
				用于封装由URL表示的Web对象的连接
				提供进一步了解远程资源的方法
				InputStream getInputStream()
				0utputSteam getOutputStream()
				例子:
				URL url=new URL(urlString); 
				URLConnection conn = url. openConnection);

InetAddress

				InetAddress的实例包含IP地址,还可能包含相应的主机名。
				工厂方法用于创建实例
					InetAddress getLocalHost()
					InetAddress getByName(String host)
					InetAddress[] getAllByName(String host)

取本机计算机名及所有IP地址

				//InetAddress 此类表示互联网协议(IP)地址。
				InetAddress addr=null;
				try{
				addr=InetAddress.getLocalHost();
				String hostName=addr.getHostName();//取得本机机器的名字
				String ip =addr.getHostAddress();
				InetAddress[]addrs=InetAddress.getAl1ByName(hostName);
				//保存ip的数组
				String[]allIp =new String[addrs.1ength];
				for(int i=0;i<addrs.length;i++){
				a11Ip[i]=addrs[i].getHostName();}
				}catch(UnknownHostException e){}

什么是TCP?

				TCP(传输控制协议)是一种基于流的网络通讯方法,它与其它的任何协议都有很大的不同。TCP提供的网络通讯接口与UDP(用户数据报协议)截然不同:
				基于UPD与基于TCP相比,基于UDP的通信传输速度更快;
				但基于UDP的通信不能提供可靠性,即发出的信息接收方不一定收到,发出信息的顺序与接收的顺序不一定相同。
				TCP三次握手通信原理:TCP三次握手的通信过程是发生在建立通信的过程中,而并非是发生在通讯过程中的。

TCP通信过程

				我们可以将基于TCP的通信比做打电话;一方负责监听,一方负责呼叫,呼叫的一方为客户端,监听的一方为服务器端。
				服务器端ServerSocket绑定于特定端口,服务器侦听socket等待连接请求
				客户端向服务器和特定端口提交连接请求
				服务器接受连接,产生一新的socket,绑定到另一端口,由此socket来处理和客户端的交互,服务器继续侦听原socket来接受其他客户端的连接请求
				连接成功后客户端也产生一socket,并通过它来与服务器端通讯(注意:客户端socket并不与特定端口绑定)
				服务器端和客户端就通过读取和写入各自的socket来进行通讯。

ServerSocket此类实现服务器套接字。

		构造方法
					ServerSocket(int port)
					ServerSocket(int port,int backlog)
					ServerSocket(int port,int backlog,InetAddress bindAddr)
				Socket accept()侦听并接受到此套接字的连接。

Socket

				实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器之间的通信端点。
				构造方法
					Socket(lnetAddress address,int port)
					Socket(String host,int port)
				通信要用到的常用方法
					InputStream getinputStream()
					OutputStream getOutputStream()

服务器端

				1.建立ServerSocket,表示对客户端连接感兴趣:
					ServerSocket server=new ServerSocket(8321);
				2.等待客户端连接:
					Socket socket=server.accept();
				4.连接之后就可以获得流开始通信了
					0utputStream os=socket.getOutputStream();
					InputStream is=socket.getInputStream();
					可以对输入输出流进行套接以便发送不同的数据。

客户端

				3.建立Socket连接到ServerSocket 
				Socket socket=new Socket(“127.0.0.1",8321);
				5.通过Socket得到输入输出流就可以和服务器通信了。
					0utputStream os=socket.getOutputStream();
					InputStream is=socket.getlnputStream();
					可以对输入输出流进行套接以便发送不同的数据。

第六章Mysql基础

DB和DBMS

				DB-数据库(DataBase,简称DB)是按照数据结构来组织,存储和管理数据的仓库。
				DBMS-数库管理系统(DataBase Mapager System,简称DBMS)用来管理数据库的软件。

数据库基本概念

				数据库
					是用户存放数据、访问数据、操作数据的存储仓库,用户的各种数据被有组织的存放在数据库中。可以随时被有权限的用户查询、统计、添加、删除、和修改。
					是长期存储在计算机内的,有组织、可共享的数据集合。数据库系统是由普通的文件系统发展而来的。
					数据库系统具有较高的数据独立性,即不依赖于特定的数据库应用程序;
					数据库系统的数据冗余小,可以节省数据的存储空间;
					另外数据库系统还很容易实现多个用户的数据共享。

数据库发展历史

				数据库的发展史
					萌芽阶段---—-文件系统
						使用磁盘文件来存储数据
					初级阶段--—-第一代数据库
						出现了网状模型、层次模型的数据库
					中级阶段----第二代数据库
						关系型数据库和结构化查询语言
					高级阶段----—-新一代数据库
						“关系-对象”型数据库
					最新阶段-----—-非关系型数据库

数据库管理系统

				数据库管理系统(DBMS)
					是数据库成熟的标志
					是管理数据库的一个软件
					DBMS是所有数据的知识库,并对数据的存储、安全、一致性、并发操作、恢复和访问负责。·DBMS有一个数据字典(有时被称为系统表),用于贮存它拥有的每个事物的相关信息,例如名字、结构、位置和类型,这种关于数据的数据也被称为元数据(metadata)
					数据库管理系统的核心是一个用来存储大量数据的数据库。

关系数据库概念

				关系型数据库
					关系模型数据库采用表组织数据(表称为“关系”),一个数据库由许多个表组成,多个表数据之间存在着关系,在这些表上的数据操作依赖于关系,关系用来描述多个表之间的数据依存,包括了一对一、一对多、多对多的关系
					桌面型的关系模型数据库
								MS ACCESS
					网络型的关系模型数据库
								0racle
								DB2
								Sybase
								MS SQL Server
								My sql(开源)
				概念模型:基于客户的想法和观点所形成的认识和抽象。
						实体(Entity):客观存在的、可以被描述的事物。例如员工、部门。
						属性(Attribute):用于描述实体所具有的特征或特性。如使用编号、姓名、工资等来属性来描述员工的特征。
						关系(Relationship):实体之间的联系。
						一对一:人和身份证
						一对多:班级和学生
						多对多:学生和课程

MySql数据库

						MySql是最流行的开放源码的数据库管理系统。
						MySql是一种关系数据库管理系统。·MySql软件是一种开放源码软件。
						MySql数据库服务器具有快速、可靠和易于使用的特点。
						MySql服务器工作在客户端/服务器模式下,或嵌入式系统中。

MySql字符集设置

				设置的两种方式
						用sql命令“SET NAMES字符集名”,每次连接数据库都得执行一次。
						如:SET NAMES‘gbk'
				显示当前客户端的字符集
						SHOW VARIABLES LIKE‘character_set_clent'
				已有数据的字符集修改
						不能直接用ALTER DATABASE CHARACTER SET XXX进行字符集的修改,这样原有数据会乱码。
						对于已有数据的字符集调整,需要先导出数据,调整字符集后再导入。

第七章DDL和DML

SQL

				结构化查询语言(Structured Query Language)
				在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。
				使用SQL语句,程序员和数据库管理员可以完成如下的任务
					改变数据库的结构
					更改系统的安全设置
					增加用户对数据库或表的许可权限
					在数据库中检索需要的信息
					对数据库的信息进行更新

SQL语句分类

				MySql致力于支持全套ANSI/ISOSQL标准。
				在MySql数据库中,SQL语句主要可以划分为以下几类:
					DDL(Data Definition Language):数据定义语言,定义对数据库对象(库、表、列、索引、约束)的操作。
						CREATE、DROP、ALTER、RENAME、TRUNCATE等
					DML(Data Manipulation Language):数据操作语言,定义对数据库记录的操作。
						INSERT、DELETE、UPDATE、SELECT等
					DCL(Data Control Language):数据控制语言,定义对数据库、表、字段、用户的访问权限和安全级别。
						GRANT、REVOKE等
					Transaction Control:事务控制
						COMMIT、ROLLBACK、SAVEPOINT等

SQL语句的书写规范

					在数据库系统中,SQL语句不区分大小写(建议用大写)。
					但字符串常量区分大小写。
					SQL语句可单行或多行书写,以“;”结尾。
					关键词不能跨多行或简写。
					用空格和缩进来提高语句的可读性。
					子句通常位于独立行,便于编辑,提高可读性。·SELECT*FROM tb_table
					注释:
						SQL标准:
							/**/。多行注释
							“--”单行注释
						MySql注释:
							“#”

SQL操作:

 					删除表
						drop table user3;删除结构和数据
						truncate table user3;删除数据,表结构还在

					alter 修改结构
					修改列类型
						alter table 表名 MODIFY 列名 列类型
					增加列
						alter table 表名 add 列名 列类型

					删除列
						alt3er table 表名 drop 列名

					更改列名
						alter table 表名 change 旧列名 新列名 列类型
						rename table 表名 to 新表名

					删除列
						alter table user drop age;
					更改表名
						alter table user rename user1;
						rename table user1 to user;

什么是约束

					约束是在表上强制执行的数据校验规则.
					约束主要用于保证数据库的完整性。
					当表中数据有相互依赖性时,可以保护相关的数据不被删除.
					大部分数据库支持下面五类完整性约束:
						NOT NULL非空
						UNIQUE Key唯一键·PRIMARY KEY主键·FOREIGN KEY外键
						CHECK检查

约束概述

					约束作为数据库对象,存放在系统表中,也有自己的名字
					创建约束的时机
						在建表的同时创建
						建表后创建(修改表)
					可定义列级或表级约束
					有单列约束和多列约束

定义约束的语法

					列级约束:在定义列的同时定义约束
						语法:列定义约束类型,
					表级约束:在定义了所有列之后定义的约束
						语法:列定义……
						[CONSTRAINT约束名]约束类型(列名)
					约束名的取名规则
						推荐采用:表名_列名_约束类型简写
					约束可以在创建表时就定义,也可以在创建完表后再添加
					语法:
						ALTER TABLE表名
						ADD CONSTRAINT约束名约束类型(要约束的列名)

非空约束(NOT NULL)

					列级约束,只能使用列级约束语法定义。
					确保字段值不允许为空
					只能在字段级定义

NULL值

					所有数据类型的值都可以是NULL。
					空字符串不等于NULL。
					0也不等于NULL。	

非空约束(NOT NULL)

					CREATE TABLE tb_student(
							id INT PRIMARY KEY AUTO_INCREMENT,
							NAME VARCHAR(18)NOT NULL
					)

唯一约束

UNIQUE

					唯一性约束条件确保所在的字段或者字段组合不出现重复值
					唯一性约束条件的字段允许出现多个NULL
					同一张表内可建多个唯一约束
					唯一约束可由多列组合而成
					建唯一约束时MySQL会为之建立对应的索引。
					如果不给唯一约束起名,该唯一约束默认与列名相同。
					CREATE TABLE tb_student(
						id INT PRIMARY KEY AUTO_INCREMENT,
						NAME VARCHAR(18)UNIQUE NOT NULL
					)

主键约束

					主键从功能上看相当于非空且唯一
					一个表中只允许一个主键
					主键是表中唯一确定一行数据的字段
					主键字段可以是单字段或者是多字段的组合
					当建立主键约束时,MySQL为主键创建对应的索引
					主键约束名总为PRIMARY。
					用法:字段名后面加上PRIMARY KEY

外键约束

					外键是构建于一个表的两个字段或者两个表的两个字段之间的关系
					外键确保了相关的两个字段的两个关系:
					子(从)表外键列的值必须在主表参照列值的范围内,或者为空(也可以加非空约束,强制不允许为空)。
					当主表的记录被子表参照时,主表记录不允许被删除。
					外键参照的只能是主表主键或者唯一键,保证子表记录可以准确定位到被参照的记录。
					格式FOREIGN KEY(外键列名)REFERENCES 主表(参照列)
					用法:字段后加REFERENCES 表名(字段名)
							CONSTRAINT FOREIGN KEY 表名 (字段名)REFERENCES 它表名(字段名)

Check 约束(Mysql会忽略)

					既可作为列级约束,也可作为表级约束
					定义在字段上的每一记录都要满足的条件
					在check中定义检查的条件表达式,数据需要符合设置的条件
					条件表达式不允许使用
					-参照其他记录的值
					CREATE TABLE tb_student(
						id INT PRIMARY KEY AUTO_INCREMENT,
						NAME VARCHAR(18),
						age INT CHECK(age >18 AND age〈 60)
					)

列级约束和表级约束

					列级约束直接跟在列后定义,不再需要指定列名,与列定义之间用空格分开
					表级约束通常放在所有的列定义之后定义,要显式指定对哪些列建立列级约束。与列定义之间采用英语逗号,隔开。
					如果是对多列建联合约束,只能使用表级约束语法。

增加约束

					可增加或删除约束,但不能直接修改
					可使约束启用和禁用
					非空约束必须使用MODIFY子句增加
					只要是可以使用列级约束语法来定义的约束,都可以通过modify来增加该约束。
						-ALTER TABLE table
						-ADD[CONSTRAINT constraint]type(column);
					加FOREIGNKEY约束到EMP表
						ALTER TABLE tb_employee 
						ADD CONSTRAINT tb_emp loyee_dept_id_fk 
						FOREIGN KEY(dept_id)REFERENCES tb_dept(dept_id);

删除定义的约束

					删除NOT NULL约束
						ALTER TABLE 表名MODIFY列名类型;
					删除UNIQUE约束
						ALTER TABLE 表名DROPINDEX惟一约束名:
					删除PRIMARY KEY约束
						ALTER TABLE 表名DROP PRIMARY KEY;
					删除FOREIGN KEY约束
						ALTER TABLE 表名DROP FOREIGNKEY外键名;

自动增长和默认值

					AUTO_INCREMENT自动增长
					default 默认值

第八章单表查询

DML

					增
						insert into 表名(列名) values(值)
					删
						delete from 表名 where 列名 = 值
					改
						update 表名 set 列名= 值 where 条件
					查
						select 列名 from 表名 where 条件 group by 列名 having 条件 order by 列名 limit 开始,几条

非空

					is not null

模糊查询

					like '%张%'
					名字有含张的
					_表示匹配一个字符
					between		在范围之间
					in   		或

第九章多表查询

MySQL多表查询

					多表查询分:交叉连接、内连接、外连接;
					交叉连接不带WHERE子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。
					内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分三种:等值连接、自然连接、不等连接;最常见的是等值连接。>外连接返回到查询结果集中的不仅包含符合连接条件的行,而且还包括左表(左外连接或左连接)、右表(右外连接或右连接)或两个边接表(全外连接)中的所有数据行;外连接:左连接、右连接、全连接。

交叉连接

					交叉连接是不带WHERE子句的多表查询,它返回被连接的两个表所有数据行的笛卡尔积

INNER JOIN ON-—-内连接

					语句:select*from a_table a INNER J0IN b_table b ON a.a_id=b.b_id;

left join on/left outer join on—左外连接

					语句:seTect*from a_table a left join b_table b on a.a_id=b.b_id;
					说明:
					left join 是left outer join的简写,它的全称是左外连接,是外连接中的一种。
					左(外)连接,左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NOLL。

right join on/right outer join on—右外连接

					语句:seTect*from a_table a right join b_table b on a.a_id=b.b_id;
					说明:
					right join right outer join的简写,它的全称是右外连接,是外连接中的一种。
					右(外)连接,右表(b_table)的记录将会全部表示出来,而左表(a_table)只会显示符合搜索条件的记录。左表记录不足的地方均为NOLL。

全连接

					说明:MySQL不支持全连接,所以只能采取关键字UNION来联合左、右连接的方法。
					示列:
					SELECT*FROM class a RIGHT OUTER JOIN t studentnew b ON a.class id=b.s id UNION SELECT*FROM class a LEFT OUTER JOIN t_studentnew b ON a.class_id=b.s_id

聚合函数

					说明:聚集函数是运行在行组上,计算和返回单个值的函数。
					常见聚合函数:
					AVG()返回某列的平均值
					COUNT()返回某列的行数
					MAX()返回某列的最大值
					MIN()返回某列的最小值
					SUM()返回某个列之和

第十章Mysql系统函数

MySQL函数-—-数学函数

					函数				功能
					ABS(x)		返回x的绝对值
					RAND()		0-1的随机数
					ROUND(x,y)	返回参数x的四舍五入的有y位小数的值
					MOD(x,y)		返回x/y的模(余数)
					PI()			返回pi的值(圆周率)
					SQRT(x)		返回一个数的平方根
					GREATEST(X1,×2...…xn)	返回集合中最大的值
					LEAST(X1,×2...…xn)	返回集合中最小的值

MySQL函数–字符串函数

					函数				功能
					ASCcl(str)		返回字符串的ASCII码
					CONCAT(Str1,str2.…)	将给定字符串拼接
					LENGTH(Str)		返回给定字符串长度
					LEFT(Str,len)	返回给定字符串最左len个字符
					RIGHT(Str,len)	返回给定字符串最右len个字符
					SUBSTRING(Str,pos)	字符串str的起始位置pos					返回一个子串
					REVERSE(str)		将str顺序反转
					LOWER(str)		str转为小写
					UPPER(Str)		str转为大写

MySQL函数-—-时间函数

					函数				功能
					CURTIME()			HH:MM:SS或HIMMSS返回当前时间值
					NOW()				YYYY-MW-DDH田:MW:SS'或YYYYMMDDHIMMSS
					CURDATE()			YYYY-MM-DD’或YYYYMMDD
					WEEKDAY(date)		返回日期的星期索引(0开始)
					DAYOFYEAR(date)	返回给定日期的天数

第十一章JDBC编程技术

JDBC简介

JDBC概念

					1、JDBC(Java DataBase Connectivity):Java语言与SQL语句相互结合且独立于特定的数据库系统的应用程序编程接口(API)。
						JDBC设计的目的:它是一种规范,设计出它的最主要的目的是让各个数据库开发商为Java程序员提供标准的数据库访问类和接口,使得独立于DBMS的Java应用程序的开发成为可能(数据库改变,驱动程序跟着改变,但应用程序不变)。
					2、ODBC(Open DataBase Connectivity):依赖微软os平台,导致Java的平台无关性技术特性和面向对象编程的特性都丧失、同时对数据库系统的访问效率也比较低——不能满足企业级大数据量的访问要求

JDBC作用:

						JDBC编程接口可以用纯Java语言编写完整的数据库访问的应用程序
						在程序中创建与物理数据库的连接
						发送标准的SQL语句到指定的关系型数据库系统中,以处理目标数据——查询、修改和增加、删除数据

java相关类

					Connection|此接口表示与数据的连接
					PreparedStatement |此接口用于执行预编译的SQL语句
					ResultSet |此接口表示了查询出来的数据库数据结果集
					Statement |此接口用于执行sQl 语句并将数据检索到ResultSet中
					DriverManager |此类用于加载和卸载各种驱动程序并建立与数据库的连接
					ResultSetMetaData |可用于获取关于ResultSet对象中列的类型和属性信息的对象

JDBC数据库访问过程

					1、注册和加载数据库驱动程序
					2、建立与数据库的连接通道
					3、构造SQL语句
					4、执行SQL语句(返回结果集)
					5、关闭资源
					详细:
							
							开始
							导入java.sql包
							加载并注册驱动程序jar包
							创建一个Connection 对象
							创建一个Statement对象
							执行语句
							使用ResultSet对象
							关闭ResultSet对象
							关闭Statement对象
							关闭连接
							结束

流行数据库的驱动加载

						MSSQL server JDBC驱动程序加载
							Class.forName(“com.microsoft.jdbc.sqlserver.SQBserverDriver”);
						Oracle JDBC驱动程序加载
							Class.forName("oracle.jdbc.driver.OradleDpiver)
						MySQL JDBC驱动程序加载
							Class.forName("com.mysql.jdbc.0rtver")
						注意:先手动导入数据库驱动包到工程的类库中
							例如mysql数据库的:
							/lib/mysql-connector-java-5 17-bin.jar

建立连接

						Connection conn=DriverManager.getConnection(url,username,password);

Statement语句

						execute:用于执行查询语句和更新语句
						executeUpdate:用于执行更新语句
						executeQuery:用于执行查询语句
				实例:
							Class.forName(“com.mysql.jdbc.Driver”);//加载驱动步骤1
							//连接参数
							String url="jdbc:mysql://127.0.0.1:3306/hqg";
							String user="bus";
							String password="bus";
							conn=DriverManager.getConnection(url,user,password);//获取连接
							Statement stmt=conn.createStatement();
							String sql=“select count(")as count from GT_area”;
							//步骤3
							ResultSet rs=stmt.executeQuery(sql);//步骤4
							while(rs.next(){
								int count=rs.getlnt(1);
							}
							rs.close();//步骤5
							stmt.close();
							conn.close();

PreparedStatement接口

					PreparedStatement接口继承自Statement,与Statement相比,PreparedStatement增加了在执行SQL调用之前,将输入参数绑定到SQL调用中的功能。
					预编译好处:
							它用于执行带或不带输入参数的预编译SQL语句。因为Preparedstatement对象已编译过,所以执行速度要快于Statement对象。因此当需要多次调用一条SQL语句时,可以考虑使用PreparedStatement接口。
							预防查询用户账号与密码的注入式攻击
							[拼接sql导致的bug:where 1=1 and passwor-9p1=1]
					要多次执行同一条SQL语句,使用PreparedStatement SQL语句
							在创建时提供参数在执行PreparedStatement时,只传递参
							数值通过不同的参数值多次调用,省去多次编译sql过程
					创建和使用PreparedStatement接口
							在创建PreparedStatement对象之后必须为参数赋值
							使用setXXX)方法
							用executeUpdate()方法执行SQL语句

JDBC事务

			事务概述:
							在jdbc的数据库操作中,一项事务是由一条或是多条表达式所组成的一个不可分割的工作单元。我们通过提交commit()或是回滚rollback()来结末事务的操作
			JDBC中事务特点
							在jdbc中,事务操作缺省是自动提交。他就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit)来提交,否则将调用rollback()进行回滚
			事务处理过程
							可以通过Connection调用setAutocommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用rollback()进行回滚。这样做可以保持相关数据的一致性
					conn.setAutoCommit(false);/禁止自动提交,设置回滚点
					conn.commit();//事务提交
					conn.rollback();/操作不成功则回滚

元数据

					元数据的定义
					元数据(Metadata)描述了程序集的内容,可以简单理解成用于描述数据的数据.					
					ResultSetMetaData resultMeta=rs.getMetaData;
					resultMeta.getColumnCount():得到表中的字段数
					resultMeta.getColumnName(i):得到表中的字段名称

类的反射及元注解

类的反射机制

					JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
					Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。					

反射机制-常用方法

					object.getClass();//获取object的Class
					c.getName();//获取类名com.guoke.dsk.McBean
					c.getSimpleName();/获取类名 McBean
					c.getDeclaredFields);//获得类的所有属性。包括private声明的和继承类
					getDeclaredField("name");//获得指定私有属性
					field.setAccessible(true);/设置属性是可以访问的
					field.get(object);/获得属性值
					getDeclaredMethods():获得类的所有方法。包括private声明的和继承类
					newlnstance():通过类的不带参数的构造方法创建这个类的一个对象。
					field.getName()			

反射-获取class

					1、通过对象调用getClass()方法来获取Person p1=new Person();Class c1=pl.getClass();
					2、直接通过类名.class的方式得到,该方法最为安全可靠,程序性能更高Class c2=Person.class;
					3、通过Class对象的forName()静态方法来获取,用的最多Class c3=Class.forName("com.ys.reflex.Person");					

自定义注解-元注解

					在jdk1.5引进了注解的,有许多框架都使用了注解,例如spring,hibernate.现将其简单介绍一下
					元注解:注解的注解,即java为注解开发特准备的注解			

元注解-Target

					@Target:定义注解的作用目标
						@Target(ElementType.TYPE)/接口、类、枚举、注解
						@Target(ElementType.FIELD)//字段、枚举的常量
						@Target(ElementType.METHOD)/方法
						@Target(Element Type.PARAMETER)/方法参数
						@Target(ElementType.CONSTRUCTOR)/构造函数
						@Target(ElementType.LOCAL_VARIABLE)//局部变量
						@Target(ElementType.ANNOTATION_TYPE)//注解
						@Target(ElementType.PACKAGE)///包			

元注解-Retention

					@Retention:定义注解的保留策略
						@Retention(RetentionPolicy.SOURCE)
						//注解仅存在于源码中,在class字节码文件中不包含
						@Retention(RetentionPolicy.CLASS)
						//默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
						@Retention(RetentionPolicy.RUNTIME)
						//注解会在class字节码文件中存在,在运行时可以通过反射获取到			

自定义注解

					@Documented
						拥有这个注解的元素可以被javadoc此类的工具文档化
					@Inherited 
						public@interface Inherited{}
						允许子类继承父类中的注解。即拥有此注解的元素其子类可以继承父类的注解			

创建、使用注解示例

					@Target(Element Type.FIELD)//作用城是类或音接口
					@Retention(RetentionPolicy.RUNTIME)//注解类型:运行时注解
					public 	@interface Column{
						String value();//注解只有一个变量时变量名必须为alue 
					}
						@Table("t_user")
						public class User(){
							@Column("id")
							private int id;
							@Column("u_name")
							private String name;			
						}

注解解析

					Tablet=(Table)c.getAnnotation(Table.class);
					获得类的注解
					f.isAnnotationPresent(Column.class)
					判断该注解是否存在
					Column column=f getAnnotation(Column.class);
					获得该注解		

如果有发现什么问题,请告知我一下,我会更正的
谢谢各位读者( ^ _ ^)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值