-
JavaWeb
- Oracle:数据库,具有自身存储空间
- JDBC:Java操作数据库技术
- html / css:静态网页
- Servlet:应用服务器技术tomcat的动态网页
- JSP:动态网页技术
- struts2 框架,配置文件
- mybaties 框架,配置文件
- js ( javascript ):前端技术
- jquery:前端框架
- maven:项目管理技术
-
引言
- 存储数据需求
- Java程序中,借助jvm内存的变量、对象进行存储
- 存储数据的方式:变量(单个数据)、对象、集合数组
- 位置:存储在jvm内存中(栈空间:局部变量;对象:堆变量)
- 缺点:jvm运行时空间存在,数据存在;但是jvm关闭则数据丢失,为临时存储
- 数据存储在文件中
- 利用IO流读文件中的数据、往文件中写数据
- 优点:数据持久化,为永久性存储
- 缺点
- 数据存储不安全
- 文件的数据类型单一,只有一种数据类型为字符串类型
- 不支持多用户同时操作
- 文件存储的数据量较小
Oracle
基本概念
- 数据库:DataBase,简称DB;是一种存储、管理数据的一种软件
- 客户端:Clinet,发送指令来使用、访问、操作数据库
- 服务端:Server,接收指令、执行指令,存储数据
- 常见数据库
- 关系型数据库
- Oracle:Oracle公司
- MySQL:起初为MySQL公司,被Sun公司收购,Sun公司被Oracle收购,免费、开源
- DB2:IBM公司
- SQLServer:微软公司
- 非关系型数据库
- Memcache、MongoDB、Redis
- 关系型数据库
- 数据库中常见概念
- 表:Table,存储数据
- 行:Row,代表一条数据
- 列/字段:Column,指示当前对应列数据的含义,也被称为字段
- 主键:Primary Key,简称PK,唯一;标识数据库中的一条数据
- 外键:Foreign Key,简称FK,用于体现两张表之间的关系
Oracle数据库安装
- 数据库服务端:
- 安装路径必须全英文,计算机根目录名字不能是中文
- 关注两个服务:OracleServiceXE 数据库核心服务和OracleXETNSListener 接收外部访问服务,监听服务
- 数据库客户端:
- sqlplus(自带)
- 开始 —> Oracle文件夹 —> sqlplus
- DOS —> 输入sqlplus指令,输入用户名和密码
- isqlplus
- 通过 http://localhost:8080/apex,解锁hr用户
- Sql-develeper:第三方提供
- Database:数据库,连接XE(便携测试版);ORCL企业级
- 连接为:Nomal普通的;sys/system管理员用户
- sqlplus(自带)
SQL —> Structur Query Language 结构化的查询语言
- 操作数据库中某一个用户下的某个表中的数据;常用操作:增删改查
Oracle基本查询语法
- 确定查询数据的表来源:from 表名
- 确定查询的字段(列名):select 列名
- 查询表中部分字段内容
- 查询员工表中所有员工的工号、名、工资
- select 列名1,列名2,… from employees 最后一个字段无需逗号
- 查询员工表中所有的信息
- select * from employees *代表表中所有字段, *查询效率较低
- 查询员工表中所有员工的工号、名、工资
- 对于查询的列起别名
- select 列名 as 别名,列名2 as 别名2,列名 from 表名。
- as可以省略,别名可以有中文,也可以是英文;英文时默认为大写,想区分则需要用双引号引起
- 对查询结果进行拼接:||相当于java中的 +
- select 列名1,列名2==||==列名3 as 别名 from 表名
- oracle中字符串字面值常量必须使用单引号引起来( ’ ’ )
- 对字段结果进行计算
- 数值类型可以进行+ - * /,字符类型不可以使用 +,日期之间进行减法运算,以天为单位
- 字段进行除法运算时,分母不能为零
- 对查询的结果去重
- 写在select后所有字段前,多个字段都重复,才去掉
- select distinct 列名1,列名2 from 表名;
排序
- 对查询结果按照指定对字段进行排序(asc升序、desc降序),默认为升序
- select … from table_name order by column asc / desc
条件查询 —> where
- 对查询的每个数据都进行条件判断,对符合条件的数据存放到查询结果中
- select … from teble_name where 过滤条件
- 条件查询分类
- 等值条件判断:=
- 字符串字面值必须使用 ’ ’ 引起来,可以参与等值运算,且区分大小写
- 不等值条件判断:!= > >= < <=
- 多条件查询:and、or / 且、或
- 区间查询
- select … from table_name where column between 起始值 and 终止值
- 小值在前,大值在后,并且结果含有边界值
- not between代表不在此区间,没有边界值
- 枚举查询:in(值1,值2,…)
- select … from table_name where column in(value1,value2,…)
- not in 不在列举的数据
- 对null值处理:is
- select … from table_name where column is null
- 过滤指定字段为null的对应数据的相关信息
- 反之为 is not null
- 模糊查询:like
- select … from table_name where column like ’ 格式表达式 ’
- 格式表达式可以是字符串常量、通配符 ’ % / _ ’
- 通配符 ’ _ ’ 表示任意一个字符;’ % '表示0~n个任意字符
- 等值条件判断:=
特殊的关键字
- 为了维护查询语句的完整性,Oracle提供了一个特殊的表dual哑表,只有一行一列,没有实际意义
- sysdate:获取当前系统时间,Oracle默认显示 日-月-年 时-分-秒,不同客户端显示不同
- select sysdate from dual
- systimestamp:时间戳
- select systimestamp from dual
- sysdate:获取当前系统时间,Oracle默认显示 日-月-年 时-分-秒,不同客户端显示不同
函数
-
执行特定功能的指令
-
单行函数:作用表中的每一行数据,有一条数据函数执行一次,产生一个对应的结果
- 如果参与运算的字段为null,则结果为null
- length(str):获取字符串str的长度
- nvl(字段,value值)
- 若字段名为null,则用第二个值替代null
- to_char(日期,‘格式字符串’)
- 日期格式:yyyy 年 mm 月 dd 日 day 星期
- hh 时 hh24 时 mi 分 ss 秒
- 将给定日期按照指定的字符串格式进行展示,并且进行比较等计算
- to_date(‘日期字符串’,‘格式字符串’)
- 日期格式的数据可以参加加法运算,以天为单位
-
组函数:作用在提前分好的组上,只要有一个组,则执行一次,产生一个结果
- 组函数不记null数据
- sum(column):对指定该列的值求和
- avg(column):对指定该列的值求平均
- max(column):对指定列获取最大值
- min(column):对指定列获取最小值
- count(column):对查询结果中的非空值进行统计
- count *:统计查询结果数据的行数
-
分组group by
- 确定分组依据:group by department_id
- 根据需求选择对应组函数,每一个小组都会产生一个结果
- 只有在group by 后面出现的column才能出现在select 后面
- 如果在group by 后面没有出现的字段,可以使用在组函数中应用在select 后面
- 如果group by 后面使用某一个函数,则必须在select、order by后面使用相同函数
- where 中不能使用组函数
- select … from table_name where 条件 group by column
-
having
- select … from table_name where 过滤条件(分组前数据) group by 分组条件 having 过滤条件(分组后数据) order by column asc / desc
- 对分组之后对数据进行过滤
-
执行顺序
-
select … from table_name where 查询 order by column asc / desc
- from:确定数据来源的表
- where:根据过滤条件筛选数据
- group by:根据分组依据,将符合条件的数据进行过滤
- having:对分组之后的结果进行过滤
- select:展示要查询的字段信息,从重命名生效角度,select在order by前
- order by:根据指定字段及排序规则进行数据排序
where | having |
---|---|
对分组之前的数据进行过滤 | 对分组之后的数据进行过滤 |
不可以使用组函数 | 可以使用组函数 |
效率相对较高 | 效率相对较低 |
伪列 —> Oracle独有
- 即虚列,在数据表中不存在的列,只有在查询时才显示出来
- rowid
- 当前某条数据在硬盘上的物理地址计算而得出的结果,每条数据都有唯一的rowid
- 通常应用在Oracle内部,如索引;应用层通常使用主键来设置唯一标识
- rownum
- 对满足查询条件的结果进行编号,编号从1~尾
- from employees时会把employees放入到数据库的缓冲区中,此时有rownum,但是仅预排列,还未生效;满足where 条件时,rownum会对剩下的数据进行再次自动编号,从1~N,此时生效;没有where则代表所有数据都有效,直接生效,作用于order by前,所以乱序
- 只能参与 < <= =1 >=1 <=1 不能参与>n >=n的运算n>=2
- select table_name . * :表示仅table_name中的所有字段,通常仅在*后有伪列、其他函数表达式时使用;为了简化sql,可以使用别名的方式 select other_name from table_name other_name没有as
子查询
- 一个查询语句执行过程中,用到另一个查询语句的执行结果;即一个select语句嵌套另一个select;定义在外面的select称为主查询,定义在里面的select被称为子查询
- 非相关子查询:子查询可以单独使用
- 子查询结果为单个值,只有一行一列
- 子查询结果为多个值:N行一列,将结果看作一个数据集,直接参与 in 运算
- 子查询到结果为多行多列:N行N列,虚表,直接作为主查询的数据来源
- 分页:
- 如果有排序需求,第一步先根据需求排序,得到的有序的虚表tb1
- 在tb1中获取查询符合条件的前n条数据并且对rownum起别名rn,并把此虚表命名为tb2
- 在tb2中查询rn>=m的数据结果
- 分页:
表连接
-
将两张表或多张表连接成一个表
-
如果查询的内容来自于两张表或多张表时,需要使用表连接
-
表连接时需要找到两张表或多张表连接的条件
-
表连接后产生的表列数是两张表列数之和,行取决于表连接的类型
-
操作多张表时有重名的字段,需要 表名.字段名 或者 表别名.字段名 区分
-
分类
- 内连接
- select … from table_name1 [inner] join table_name2 … on 连接条件
- 必须有连接条件
- 查询结果是多张表中基于连接条件都符合连接条件的数据
- 左表和右表没有顺序要求
- 外连接
- 左外连接
- select … from table_name1 left [outer] join table_name2 … on 连接条件
- 最终数据为符合连接条件的数据 + 左表没有匹配成功的数据(对应的右表字段以null填充)
- 左表和右表有顺序要求,以左表为主,左表中有而右表中不存在的字段用null填充
- 右外连接
- select … from table_name1 right [outer] join table_name2 … on 连接条件
- 最终数据为符合连接条件的数据 + 右表没有匹配成功的数据(对应的左表字段以null填充)
- 左表和右表有顺序要求,以右表为主,右表中有而左表中不存在的字段用null填充
- 全外连接
- select … from table_name1 full join table_name2 … on 连接条件
- 最终数据为符合连接条件的数据 + 左表中没匹配上的数据 + 右表中没匹配上的数据
- 左表和右表没有顺序要求,一张表中有而另一张表中不存在的字段用null填充
- 左外连接
- 多表连接(可用内连接或外连接)
- select … from table_name1 join table_name2 on 连接条件 join table_name3 … on 连接条件
- 自连接
- 特殊的表连接,参与表连接的两张表或多张表是同一张表,通常使用自连接
- 字段名不同,但有相同的含义作为连接条件
- 交叉连接(又称笛卡尔积)
- cross join
- select … from 表名1 cross join 表名2 where … group by … having … order by
- 查询结果为表于表做无条件连接
- 内连接
-
获取所有表 select * from tabs
SQL(Structured Query Language 结构化查询语言)
-
对DB中的数据进行CRUD
-
DQL(Data Query Language):数据查询语言,如select
-
DML(Data Manipulate Language):数据操作语言,对表中数据的操作
- 如insert、delete、update / 增、删、改
-
DDL(Data Definition Language):数据定义语言,对表结构的操作;
- 如create、drop、alter,建模工具自动生成对应的表
-
DCL(Data Controller Language):数据控制语言
- 如grand、revoke,和数据库管理员(DBA)相关
-
TCL(Transaction Controller Language):事务控制语言
- 如commit、rollback
建表
--基本语法
create table table_name(
column_name1 数据类型 [默认值] [约束1] [约束2],
column_name2 数据类型2 --前面每个字段用逗号隔开,最后一个字段没有逗号
);
- 数据类型
数值类型
number(m):整数类型,长度最多为 m 位
number(m,n):m 代表最大位数,n 代表小数的位数(如果小数位超出指定长度,则默认采用四舍五入存储)
number:默认为小数类型,代表数据库存储的最大数据,长度为38,其中小数位7位;相当于double
integer:相当于number(38)
字符串类型
char(n):固定长度字符串类型,实际存储内容长度不够时用空字符填充,最大2000字符空间
--浪费空间,效率高
varchar2(n):Oracle特有类型,可变长字符串,根据实际存储来分配内存,最多 n 个,最大4000字符空间
--节省数据存储空间,效率低
--Oracle中不区分字符类型和字符串类型,表示字符可以使用varchar2(1)/char(1)
布尔类型
Oracle不支持布尔类型,可以使用
number(1) 1 / 0
char(1) y / n
char(3) 是 / 否 等来表示
Oracle中汉字采用的编码方式为UTF-8,汉字长度为2~3,通常默认为3
日期类型
date:年月日,时分秒 --精确到秒,Oracle中日期默认为 dd-mm -yy / 日-月 -年(两位)
timestamp::精确到毫秒
大数据类型
clob:字符大数据,如大文本文件等
blob:二进制大数据,如视频等
-
默认值:default
- column_name 数据类型 default 值 [约束]
- 标识该字段在不填写任何内容时,赋予提前指定的数据
- 给定默认值时必须和该字段的数据类型一致
-
约束
- 主键约束(PK)
- column_name 数据类型 primary key
- 唯一、非空
- 用于唯一标识表中的一条数据,如工号、学号等
- 通常每个表都要设置一个主键约束,如果没有就设置一个没有实际含义的列
- 唯一约束
- column_ name 数据类型 unique
- 唯一、可以为空
- 用于约束该字段内容不允许重复,如身份证号、手机号等
- 非空约束
- column_name 数据类型 not null
- 非空、可以重复
- 标识该字段内容不允许为空,但可以重复,如姓名
- 外键约束
- column_name 数据类型 references 主表名(列名)—> 通常列名为主键列或唯一字段
- 可以重复,可以为null
- 标识该字段的值不允许随意输入,必须遵从于另一个表中的某一列主键值或是唯一列中的值
- 设置外键的所在表为从表,外键指向的表中某一列所在的表为主表
- 从表中的对应字段数据要跟从于主表中对应的字段
- 检查约束(自定义约束)
- column_name 数据类型 check ( 检查约束表达式 )
- 根据自定义规则对该字段进行约束
- sex char(3) check ( sex in (‘男’,'女‘) ) 性别只能是男 / 女
- email varchar2(30) check ( email like ‘%@%’ ) 邮箱必须包含@符号
- phone char(11) check ( phone like ‘__’ )
- phone char(11) check ( length (phone) = 11 ) 手机号必须十一位
- 主键约束(PK)
联合约束
- 使用表的任意一个字段无法标识主键或唯一约束时,可以使用两个字段组合进行约束
- 表与表为多对多时,建立联系时需要用到联合约束
字段级约束 | 联合约束(表级约束) |
---|---|
定义在某一个字段后面 | 不定义在某个字段后,定义在表上 |
主键约束、唯一约束、非空约束、外键约束、检查约束 | 联合主键约束、联合唯一约束 |
primary key、unique、not null、references、check | 联合主键:primary key(字段1,字段2) 联合唯一:unique(字段1,字段2) |
--联合约束
--学生表
create table students(
s_id number(5) primary key,
s_name varchar2(30) not null
);
--课程表
create table courses(
c_id number(5) primary key,
c_name varchar2(30) not null
);
--课程、学生选课表 关系表
create table sc( --学生和课程为多对多关系
s_id number(5) references students(s_id),
c_id number(5) references courses(c_id),
primary key(s_id,c_id)
);
insert into students values(1,'hang');
insert into students values(2,'yuan');
insert into courses values(10,'CoreJava');
insert into courses values(11,'Oracle');
insert into sc values(1,10);
insert into sc values(1,11);
insert into sc values(2,11);
--表连接,根据学生查询课程
select * from students s join sc on s.s_id = sc.s_id join courses c on c.c_id = sc.c_id
- 标识符命名规范(表名、字段名等):
- 有数字、字母、_ 、$、# 组成,不能以数字开头
- 有长度限制,不能超过30个字符
- 不区分大小写
- 不能以Oracle中关键字命名
DML命令(增删改)
- 插入数据 insert
- insert into table_name ( column1,column2,column3 ) values ( value1,value2,value3 )
- 指定列时没有顺序要求
- 值的个数、顺序、数据类型必须和前面指定的列对应
- 插入数据时,非空字段没有默认值的情况下,必须给定数据
- 如果对表中所有字段都插入数据,可以将column省略,但是values中值的个数、数据类型、顺序必须和表结构中的完全一致
- 修改数据update
- update table_name set column1 = value1,column2 = value2 where 过滤条件
- 把符合where过滤条件的数据行,根据字段 = 值进行对应内容的修改
- 没有where条件,代表要改表中所有数据
- 修改数据时,必须遵循数据类型、长度和约束
- 在添加和修改数据时,出现“未找到父相关键字”,则代表违反了FK约束条件(在主表的PK或唯一键中没找到对应的数据内容)
- 删除数据delete
- delete from table_name where 过滤条件
- 从表中删除符合过滤条件的数据,逐行删除
- 删除主表数据时,一定要保证从表中没有对应的引用,否则会出现“违反完整约束条件-已找到子记录“
- 删除数据通常给出过滤条件,如果没有指定条件,则删除全表中的所有数据
- 删除全表 delete from table_name 效率低
- 表截断 —> 直接将存储表数据部分的空间直接清除,进而删除数据 [非DML]
- truncate table table_name 效率远高于delete
- truncate 和 delete只是删除表中数据,表结构还在
- drop table table_name
- 将表结构字段、约束及表中的数据删除
- update table_name set delete Flag = 1 where id = 5 设置数据的删除标志为1
序列(开发时使用UUID+算法 维护主键唯一性)
- create sequence name_sequence —> 默认从 1 开始,每次加 1
- create sequence name_sequence start with n —> 创建序列从 n 开始,每次加 1
- create sequence name_sequence start with n increment by m —> 创建序列从 n 开始,每次加m
- Oracle提供的工具,自动产生一系列连续且不重复的值
- 通常用于insert插入数据语句中,用于维护主键的唯一性
- name_sequence . nextval —> 获取序列中下一个有效值
- name_sequence . currval —> 查看序列当前值
- drop sequence name_sequence —> 删除序列
- 序列一旦被创建,被所有的表都共享,所以在实际开发应用时,通常每张表创建对应的一个序列
- 序列中的数据一旦被使用,就无法再重用
视图view
- create view name_view as 查询语句
- 一条起了名字的查询语句,视图不存储实际数据,基本不占磁盘空间,只有命令
- 并不存储数据,只是起到简化SQL语句作用,不提高查询效率
- select name_view from user_views —> 查看视图
- select * from name_view —> 使用视图 —> * 和字段名根据需求选择
- drop view name_view —> 删除视图
- 安全性,对开发人员屏蔽掉表和字段信息
- 视图可以根据用户不同权限,进行针对定制
索引index
- create index name_index on name_table(name_column)
- drop index name_index —> 删除索引
- 在表中用于提高查询效率,类似书前目录
- 索引中有数据(索引列的内容 + rowid),索引列自然排序
- 将常用的查询字段设为索引,且主键和唯一列数据库默认创建索引
- 索引不是创建越多越好,索引占实际存储空间,会导致增删改数据时,需要同时维护索引的数据而影响效率
- 在Oracle中,索引创建之后,不需要手动使用;查询时使用到索引列时自动使用索引
- 如果同时包含多个过滤条件,将含有索引的过滤条件放在前面
事务:transaction(TCL事务控制语句)
- 数据库的最小执行单元,通常由一个或是多个SQL语句构成,所有的SQL都执行成功代表事务成功,事务提交为commit;有一个SQL执行失败则代表事务失败,事务回滚rollback
- 事务的大小取决于实际开发业务的需求
- 事务的边界
- 上一事务结束后,在执行第一个DML语句时,事务自动开始 —> 从第一条SQL开始执行,事务开始
- 结束
- 遇到DML语句(insert 、 delete 、 update)需要明确指定结束 —> commit 提交或 rollback回滚
- 遇到 create / drop / alter DDL语句时,事务自动结束
- 回滚段
- 数据库服务器DBServer会为每一个连接上的client,开辟一小块独立的内存空间(称为回滚段),用于暂时存储sql语句的执行结果,当事务commit时,会把自己回滚的数据真正的写入 DB中;当事务rollback时,则会清空自己回滚段里的数据。
- 事务底层基于锁对数据库安全进行保证
- 在一个事务insert / update / delete 数据时,会获取该数据的锁标记,直到该事务结束(commit / rollback)才释放锁标记
- 在一个事务执有数据的锁标记时,多事务并发操作,其他事务不能对该数据进行insert / update / delete 操作,直到获取到锁标记为止(可以进行select操作,查询操作不参与事务)
事务的ACID四大特性
- Atomic(原子性):事务中的多个SQL为一个整体,要么全部成功,要么全部失败
- Consistency(一致性):数据的合理性;事务执行前后,无论成功还是失败,最终数据是合理的
- Isolation(隔离性):多个事务并发时,事务之间相互独立,互不影响
- Durability(持久性):事务结束(成功或失败),对数据库的数据修改是永久性的