报名学习开课吧Java商业项目实战就业班

一、枚举、注解与反射

1.枚举

枚举简介:枚举,可以把相关的常量分组到一个枚举类型里,用于定义有限数量的一组同类常量。

枚举定义格式:权限修饰符 enum 枚举名称 { 实例1,实例2,实例3,实例4; }

案例如下:

枚举常见方法:

 实现接口的枚举类:

枚举使用注意事项:

一旦定义了枚举,最好不要妄图修改里面的值,除非修改是必要的。

枚举类默认继承的是java.lang.Enum类而不是Object类

枚举类不能有子类,因为其枚举类默认被final修饰

只能有private构造方法

switch中使用枚举时,直接使用常量名,不用携带类名

不能定义name属性,因为自带name属性

不要为枚举类中的属性提供set方法,不符合枚举最初设计初衷。 

2.注解

注解概述:

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。和注释不同,Java 标注可以通过反射获取标 注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。它也支持自定义 Java 标注。

主要用于:

编译格式检查

反射中解析

生成帮助文档

跟踪代码依赖 

内置注解:

 SuppressWarnings:抑制编译时的警告信息。 *

定义在java.lang.SuppressWarnings

三种使用方式 参数列表: 1. @SuppressWarnings("unchecked") [^ 抑制单类型的警告]

2. @SuppressWarnings("unchecked","rawtypes") [^ 抑制多类型的警告]

3. @SuppressWarnings("all") [^ 抑制所有类型的警告]

参数列表:

元注解:

作用在其他注解的注解

如:@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可 以通过反射访问。

@Documented - 标记这些注解是否包含在用户文档中 javadoc。

@Target - 标记这个注解应该是哪种 Java 成员。

@Inherited - 标记这个注解是自动继承的

①子类会继承父类使用的注解中被@Inherited修饰的注解

②接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有 被@Inherited修饰

③类实现接口时不会继承任何接口中定义的注解

自定义注解:

每 1 个 Annotation 对象,都会有唯一的 RetentionPolicy 属性((注解作用域策略);至于 ElementType 属性(注解的用途类型),则有 1~n 个。

a) 若 Annotation 的类型为 SOURCE,则意味着:Annotation 仅存在于编译器处理期间,编译器 处理完之后,该 Annotation 就没用了。 例如," @Override" 标志就是一个 Annotation。当它修 饰一个方法的时候,就意味着该方法覆盖父类的方法;并且在编译期间会进行语法检查!编译器处 理完后,"@Override" 就没有任何作用了。

b) 若 Annotation 的类型为 CLASS,则意味着:编译器将 Annotation 存储于类对应的 .class 文件 中,它是 Annotation 的默认行为。

c) 若 Annotation 的类型为 RUNTIME,则意味着:编译器将 Annotation 存储于 class 文件中,并 且可由JVM读入。 

 自定义注解定义格式:@interface 自定义注解名{}

定义时的注意点:①定义的注解,自动继承了java.lang,annotation.Annotation接口

②注解中的每一个方法,实际是声明的注解配置参数

方法的名称就是配置参数的名称 :方法的返回值类型,就是配置参数的类型。只能是:基本类型/Class/String/enum

③可以通过default来声明参数的默认值

④如果只有一个参数成员,一般参数名为value

⑤注解元素必须要有值,我们定义注解元素时,经常使用空字符串、0作为默认值。

案例:

(01) @interface 使用 @interface 定义注解时,意味着它实现了 java.lang.annotation.Annotation 接口,即该注解就是 一个Annotation。

定义 Annotation 时,@interface 是必须的。

注意:它和我们通常的 implemented 实现接口的方法不同。Annotation 接口的实现细节都由编译器完 成。通过 @interface 定义注解后,该注解不能继承其他的注解或接口。

(02) @Documented 类和方法的 Annotation 在缺省情况下是不出现在 javadoc 中的。如果使用 @Documented 修饰该 Annotation,则表示它可以出现在 javadoc 中。 定义 Annotation 时,@Documented 可有可无;若没有定义,则 Annotation 不会出现在 javadoc 中。

