一、IO
input output
输入:外介到程序
输出:程序到外介
文件:
File 类 表示文件夹也可以表示文件
File file = new File(path);// path可以是绝对路径,也可以是相对路径
1、创建文件
createNewFile();(最好先用exists()检测下文件是否存在)
2、创建文件夹
mkdir()
3、删除文件(文件夹)
delete()
注意:文件夹的删除必须是该文件夹为空的情况下
4、文件遍历
怎样获取指定目录下所有文件(子孙目录下的文件)
(将一个目录下所有子孙文件名全部打印输出)
File[] files = file.listFiles();
4、文件名过滤器
FilenameFilter 接口
自定义类实现此接口即可
1) 创建一个文件对象 File dir = new File(path);
2) 该文件夹存在 dir.exists()
3) 得到文件夹下所有文件 File[] lists = dir.listFiles();
4) 不是空文件夹 lists!=null
//获取指定目录下所有文件,包括文件夹
File[] files = file.listFiles();
if (files != null) {
for (File f:files) {
if (f.isFile()){ //是文件
System.out.println(f.getAbsolutePath());
}else { //是文件夹继续往下找
//递归调用
foreachDir(f.getAbsolutePath());
}
}
}
//遍历当前目录下子孙文件夹
File[] files = file.listFiles();
if (files != null){
for (File f:files) {
if (f.isDirectory()) {
foreachDirByType(f.getAbsolutePath(),type);
}
}
}
二、IO流
1、流分类:
按方向分:输入流、输出流
按类型分:byte字节流(8位)
char字符流(16位)
2、字节输入流超类:InputStream
文件字节输入流:FileInputStream 文件的读操作
文件末尾结束符 EOF(end of file) =-1
read() 一次只读一个字节,对中文不支持
read(byte[] b) 一次性将文件内容读取存放到b数组,然后将b转换成String
文件字节输出流:FileOutputStream 文件的写操作
write(): 一次只写一个字节,对中文不支持
write(byte[] b) 一次性将byte数组内容写入文件
3、字符流
输入字符流超类:Reader
FileReader:一次读2个字节
输出字符流超类:Writer
FileWriter:一次写2个字节
4、缓冲流(一次读取一行)
是对字符流的增强
BufferedReader
读取文件,一次读一行
BufferedWriter
5、打印流
能打印各种类型的数据
只有输出流、不会抛异常
PrintStream:字节流,能输出字节、字符
PrintWriter:字符流
PrintStream与PrintWriter的对比
1)PrintStream是字节流,PrintWriter是字符流
2)PrintStream只能对字节流装饰,PrintWriter既可以对字节流、
也可以对字符流装饰
3)PrintStream能实现的功能,PrintWriter都可以实现, 但是PrintWriter出现的较晚
(解释System.out是一个PrintStream对象而不是一个PrintWriter对象)
4)PrintStream可以输出字符,但是字符的编码采用系统默认的编码格式。
4、 字节流转换成字符流
System.in 是一个InputStream字节流对象,实际上只能接收一个一个
的字节,输入不方便,这个时候可将其转换成字符流对象
InputStreamReader:字符流(字节流转成字符流的中间桥梁)
OutPutStreamWriter:字符流
5、IO流总结
1)名称凡是以Stream结尾的,都是字节流
2)名称凡是以Reader结尾的,都是输入字符流,凡是以Writer结尾
的都是输出字符流
3)高级流(缓冲流、打印输出流),读写效率相对来说较高
6、字节流和字符流的使用场景
字节流:
1)处理单位是字节,操作字节或字节数组
2)字节流可以处理任何类型的对象,包括二进制对象,
如图片、音频、视频都可以用字节流处理,一个byte一个byte读写
字符流:
1)处理单位是字符,操作单个字符、字符串、字符数组
它可以将字节转换成字符(采用unicode编码),多以对国际化支持较好
2)如果操作的是文本对象,包含中文,则采用字符流较好
3)效率上比字节流高
7、序列化
目标:将对象保存到磁盘中,或者允许在网络中传输对象
允许把内存中的对象转换成与平台无关的二进制流
反序列化:把二进制流转换成java对象
怎样将一个对象序列化呢?
步骤:
1、实现Serializable接口
2、ObjectOutputStream 对象字节输出流
反序列化 ObjectInputStream 对象字节输入流
三、多线程
1、进程:简单而言,就是运行的程序和所需要的资源(CPU、内存等)的集合
多个进程同时运行,就是多进程,操作系统几乎都是支持多进程
2、线程:基于进程的,粒度比进程小,是运行的程序的一个流程。
一个程序执行多个任务,每一个任务称为一个线程。
要点1:线程是进程的组成部分,一个进程可以拥有多个线程,但是至少有一个主线程。
要点2:线程是独立运行,是CPU强占式的,也就是当前运行的线程可能被挂起(暂定)
要点3:一个线程可以创建和撤销其他另外一个线程,同一个进程中的线程可以并发执行。
3、线程与进程的区别:
1):进程间的内存空间是独立的,但是线程的内存空间是共享的
2):线程的运行效率比进程高,利于通信。(由于共享)
3):线程的创建比进程消耗资源少,使用的也多。
4):多线程的实现比多进程容易(开销小,通信简单)
4、多线程的目标
提高运行效率,最大限度的使用CPU
5、多线程的实现方式
方式一:继承Thread类
重写run方法
实例化线程对象
调用start方法,启动线程
方式二:实现Runable接口
重写run方法
实例化Thread对象,传入自定义线程对象
调用start方法,启动线程
Java是单继承、多实现的
6、主线程名称默认是main,其他子线程名称默认是Thread-0/1/2......
7、线程优先级的
从1-10,级别依次增加,默认级别是5
set/getPriority(int pro) 获取设置线程级别
级别越高,代表被CPU执行的可能性越大
8、线程的生命周期
新建:创建一个线程对象
就绪:调用start方法
运行:获得CPU的时间片
阻塞:线程被挂起(暂停) sleep、join、IO
结束:线程运行完成或异常
sleep(毫秒):当前线程进入暂停,进入阻塞状态,CPU的时间片让给其他就绪状态的线程。
join():合并线程,等待合并的线程执行完成后当前线程才继续往下执行
yield():当前线程进入暂停,进入就绪状态,CPU的时间片让给优先级(+)就绪状态的线程。
sleep与yield的区别
1)sleep(毫秒),暂停线程,进入阻塞状态,CPU时间片让给其他线程(就绪状态),抛出中断异常
2)yield(),暂停线程,进入就绪状态,CPU时间片让给优先级相同或更高的线程,无异常
sleep的移植性,建议用sleep方法。
9、线程同步问题
多个线程同时操作同一个对象时,需要进行协调。
解决方式:
方式一:synchronized关键字
修饰方法:同步方法
修饰代码块:同步代码块
一个线程访问同步代码块时,其他非同步代码块可以被同时访问。
方式二:java5 Lock接口·
10、线程间的通信
多个线程同时工作,对共享的数据的有序操作
Object类
wait():当前对象等待,直到其他线程调用notify/All()方法。
notify():唤醒在此同步对象上的单个线程。
notifyAll():
多个线程互相等待对方持有的锁,而在得到对方的锁之前都不会释放自己的锁,
这种现象叫死锁。
11、线程池
如果并发的线程数目较大,但是每个线程执行的任务时间较短,
执行完后就结束了,频繁的创建线程会大大的影响系统效率。
采用线程池 线程执行完任务后不立即销毁,而是回收到线程池,
以便下一次任务的使用,这些线程的管理都由线程池负责。
12、线程池的创建
由Executors工厂类来产生
方式一:newCachedThreadPool()
创建可缓存的线程池,每个线程调用前,会在线程池中判断下是否有空闲的线程,
如果有则调用,没有则创建。
ExecutorService 接口
AbstractExecutorService 实现了 ExecutorService
ThreadPoolExecutor 继承 AbstractExecutorService
ExecutorService exe = new ThreadPoolExecutor();
方式二:newFixedThreadPool(int num)
创建一个固定个数的线程池,对于线程的最大并发数可控,
超出的线程会排队等待。
方式三:newSingleThreadExecutor()
创建单个线程的线程池。
方式四:newScheduledThreadPool(int num);
线程对象,启动线程延迟时长,线程创建间隔时长,单位
定时器:间隔固定时间执行重复的操作
创建一个定长线程池,支持定时(周期性的)执行任务。
shutdown();等到线程池中正在执行任务的线程完成再关闭
四、JSON
是一种轻量级的数据交换格式
java script object notation js对象标记语言
键值对
一个json对象{key:value,key:value,...}
一个json对象集合[{json对象},{json对象},...]
分类:
JSON对象(JSONObject) {}
JSON数组对象(JSONArray) []
JSONObject
1)、创建一个JSONObject对象
2)、将json格式的字符串转换成JSONObject对象
3)、Map转换成JSONObject对象
4)、java对象转换成JSONObject对象
JSONObject.fromObject(java对象);
JSONArray
1)、创建一个JSONArray对象
2)、List转换成JSONArray对象
五、JSOUP
解析HTMl工具 第三方
url/字符串(必须是html格式的)——>Document对象(文档)
Node节点:是文档中的节点(分为元素、属性、文本)
Element元素:继承Node,Attr(属性),Text(文本)
Document:继承Element,表示文档根节点
六、XML解析
HTML:超文本标记语言
规定的标签
XML: 可扩展标记语言
自定义标签:必须是成对出现(有开始、结束标签)
必须有一对根节点标签(其他标签包含在内)
Node:表示文档中的节点对象
Element:表示标签/元素节点,包含属性(Attr)、文本(Text),注释
继承Node
Document:文档对象,表示的文档的根节点,继承Node
DOM:Document Object Model 文档对象模型
DOM是html和xml文档的编程接口规范,和平台、语言是无关的。
利用dom规范,能够实现dom 文档和xml之间的相互转换,遍历、操作相应dom文档的内容。
DOM规范的核心就是树模型。
1.DOM解析
解析XML
构建器工厂->解析器->document
创建XML
转换器工厂->转换器->将document转换成xml文件
Document树->XML
步骤:
1、获取解析器工厂,得到解析器对象,创建空的document对象
2、创建节点(根节点、Element、Text、Attr)
3、设定节点之间的关系
4、创建转换器工厂,得到转换器
5、定义转换器输入对象(document对象转换成Source对象)
6、定义转换器输出对象(File对象转换成Result对象)
7、通过转换器转换。
更新XML
2.SAX解析
边读边解析,基于事件驱动的
基础类 DefaultHandler
stratDocument:文档开始
endDocument:文档结束
startElement:元素开始
endElement:元素结束
characters:文本处理
步骤:
1、自定义SAX解析器,继承DefaultHandler
2、重写以上方法(startElement、endElement、characters)
3、定义解析xml的方法(工厂-》解析器-》解析)
DOM解析与SAX解析的不同
DOM解析:一次性将整个文档读入,内存形成Dom树。易于小型文档的读写,
如果一次读入后需要多次处理DOM树,较适合。
SAX解析:基于事件驱动的,边读边解析。适用于大型文档,节省内存空间。
七、网络编程
1、网络分类:
按规模分:局域网(LAN)
城域网(WAN)
广域网(WAN)
最大的网络就是WWW 万维网
2、ISO组织
OSI七层网络模型
应用层:面向用户
表示层:数据格式、加密解密
会话层:管理用户连接
传输层:数据包传输(很关键的一层)
网络层:地址识别,路由器
数据链路层: 比特流 交换机
物理层:比特流 集线器(HUB)
“应是会输网恋里”
3、TCP/IP的四层网络模型
应用层:面向所有用户的应用程序
常用协议:
HTTP(80):超文本传输协议
FTP(21):文件传输协议
SMTP(25):简单邮件传输协议
DNS(53):域名解析协议(www.163.com)
Telnet(23):远程登录协议
SSH(22):
传输层:TCP、UDP
网络层:IP
网络接口层:比特流
4、协议:“合同”
计算机之间相互通信,必须要有一些约定,这些约定就是通信协议
5、IP地址
IPV4协议 IPV6协议
IP:唯一标识互联网上的一台计算机
192.168.0.1
由32位0/1组成的,8位之间以.分隔,4个8位二进制
00011111.1111111.00000000.10101010
分类:A、B、C、D、E
A类:10.0.0.0-126.255.255.255
B类:128.0.0.0-191.255.255.255
C类:192.0.0.0-233.255.255.255 常用段
本机IP:127.0.0.1
查看本机IP地址 ipconfig
DNS协议:解析域名成IP地址+端口
6、端口
范围:0-65535
0-1023:系统保留端口
1024-49151:注册端口,是应用程序通常使用此范围内端口
49152-65535:随机端口号,一般应用程序不使用此范围端口
tomcat:8080
mysql:3306
oracle:1521
http:80
7、JAVA中对网络编程的支持
java.net.*包
InetAddress:IP地址类
8、TCP socket通信
套接字 (socket)
TCP协议:面向连接的,它是在通信双方都建立一个socket,从而形成一个虚拟的链路。
java中服务器端:ServerSocket对象
客户端:Socket对象
socket通信步骤
1、创建服务器端的ServerSocket对象,设置建立连接的端口号
2、创建客户端的Socket对象,绑定服务器IP、端口号
3、服务器端侦听(accpet)
4、客户端发起连接
5、取得InputStream、OutputStream流对象
6、基于输入流、输出流对象进行通信
9、UDP
面向非连接的,不可靠的通信协议
a、只管发送消息,不管对方是否收到,UDP协议无法控制
b、没有建立连接,因此它的通信效率较高
c、应用场景:网络游戏、视频会议 B2B
JAVA中对于UDP通信的支持
DatagramSocket: 服务器端和客户端都用此套接字
DatagramPacket:数据报对象(发送和接收数据都是它)
包含目的IP+端口
socket对象.send(DatagramPacket d) 发送数据
socket对象.receive(DatagramPacket d) 接收数据
UDP通信
client端(发送方)
1、创建DatagramSocket对象(可先指定IP+端口,也不指定,在数据报中指定)
2、准备发送的数据(转换成byte数组)
3、创建DatagramPacket对象(byte数组、长度、IP、端口)
4、发送数据
server端(接收方)
1、创建DatagramSocket对象(端口号)
2、创建DatagramPacket对象(byte数组、长度)
3、接收数据报
4、提取数据报的内容(getData获取byte数组)
TCP与UDP协议比较
都是传输层的协议
1)、TCP面向连接的协议,UDP面向非连接的协议
2)、TCP是传输可靠的协议,UDP是传输不可靠的协议
3)、TCP传输效率低,UDP传输效率高
4)、TCP传输数据量(每次)无限制,UDP对传输的数据量有限制,最大不超过64K。
查看本机端口使用情况: netstat -ano
10、JAVA作为客户端访问互联网资源
URL:统一资源定位符,指互联网上的资源,通常,包含协议、IP地址、端口
Jsoup:url->Document对象
java:url->连接对象->输入、输出流——>网页内容
案例:通过URL获取百度网页内容
URL url = new URL("https://www.baidu.com/");
// 获取连接对象
URLConnection con = url.openConnection();
java程序作为客户端向互联网资源发送数据
方式一:get请求
参数带在url后用?分隔,多个参数之间用& http://localhost:8080/URLWEBDEMO/test.jsp?user=ZS&pwd=123456
http://localhost:8080/URLWEBDEMO/test.jsp?user=%E5%BC%A0%E4%B8%89
方式二:post请求
表单提交
参数是另外提交的,在浏览器地址栏不可见
url规范中是不支持中文的,但是通过浏览器访问url中可以带中文(浏览器对url中的中文进行了转码)
java程序作为客户端访问时,如果以get方式请求,参数有中文,则必须手动进行转码:
String dname = java.net.URLEncoder.encode("张三","UTF-8");
GET和POST的区别
GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,
POST方法是把提交的数据放在HTTP包的Body中.
GET提交的数据大小有限制(因为浏览器对URL的长度有限制),
而POST方法提交的数据没有限制.
GET方式需要使用Request.QueryString来取得变量的值,
而POST方式通过Request.Form来获取变量的值,
也就是说Get是通过地址栏来传值,
而Post是通过提交表单来传值。
GET方式提交数据,会带来安全问题,比如一个登录页面,
通过GET方式提交数据时,用户名和密码将出现在URL上,
如果页面可以被缓存或者其他人可以访问这台机器,
就可以从历史记录获得该用户的账号和密码.
11、junit测试
专门用于测试,单元测试,
导入junit4.X.jar (基于java5及其以上 注解特性)
@override
@Test:用在方法上,表示该方法被junit测试运行,只能用于无参无返回值的方法
@Ignore:表示该方法被忽略,不被测试
@Before:在每一个测试方法执行前运行
@After:在每一个测试方法执行后运行
@BeforeClass:在所有测试方法执行前执行,必须是static修饰的
@AfterClass:在所有测试方法执行后执行,必须是static修饰的
Errors:测试代码有问题
Failures: 测试结果未通过(指被测试的代码)
测试结果:红色线条表示测试未通过,绿色表示测试通过
Assert
assertSame:比较对象的地址是否相等
assertEquals:比较对象的内容是否相等
Debug
观察variables中变量的值的变化情况
Log4j
日志框架,apache 开源项目
组成:
1、日志优先级:OFF、FATAL>ERROR>WARN>INFO>DEBUG、ALL、自定义
常用的:ERROR、WARN、INFO、DEBUG
输出当前优先级以及比当前优先级高的日志
2、日志输出目的地(Appender):
ConsoleAppender:输出到控制台
FileAppender:输出到文件
DailyRollingFileAppender:每天产生一个新的日志文件
RollingFileAppender:日志文件达到一定大小后,产生新的日志文件
3、日志信息的输出格式
HTMLLayout(HTML表示)
SimpleLayout(日志信息+日志的级别)
PatternLayout(灵活的日志格式)
TTCCLayout(包含日志产生的线程、时间、类别等信息)
日志信息定义:
%p:表示日志的优先级
%l: 日志产生的位置
%m:日志信息
%d:日志产生的时间
%n:换行
src下log4j.properties
12、反射
.java->.class
jvm加载.class Student对象 反射机制
程序运行的时候动态的创建类的对象,并且可以访问对象中属性和方法
作用:程序运行的时候判断任何对象所属的类
访问该对象的属性和方法
J2EE Spring框架
反编译 .class ->.java
核心Class类
每一个java类,都自带了一个与之对应的Class对象(系统自动生成的)
每一个class文件被jvm加载进来的时候,就会保存Class对象,
记录了该类所属包、类名、属性、方法、修饰符,总之,记录与该类相关的信息。
定义一个Student类
***一个Student类 一个Class对象 n个Student对象***
获取某个类的class对象方式
1、class.forName("类的全路径名")
2、类名.class
3、类名 obj = new 类名();
obj.getClass();
无论以哪种方式获取的class对象,都是同一个
基础数据类型的class对象获取方式
包装类.TYPE
如 Integer.TYPE 获取的int的class对象
Integer.class 获取的Integer的class对象
反射中的核心类
Class:该类的class对象
Field:属性
Method:方法
Constructor:构造方法
Array:数组
getDeclaredXXXX():获取本类中属性、方法、构造方法,不区分修饰符
getXXXX():获取公开的属性、方法、构造方法等,包含父类中继承的
注解
注释 (@开头的),对java中包、类、方法、属性的辅助说明
它不会影响程序的执行,java5提供的新特性
@Override @Test @Before......
一、内置注解
@Override :用来表示方法的覆盖
@SuppressWarnings:用来消除警告
@Deprecated:表示类、方法已过时,还是可以继续使用,但是编译器会给出提示
@FunctionalInterface:保证接口中只能有一个方法,java8(7)的新特性
二、自定义注解:
语法:
public @interface 注解名{
public 参数类型 参数名() {default 默认值};
}
参数类型:8种基本数据类型,String,Class及其数组,枚举
三、元注解
也是一种注解,用来辅助说明注解的
共4种
@Target:说明注解的使用范围
ElementType.TYPE: 可用在类、接口、枚举、注解上
FIELD:可用在属性上
METHOD:可用在方法中
CONSTRUCTOR:可用在构造方法
PACKAGE:可用在包上面
PARAMETER:可用在参数上
...
@Retention: 说明注解的声明周期(SOURCE、CLASS、RUNTIME)
SOURCE:注解只保留到源代码中
CLASS:注解只保留到class文件中,jvm加载后,就被丢弃
RUNTIME:注解保留到程序运行时期,可通过反射获取注解信息
@Documented:说明通过javadoc产生API文档会用
@Inherited:子类对父类自定义注解的继承(用在父类的注解上)
@Request("login","login.jsp") 反射
泛型
1、java5新特性,泛型:“参数化类型”
List<E> E即可以是Object、String、Student
使用泛型和不使用泛型的区别
好处:安全简单,它在编译的时候能够检测类型安全
所有的强制转换都是隐式和自动的,不需要人工干预。
集合框架中用的最多
2、泛型接口
public interface 接口名<T>{
}
“T”:不是固定的,可以取任何一个字母,type的首字母
3、泛型类
public class 类名<T,S>{
}
可以指定多个泛型(参数类型): <T,S>
4、泛型方法
修饰符 <T,S> 返回类型 方法名(形式参数列表)
泛型方法不一定要在泛型类中。
上限:Class<? extends A> 只能接受A类型及其子类类型 <=A
下限:Class<? super A> 只能接受A类型及其父类类型 >=A
泛型总结:
1、在集合中建议用泛型,因为会发生转换异常(安全性问题)
2、简单,从集合中取对象处理不需要转换
简单、安全
JDBC
java database conection
JDBC是SUN公司提供的一套连接各种数据库的标准接口
开发人员而言,只需使用相同的标准就完成数据库的连接
一、JDBC驱动通常类型
1、面向数据库的纯JAVA驱动(jar包),目前最流行,主流的
2、ODBC,已经淘汰了,被JDBC取代了,java8不支持。
3、与平台绑定,特定数据库的驱动。
4、基于中间件java驱动
二、JAVA中对于JDBC支持的相关类
java.sql.*包
1、DriverManager:用于管理JDBC驱动的服务类。
获取Connection对象
2、Connection类:连接对象
3、Statement接口:sql语句接口(增删改查语句)
ResulteSet executeQuery(查询语句)
int executeUpdate(新增、插入、删除语句)
返回的结果是影响的行数
boolean execute(增删改查语句)
如果执行的结果是一个ResulteSet,则返回true
如果执行的记过是影响的行数(有影响返回true,无影响返回false)
4、ResultSet类:结果集(查询结果)
三、JDBC编程步骤
1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机)
这通过java.lang.Class类的静态方法forName(String className)实现。
2.提供JDBC连接的URL 连接URL定义了连接数据库时的协议、子协议、数据源标识。
书写形式:协议:子协议:数据源标识
协议:在JDBC中总是以jdbc开始
子协议:是桥连接的驱动程序或是数据库管理系统名称。
数据源标识:标记找到数据库来源的地址与连接端口。
3.创建数据库的连接 要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,
该对象就代表一个数据库的连接。 使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。
4.创建一个Statement 要执行SQL语句,必须获得java.sql.Statement实例,
Statement实例分为以下3种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
5.执行SQL语句 Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate和execute
6.处理结果
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
? ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些
行中数据的访问。
? 使用结果集(ResultSet)对象的访问方法获取数据:
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ; // 此方法比较高效
}
(列是从左到右编号的,并且从列1开始)
7.关闭JDBC对象
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声
明顺序相反:
1、关闭记录集
2、关闭声明
3、关闭连接对象
四、面向对象思想编写JDBC工具类
加载驱动、获取连接对象、关闭资源
五、基于JDBC工具类,以面向对象的分析方法对象EMP进行增删改查
数据库中一行数据-》java中的一个对象
抽象成一个java类
SQL注入风险
六、预编译statement
PreparedStatement 推荐使用,防止sql注入
? 占位符
PreparedStatement好处
1、?是占位符,可以动态编写sql
2、sql是预编译,效率要高与Statement
3、可以防止sql注入,提高安全性
一、批量提交
addBatch():将一组参数添加到PreparedStatement
int[] executeBatch():将一批参数命令提交
二、调用存储过程
CallableStatement接口 继承PreparedStatement
1、创建CallableStatement
CallableStatement cs = con.preparecall(sql)
sql格式:
String sql="{call 过程名(?....?)}";
2、为存储过程中的参数设值
输入参数:cs.setXXX(序号,值)
输出参数:cs.registerOutParameter(序号, Types.类型)
Types.类型是数据库中类型
输入输出参数类型?
3、执行
cs.execute();
4、获取输出参数值
cs.getXXX(序号);
5、关闭资源
一、事务
1、定义:数据库中,指一组逻辑单元,使数据从一种状态变换到另外一种状态。
eg:转账的问题,A账户向B账户转账,就需要将他们(转出、转入)放入同一个事务中
2、事务的四大特征:ACID
原子性:Atomic
一致性:Consistency
隔离性:Isolationi
持久性:Durability
3、事务的提交和回滚
Connection类
提交:commit()
回滚:rollback()
java中的事务提交方式默认是自动提交的。
设置提交方式:setAutoCommit(false);//手动提交
分析:如果让多个sql作为一个事务来处理,首先要取消自动提交,当所有的sql执行完毕后,再commit;当某个sql语句出现异常,则在异常部分调用rollback();
try{
con.setAutoCommit(false);
// 多个sql的执行
con.commit();
}catch(Exception e){
con.rollback();
}
表:account
字段 id number(10) 主键
money number(20,2);
public boolean transfer(long sid,long did,double money){
}
A转账给B的同时,A的账户获得10元利息
事务 A获得利息
4、回滚点
//设置回滚点
SavePoint sp = con.setSavePoint();
//回滚到回滚点
con.rollback(sp);
二、元数据:包括表的结构信息
1、 表名、字段名、字段类型、字段个数
ResultSet
ResultSetMetaData rmd = rs.getMetaData()
2、使用场景:持久层框架中生成java实体类
mysql与oracle使用区别
1、主键自增问题
oracle:序列
mysql:自增列 auto_increasement
2、日期
oracle:当前时间 sysdate 插入指定日期 to_date('2013-01-13','yyyy-mm-dd')
mysql:当前时间 now() 插入指定日期 直接使用日期字符串 即'2013-01-13'
3、翻页技术
后台实现(数据库)
mysql实现 limit
SELECT * FROM emp LIMIT 5,5
-- m m = (pagenum-1)*pagesize
-- n n =pagesize
oracel实现 rownum
-- emp表 表格显示 每页5条 总共四页
-- pagesize=5 pagenum = 1 2 3 4
--查询第1页
select * from(
select rownum rn,e.* from emp e where rownum<=5 -- m = pagenum*pagesize
) where rn>=1 -- n = (pagenum-1)*pagesize+1
-- 查询第2页的数据
select * from(
select rownum rn,e.* from emp e where rownum<=10
) where rn>=6