(03) @Target(ElementType.TYPE) 前面我们说过,ElementType 是 Annotation 的类型属性。而 @Target 的作用,就是来指定 Annotation 的类型属性。 @Target(ElementType.TYPE) 的意思就是指定该 Annotation 的类型是 ElementType.TYPE。这就意味着,MyAnnotation1 是来修饰"类、接口(包括注释类型)或枚举声明"的注解。 定义 Annotation 时,@Target 可有可无。若有 @Target,则该 Annotation 只能用于它所指定的地 方;若没有 @Target,则该 Annotation 可以用于任何地方。

(04) @Retention(RetentionPolicy.RUNTIME) 前面我们说过,RetentionPolicy 是 Annotation 的策略属性,而 @Retention 的作用,就是指定 Annotation 的策略属性@Retention(RetentionPolicy.RUNTIME) 的意思就是指定该 Annotation 的策略是 RetentionPolicy.RUNTIME。这就意味着,编译器会将该 Annotation 信息保留在 .class 文件中,并且 能被虚拟机读取。 定义 Annotation 时,@Retention 可有可无。若没有 @Retention,则默认是 RetentionPolicy.CLASS。 

3.反射

反射概述:

JAVA反射机制是在运行状态中,获取任意一个类的结构 , 创建对象 , 得到方法,执行方法 , 属性 等。这种在运行状态动态获取信息以及动态调用对象方法的功能被称为java语言的反射机制。

类加载器:

Java类加载器(Java Classloader)是Java运行时环境(Java Runtime Environment)的一部分, 负责动态加载Java类到Java虚拟机的内存空间中。 java默认有三种类加载器:BootstrapClassLoader、ExtensionClassLoader、App ClassLoader。

BootstrapClassLoader(引导启动类加载器): 嵌在JVM内核中的加载器,该加载器是用C++语言写的,主要负载加载JAVA_HOME/lib下的类库,引 导启动类加载器无法被应用程序直接使用。 ExtensionClassLoader(扩展类加载器): ExtensionClassLoader是用JAVA编写,且它的父类加载器是Bootstrap。 是由sun.misc.Launcher$ExtClassLoader实现的,主要加载JAVA_HOME/lib/ext目录中的类 库。 它的父加载器是BootstrapClassLoader

App ClassLoader(应用类加载器): App ClassLoader是应用程序类加载器,负责加载应用程序classpath目录下的所有jar和class文 件。它的父加载器为Ext ClassLoader

Class与加载方式:

在Java中,每一个字节码文件,被加在到内存后,都存在一个对应的Class类型的对象

得到Class的几种方式:

 反射中的构造方法:

①通过class对象 获取一个类的构造方法 

 ②Constructor 创建对象

 反射中的方法:

①通过class对象 获取一个类的方法

②Method 执行方法

 反射中的属性:

①通过class对象 获取一个类的属性

②Field 属性的对象类型

 4.反射与注解

获取类上的所有注解:

 获取注解所传参数:

 获取类中属性上的注解所传数(类中其他对象方法也类似):

 5.内省

简介:

基于反射 , java所提供的一套应用到JavaBean的API

一个定义在包中的类 , 拥有无参构造器 所有属性私有, 所有属性提供get/set方法,实现了序列化接口 。这种类, 我们称其为 bean类 . Java提供了一套java.beans包的api , 对于反射的操作, 进行了封装 。

①获取Bean类信息

 ②获取bean类的 get/set方法 数组

 ③逐个获取某个属性的get和set方法

注意:当属性类型为boolean类型时,所获得的get方法的方法名为

二、数据库基础 

1.数据库简介:

数据库(DataBase,DB):指长期保存在计算机的存储设备上,按照一定规则组织起来,可以被各种 用户或应用共享的数据集合。

2.数据库三大范式:

第一范式:无重复的列。当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一 范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的 关系模式中实现不了。

第二范式:属性完全依赖于主键 [ 消除部分子函数依赖 ]。如果关系模式R满足第一范式,并且R得所有 非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。第二范式(2NF)是 在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第 二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上 一个列,以存储各个实例的唯一标识。这个唯一属性列被称为主关键字或主键、主码。

第三范式:属性不依赖于其它非主属性 [ 消除传递依赖 ]。设R是一个满足第一范式条件的关系模式,X 是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF. 满足 第三范式(3NF)必须先满足第二范式(2NF)。第三范式(3NF)要求一个数据库表中不包含已在其 它表中已包含的非主关键字信息。

3.SQL语音介绍

Create, Read, Update, and Delete 通常称为CRUD操作。

SQL语句的分类:

DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等。

DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)增删改。 - DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别。 -

DQL(Data Query Language):数据查询语言,用来查询记录(数据)查询。

4.DDL操作数据库

CREATE DATABASE语句用于创建新的数据库:

编码方式:gb2312,utf-8,gbk,iso-8859-1,如下:

show databases语句 用于查看当前数据库服务器中的所有数据库 

alter database 数据库名 character set 编码方式 用于修改数据库

drop database 数据库名 用于删除数据库

Select database() 用于查看当前使用的数据库

:use 数据库名 用于切换数据库

5.DDL操作表

创建表:

CREATE TABLE 表名(

        列名1 数据类型 [约束],

        列名2 数据类型 [约束],

        列名n 数据类型 [约束] );

示例:

常用数据类型:

drop table 表名 用于删除表

show tables 用于展示当前数据库中的所有表 

desc 表名 用于查看表的字段信息

alter table 表名 add 新列名 新的数据类型 用于增加列

alter table 表名 change 旧列名 新列名 新的数据类型 用于修改列

alter table 表名 drop 列名 用于删除列

alter table 旧表名 rename 新表名 用于修改表名

alter table 表名 character set 编码方式 用于修改表的字符集

show create table 表名 用于查看表的创建细节

6.DML操作

增加操作:

insert into 表名(列名) values(数据值);

示例:insert into student(stuname,stuage,stusex,birthday) values('张三1',18,'a','2000- 1-1');

当给所有列添加数据的时候可以将列名省略,此时列值的顺序按照数据表中列的顺序执行,如:insert into student values('李四',12,'1111',189.98,'2000-1-1','男','2007-1-1');

同时添加多行:

sql中的运算符:

 更新操作:

UPDATE 表名 SET 列名1=列值1,列名2=列值2 ... WHERE 列名=值

 删除操作:

DELETE from 表名 【WHERE 列名=值】

注意:- DELETE 删除表中的数据,表结构还在;删除后的数据可以找回 - TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。 - 删除的数据不能找回。执行速度比DELETE快。

7.DCL操作

创建用户:

 用户授权:

用户权限查询:

show grants for 用户名@IP;

撤销用户权限:

revoke 权限1,权限2,........,权限n on 数据库名.* from 用户名@IP; 

删除用户:

drop user test123@localhost;

8.DQL

数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。 查询返回的结果集是一张虚拟表。

语法: SELECT 列名 FROM 表名 【WHERE --> BROUP BY-->HAVING--> ORDER BY】

9.查询

简单查询:

条件查询:

 

 模糊查询:

语法: 列名 like '表达式'   注意:表达式必须是字符串

 _(下划线): 任意一个字符

%:任意0~n个字符,'张%'

字段控制查询

10.排序

语法: order by 列名 asc/desc

//asc 升序 desc 降序 默认不写的话是升序

多列排序:当前面的列的值相同的时候,才会按照后面的列值进行排序

示例:

SELECT * FROM emp

ORDER BY sal DESC,empno ASC;

11.聚合函数

12.分组查询:

当需要分组查询时需要使用GROUP BY子句,例如查询每个部门的工资和,这说明要使用部分来分组。  

注意:如果查询语句中有分组操作,则select后面能添加的只能是聚合函数和被分组的列名 

示例:

 HAVING子句:

 12.LIMIT

LIMIT用来限定查询结果的起始行,以及总行数。

示例:

 分页查询:

三、数据库高级 

1.完整性介绍

用来保证存放到数据库中的数据是有效的,即数据的有效性和准确性

确保数据的完整性 = 在创建表时给表中添加约束

完整性的分类:

①实体完整性(行完整性)②域完整性(列完整性)③引用完整性(关联表完整性)

示例:

 

实体完整性:

实体:即表中的一行(一条记录)代表一个实体(entity)

实体完整性的作用:标识每一行数据不重复。 

约束类型:主键约束(primary key)

唯一约束(unique)

自动增长列(auto_increment)

 域完整性:

域完整性的作用:限制此单元格的数据正确,不对照此列的其它单元格比较

域代表当前单元格

域完整性约束类型:①数据类型②非空约束(not null)③默认值约束(default)④check约束(mysql不支持)⑥check(sex='男' or sex='女')

 

 

 

引用完整性:

外键约束:FOREIGN KEY

示例:

2.表的关系

一对多/多对一关系:一对多建表原则:在多的一方创建一个字段,字段作为外键指向一的一方的主键. 

多对多关系:多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一 方的主键。

一对一关系:两种建表原则: ①唯一外键对应:假设一对一是一个一对多的关系,在多的一方创建一个外键指向一的一方的主键,将外 键设置为unique. ②主键对应:让一对一的双方的主键进行建立关系.

3.多表查询

多表查询分为以下几种:

合并结果集:

作用:合并结果集就是把两个select语句的查询结果合并到一起!

合并结果集有两种方式: ①UNION:去除重复记录,例如:SELECT* FROM t1 UNION SELECT * FROM t2;

②UNION ALL:不去除重复记录,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2。 

 注意:被合并的两个结果:列数、列类型必须相同

连接查询:

连接查询就是求出多个表的乘积,例如t1连接t2,那么查询出的结果就是t1*t2。

示例:

连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1), (a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。

多表查询产生这样的结果并不是我们想要的,那么怎么去除重复的,不想要的记录呢,当然是通过 条件过滤。通常要查询的多个表之间都存在关联关系,那么就通过关联关系去除笛卡尔积。 

内连接:

语法:

等价于:

 

注:①表1和表2的顺序可以互换

②找两张表的等值关系时,找表示相同含义的列作为等值关系。

③点操作符表示“的”,格式:表名.列名

④可以使用as,给表名起别名,注意定义别名之后,统一使用别名  

示例:

三表联查:

 

 SQL标准的内连接为:

外连接:

包括左外连接和右外连接,外连接的特点:查询出的结果存在不满足条件的可能。 

左外联:select 列名 from 主表 left join 次表 on 主表.列名=次表.列名

右外联:select 列名 from 次表 right join 主表 on 主表.列名=次表.列名

注意:①主表数据全部显示,次表数据匹配显示,能匹配到的显示数据,匹配不成功的显示null -- ②主表和次表不能随意调换位置

 

 连接查询心得:

连接不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要 整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多 数情况下都是使用主外键关系去除。

两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,所以在大家不 是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两 张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。

自然连接:

自然连接是一种特殊的等值连接,他要求两个关系表中进行连 接的必须是相同的属性列(名字相同),无须添加连接条件,并且在结果中消除重复的属性列。

示例:

select * from emp e natural join dept d;

子查询:

一个select语句中包含另一个完整的select语句。 子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么 就是子查询语句了。

示例:

 

4.扩展

表表更新:

多表删除:

 

日期运算函数 

now() 获得当前系统时间

year(日期值) 获得日期值中的年份

date_add(日期,interval 计算值 计算的字段);

注:计算值大于0表示往后推日期,小于0表示往前推日期

示例: date_add(now(),interval -40 year);//40年前的日期

 5.数据库优化

①对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引

②应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫 描。

如: select id from t where num is null

最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.

备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。

③应尽量避免在 where 子句中使用 != 或 <> 操作符,否则引擎将放弃使用索引而进行全表扫描。 ④应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致 引擎放弃使用索引而进行全表扫描。

如:select id from t where num=10 or Name = 'admin'可以改成:

 ⑤.in 和 not in 也要慎用,否则会导致全表扫描。

如:select id from t where num in(1,2,3) 对于连续的数值。

能用 between 就不要用 in 了: select id from t where num between 1 and 3

很多时候用 exists 代替 in 是一个好的选择

四、数据库进阶

1.事务

事务(Transaction)是由一系列对系统中数据进⾏访问与更新的操作所组成的⼀个程序执行逻辑单元。

 

事务的语法:

①start transaction; begin;

②commit; 使得当前的修改确认

③rollback; 使得当前的修改被放弃

事务的ACID特性

①原⼦性(Atomicity) 事务的原⼦性是指事务必须是⼀个原子的操作序列单元。事务中包含的各项操作在⼀次执⾏过程中,只 允许出现两种状态之一。 (1)全部执行成功 (2)全部执行失败 事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执⾏过程中出错, 会回滚到事务开始前的状态,所有的操作就像没有发⽣一样。也就是说事务是⼀个不可分割的整体,就 像化学中学过的原子,是物质构成的基本单位。

②⼀致性(Consistency) 事务的一致性是指事务的执⾏不能破坏数据库数据的完整性和一致性,一个事务在执⾏之前和执行之 后,数据库都必须处以⼀致性状态。 比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,⽽B账户没有加钱。

③隔离性(Isolation) 事务的隔离性是指在并发环境中,并发的事务是互相隔离的。也就是说,不同的事务并发操作相同的数 据时,每个事务都有各自完整的数据空间。 ⼀个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的。 隔离性分4个级别,下面会介绍。

④持久性(Duration) 事务的持久性是指事务⼀旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服 务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态

事务的并发问题:

①脏读:读取到了没有提交的数据, 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。

②不可重复读:同⼀条命令返回不同的结果集(更新).事务 A 多次读取同一数据,事务 B 在事务A 多次读取的过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致。

③幻读:重复查询的过程中,数据 就发⽣了量的变化(insert, delete)。

事务隔离级别:

4种事务隔离级别从上往下,级别越高,并发性越差,安全性就越来越高。 ⼀般数据默认级别是读以提交或可重复读 

查看当前会话中事务的隔离级别:

设置当前会话中的事务隔离级别:

mysql> set session transaction isolation level read uncommitted; Query OK, 0 rows affected (0.00 sec) 

读未提交:

如果一个事务正在处理理某一数 据,并对其进⾏了更新,但同时尚未完成事务,因此还没有提交事务;而以此同时,允许另一个事务也 能够访问该数据。

脏读示例:

读已提交:

读已提交是不同的事务执行的时候只能获取到已经提交的数据。 这样就不会出现上面的脏读的情况了。 但是在同一个事务中执行同一个读取,结果不一致 。

不可重复读示例:

可可重复读:

可重复读就是保证在事务处理理过程中,多次读取同一个数据时,该数据的值和事务开始时刻是一致的。 因此该事务级别限制了不可重复读和脏读,但是有可能出现幻读的数据。 幻读 幻读就是指同样的事务操作,在前后两个时间段内执行对同一个数据项的读取,可能出现不一致的结果。

诡异的更新事件:

 顺序读:

顺序读是最严格的事务隔离级别。它要求所有的事务排队顺序执⾏行行,即事务只能一个接一个地处理,不能并发。

 2.不同的隔离级别的锁的情况

①读未提交(RU): 有行级的锁,没有间隙锁。它与RC的区别是能够查询到未提交的数据。

②读已提交(RC):有行级的锁,没有间隙锁,读不到没有提交的数据。

③可重复读(RR):有行级的锁,也有间隙锁,每次读取的数据都是一样的,并且没有幻读的情况。

④序列化(S):有行级锁,也有间隙锁,读表的时候,就已经上锁了

3.隐式提交

DQL:查询语句句 DML:写操作(添加,删除,修改) DDL:定义语句句(建库,建表,修改表,索引操作,存储过程,视图) DCL: 控制语⾔言(给⽤用户授权,或删除授权) DDL(Data Define Language):都是隐式提交。 隐式提交:执⾏行行这 种语句句相当于执⾏行行commit; DDL

五、JDBC

1.JDBC简介

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多 种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序

JDBC可以在各种平台上使用Java,如Windows,Mac OS和各种版本的UNIX。

JDBC库包括通常与数据库使用相关的下面提到的每个任务的API。

①连接数据库。

②创建SQL或MySQL语句。

③在数据库中执行SQL或MySQL查询。 

④查看和修改生成的记录。

2.JDBC体系结构

JDBC API支持用于数据库访问的两层和三层处理模型,但通常,JDBC体系结构由两层组成: - ①JDBC API:这提供了应用程序到JDBC管理器连接。

②JDBC驱动程序API:这支持JDBC管理器到驱动程序连接。

JDBC API使用驱动程序管理器和特定于数据库的驱动程序来提供与异构数据库的透明连接。

 

 3.JDBC核心组件

①DriverManager: 此类管理数据库驱动程序列表。使用通信子协议将来自java应用程序的连接请求 与适当的数据库驱动程序匹配。

②Driver:此接口处理与数据库服务器的通信,我们很少会直接与Driver对象进行交互。而是使用 DriverManager对象来管理这种类型的对象。

③Connection:该界面具有用于联系数据库的所有方法。连接对象表示通信上下文,即,与数据库 的所有通信仅通过连接对象。

④Statement:使用从此接口创建的对象将SQL语句提交到数据库。除了执行存储过程之外,一些派 生接口还接受参数。

⑤ResultSet:在使用Statement对象执行SQL查询后,这些对象保存从数据库检索的数据。它作为一 个迭代器,允许我们移动其数据。

⑥SQLException:此类处理数据库应用程序中发生的任何错误

4.JDBC使用步骤

构建JDBC应用程序涉及以下六个步骤:

① 导入包:需要包含包含数据库编程所需的JDBC类的包。大多数情况下,使用import java.sql.*就足够 了。

②注册JDBC驱动程序:要求您初始化驱动程序,以便您可以打开与数据库的通信通道。

③ 打开连接:需要使用DriverManager.getConnection()方法创建一个Connection对象,该对象表 示与数据库的物理连接。

④执行查询:需要使用类型为Statement的对象来构建和提交SQL语句到数据库。

⑤ 从结果集中提取数据:需要使用相应的ResultSet.getXXX()方法从结果集中检索数据。

⑥释放资源:需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集。

(具体实现案例在11.基于德鲁伊的工具类的实现案例展示)

5.数据库事务

一组要么同时执行成功,要么同时执行失败的SQL语句。是数据库操作的一个执行单元。

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执 行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更 新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误 恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、 隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务 的处理。

 JDBC中事务应用:

如果JDBC连接处于自动提交模式,默认情况下,则每个SQL语句在完成后都会提交到数据库。 事务使您能够控制是否和何时更改应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单 元,如果任何语句失败,则整个事务将失败。 要启用手动事务支持,而不是JDBC驱动程序默认使用的自动提交模式,请使用Connection对象的 setAutoCommit()方法。如果将boolean false传递给setAutoCommit(),则关闭自动提交。我 们可以传递一个布尔值true来重新打开它。

示例:

6.Savepoints

新的JDBC 3.0 Savepoint接口为您提供了额外的事务控制。

设置保存点时,可以在事务中定义逻辑回滚点。如果通过保存点发生错误,则可以使用回滚方法来撤消 所有更改或仅保存在保存点之后所做的更改。 

Connection对象有两种新的方法来帮助您管理保存点

①setSavepoint(String savepointName):定义新的保存点。它还返回一个Savepoint对象。 - ②releaseSavepoint(Savepoint savepointName):删除保存点。请注意,它需要一个Savepoint 对象作为参数。此对象通常是由setSavepoint()方法生成的保存点。

 

 7.JDBC批处理

批量处理允许您将相关的SQL语句分组到批处理中,并通过对数据库的一次调用提交它们。 当您一次向数据库发送多个SQL语句时,可以减少连接数据库的开销,从而提高性能。

Statement批处理:

①使用createStatement()方法创建Statement对象。

②使用setAutoCommit()将auto-commit设置为false 。

③ 使用addBatch()方法在创建的语句对象上添加您喜欢的SQL语句到批处理中。

④在创建的语句对象上使用executeBatch()方法执行所有SQL语句。

⑤最后,使用commit()方法提交所有更改。

示例:

 PreparedStatement批处理:

①使用占位符创建SQL语句。

②使用prepareStatement() 方法创建PrepareStatement对象。

③使用setAutoCommit()将auto-commit设置为false 。

④ 使用addBatch()方法在创建的语句对象上添加您喜欢的SQL语句到批处理中。

⑤在创建的语句对象上使用executeBatch()方法执行所有SQL语句。

⑥ 最后,使用commit()方法提交所有更改。

8.反射处理结果集

接口:

//查询所有的学生信息

public List<Student> findallstudent(Class cla)  

实现类:

 

9.properties文件

properties文件保存数据库信息-特点:key-value存储方式

driver=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/yhp

user=root

password=123456

工具类中读取属性文件

方式1

方式2

 

说明: 使用ResourceBundle访问本地资源

在设计时,我们往往需要访问一些适合本地修改的配置信息,如果作为静态变量,那么每次修改都 需要重新编译一个class,.config保存此类信息并不适合,这时我们需要ResourceBundle。

通过ResourceBundle,我们需要访问位于/WEB-INF/classes目录下的一个后缀名为properties的文本 类型文件,从里面读取我们需要的值。 

10.连接池

数据库连接池原理:

连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数 据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户 也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连 接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数 以及每个连接的最大使用次数、最大空闲时间等等,也可以通过其自身的管理机制来监视数据库连接的 数量、使用情况等。

自定义连接池:

具体实现代码展示:

 

 

java规范实现连接池:

Java为连接池实现提供了一个规范(接口),规范的写法,我们需要实现DataSource接口! 但是实现DataSource接口有一个弊端,没有提供回收链接方法!这里我们将使用装饰者模式

装饰Connection!具体实现代码如下: 

 

基于规范实现的连接池

 

 

最小连接数: 是数据库一直保持的数据库连接数,所以如果应用程序对数据库连接的使用量不大,将有大量的数据库 资源被浪费。

初始化连接数: 连接池启动时创建的初始化数据库连接数量。

最大连接数: 是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求被加入到等待队 列中。

最大等待时间: 当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置参数为0或者负 数使得无限等待(根据不同连接池配置)。 

 

注1:在DBCP连接池的配置中,还有一个maxIdle的属性,表示最大空闲连接数,超过的空闲连接将被释 放,默认值为8。对应的该属性在Druid连接池已不再使用,配置了也没有效果,c3p0连接池则没有对 应的属性。 

注2:数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连 接。如果当前池中正在使用的连接数等于maxActive,则会等待一段时间,等待其他操作释放掉某一个 连接,如果这个等待时间超过了maxWait,则会报错;如果当前正在使用的连接数没有达到 maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。在 连接使用完毕后,不是将其物理连接关闭,而是将其放入池中等待其他操作复用。 

DBCP连接池:

导入相应jar包 mysql-jdbc.jar commons-dbcp.jar commons-pool.jar

C3P0连接池:

导入jar包 c3p0-0.9.1.2.jar mysql-connector-java-5.0.8.jar

.添加配置文件

 

 

 Druid(德鲁伊)连接池:

 

导入jar包

编写工具类:

注:在Druid连接池的配置中,driverClassName可配可不配,如果不配置会根据url自动识别dbType(数 据库类型),然后选择相应的driverClassName。 

11.基于德鲁伊的工具类的实现案例展示:

package com.java.utils;

import com.alibaba.druid.pool.DruidDataSource;

import java.sql.*;
import java.util.List;
import java.util.ResourceBundle;

public class DBUtils {
    //1.定义变量
    private Connection connection;
    private PreparedStatement pps;
    private ResultSet resultSet;
    private int count;

    private static String userName;
    private static String userPass;
    private static String url;
    private static String driverName;
    //德鲁伊
    private static DruidDataSource dataSource = new DruidDataSource();

    //2.加载驱动
    static {
        ResourceBundle bundle = ResourceBundle.getBundle("db");
        driverName = bundle.getString("driverclass");
        url = bundle.getString("url");
        userName = bundle.getString("user");
        userPass = bundle.getString("password");
        dataSource.setUsername(userName);
        dataSource.setPassword(userPass);
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverName);
    }

    //3.获得连接
    protected Connection getConnection() {
        try {
            connection = dataSource.getConnection();
            //connection = DriverManager.getConnection(url,userName,userPass);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return connection;
    }

    //4.得到预状态通道
    protected PreparedStatement getPps(String sql) {
        try {
            pps = getConnection().prepareStatement(sql);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return pps;
    }

    //5.绑定参数
    protected void param(List list) {
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                try {
                    pps.setObject(i + 1, list.get(i));
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }

    //6.执行操作
    protected int update(String sql, List list) {
        getPps(sql);
        param(list);
        try {
            count = pps.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return count;
    }

    protected ResultSet query(String sql, List list) {
        getPps(sql);
        param(list);
        try {
            resultSet = pps.executeQuery();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return resultSet;
    }

    //7.关闭资源
    protected void close() {
        try {
            if (connection != null) {
                connection.close();
            }
            if (pps != null) {
                pps.close();
            }
            if (resultSet != null) {
                resultSet.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值