JavaSE就业班四----数据库Oracle和JDBC

1.数据库的概述(常识)

  • 数据库的概念

           数据库就是指存放数据的仓库

  • 主流的数据库

               目前主流的数据库有:Oracle、SQL Server、MySql、DB2、..

  • SQL语言的主要分类
    • DDL数据定义语句 - 主要用于对数据库中的表格进行创建、修改以及删除操作;
    • DML数据操纵语句 - 主要用于对表格中的数据进行插入、修改、删除操作;
    • Select查询语句  - 主要用于对表中的数据进行查询操作;
    • TCL事务控制语句 - 主要用于对数据的操作进行提交、回滚等操作;
    • DCL数据控制语句 - 主要用于创建用户、删除用户等操作;

2.数据库环境的搭建

  • 数据库的下载和安装
    • 数据库的下载方式: www.oracle.com
    • 数据库的安装方式: 对于精简版来说,找到setup.exe双击打开后一路点击下一步!
                            在安装的过程中将密码设置为:123456 即可   MySQL:是sasa
    •  数据库的卸载方式: 控制面板 => 程序和功能 => 找到oracle11g,右击选择卸载!
  • 数据库的登录方式
    • 若没有安装本地数据库,需要先使用 telnet IP地址 方式登录拥有数据库的服务器(Windows系统)
    • 进入数据库的方式
             1) 使用dos窗口 加 sqlplus工具,输入数据库的用户名和密码即可
             2) 使用图形化工具sql developer进行操作           
      • 3)Oracle默认端口1521    MySQL的是8080    
    • Ubuntu系统登录
      • 终端输入    sqlplus
      • show user;              # 查看当前账号
      •  
  • 表空间和账户的创建
    •  由于system账户是oracle的系统账户,使用该账户对数据操作有风险,因此需要开通新的账户,而账户对应的磁盘空间就叫做表空间,具体命令如下:
      •  create tablespace practice        -- 表示创建表空间,名字为practice
           datafile 'd:\practice.dbf'        -- 表示对应d盘下名字为pratice.dbf的文件
           size 10M;                         -- 表示表空间的大小为10Mb 
           
           drop tablespace practice          -- 表示删除名字为practice的表空间
           including contents and datafiles; -- 表示同时删除里面的内容以及对应的文件

           
           create user xiaomage              -- 表示创建用户,名字为 xiaomage          
           identified by 123456              -- 表示密码设置为 123456
           default tablespace practice;      -- 表示默认表空间为 practice

           drop user xiaomage;               -- 表示删除用户 xiaomage

           
           grant create view to xiaomage;      -- 表示授予创建视图的权限给xiaomage
           grant connect,resource to xiaomage; -- 表示授予连接、建表等权限给xiaomage
           
           revoke create view from xiaomage;      -- 表示撤销xiaomage创建视图的权限 
           revoke connect,resource from xiaomage; -- 表示撤销xiaomage连接、建表等权限    
           
           exit;  -- 表示退出当前账户,使用xiaomage账户重新登录

3.常用的数据类型

在Java语言中的基本数据类型有:byte、short、int、long、float、double、char、boolean类型。
   

在SQL语言中的常用数据类型有:数值类型、字符类型、日期类型
       
   number(n)   - 表示可以描述n位数字,如:number(2)等
   number(n,m) - 表示总共描述n位数字,但小数点后有m位数字,如:number(3,2)等

   char(n) - 表示字符串的长度为n,若填不满则使用空格补齐
   varchar2(n) - 表示字符串的长度为n,若填不满则自动缩小长度

   date - 用于描述日期类型,可以描述年月日时分秒信息。

4.DDL数据定义语句

  • 创建表格的格式
    •  create table 表名(
            列名1 数据类型,
            列名2 数据类型,
            ...
         );
      如:
         create table person(
            name varchar2(20),   -- 姓名
            age  number(3),      -- 年龄
            sex  char(3)         -- 性别
         ); 
  • 修改表格的格式
    • -- 删除表格中列的格式
         alter table 表名 drop column 列名; 
      如:
         -- 表示修改person表的方式为删除名字为sex的列
         alter table person drop column sex;   
        
         
         -- 增加表格中列的格式
         alter table 表名 add 列名 数据类型;
      如:
         -- 实现向person表中增加名字为sex类型为3个字节字符类型的列
         alter table person add sex char(3);

         
         -- 修改表格中列名的格式
         alter table 表名 rename column 列名 to 新列名;
      如:
         -- 实现将person表中名字为sex的列名修改为gender
         alter table person rename column sex to gender; 

      保留字段的使用:
         create table ps(
             pid varchar2(8),
             title varchar2(20),
             price number(8,2),
             gid   number(2),
             des   CLOB,
             count number(6),
             baoliu1 varchar2(20),
             baoliu2 varchar2(20),
             baoliu3 varchar2(20)
         );   

  • 删除表格的格式
    •  drop table 表名;
      如:
         -- 表示删除名字为p的表
         drop table p; 

5.DML数据操纵语句

  • 插入数据的格式
    • insert into 表名 [(列名1, 列名2, ...)] values(数据1, 数据2, ...);
      如:
         -- 实现向person表中插入数据 '武志伟'  18 '男'
         insert into person (name, age, gender) values('武志伟', 18, '男'); 
         -- 实现向person表中插入数据 '苍老师'      '女'
         insert into person (name, gender) values('苍老师', '女');
         -- 实现向person表中插入数据 '薛宇宸' 17 '男'
         insert into person values('薛宇宸', 17, '男');
  •  修改(更新)数据的格式
    • update 表名 set 列名 = 更新后的新值 [where 条件];
      如:
         -- 实现将person表中所有人的年龄都改为18
         update person set age = 18;
         -- 实现将person表中名字为'武志伟'的年龄改为16
         update person set age = 16 where name = '武志伟';
  • 删除数据的格式
    • delete [from] 表名 [where 条件];
      如:
         -- 实现将person表中名字为'苍老师'的记录删除
         delete from person where name = '苍老师';
         -- 实现将person表中所有记录删除
         delete from person;

6.Select查询(一)

  • 查看表结构的方式
    • desc 表名;  -- 表示查看表结构,也就是查看该表的所有字段以及类型等信息
  • 查询表中字段的数值
    • select 列名1,列名2,... from 表名;
      如:
         -- 查询员工表中所有员工的编号
         select id from s_emp; 
         -- 查询员工表中所有员工的编号、名字以及薪水
         select id,first_name,salary from s_emp;
    •  -- 查询员工表中所有字段的简化写法
         select * from s_emp;
  • 常用的算术运算符
    •   + 加法   -  减法    *  乘法     / 除法    mod 取余
      •  -- 查询员工表中每个员工加500元过节费后的薪水
           select salary,salary+500 from s_emp;
           -- 查询员工表中每个员工减200元后的薪水
           select id,first_name,salary,salary-200 from s_emp; 
           -- 查询员工表中所有员工的年薪
           select first_name,salary,salary*16 from s_emp;
           -- 查询员工表中所有员工的日薪
           select first_name,salary,salary/22 from s_emp;
           -- 查询员工表中9对2取余的结果
           select first_name,salary,mod(9,2) from s_emp;
  •  列的别名
    • select 列名1 [as] 列的别名1, 列名2 [as] 列的别名2, ... from 表名;
      •  -- 查询员工表中所有员工的年薪,并将列名设置为 '年薪'
           select salary, salary*16 as 年薪 from s_emp;
           -- as 关键字可以省略
           select salary, salary*16 年薪 from s_emp;     
           -- 希望在年薪中间加上 空格 
           select salary, salary*16 年 薪 from s_emp;   -- error
           -- 更正上述的错误
           select salary, salary*16 "年 薪" from s_emp;
           -- 查询员工表中所有员工的年薪,并将列名设置为'Income'
           select salary, salary*16 Income from s_emp;
           -- ''和""中括起来的内容是区分大小写的
           select salary, salary*16 "Income" from s_emp;

        注意:
           a.当别名中需要区分大小写,或者有空格这类特殊字符时,需要使用 双引号 括起来
           b.当需要描述字符串数据时,就需要使用 单引号 括起来;

  • 字符串的拼接
    • 在sql语句中使用 || 表示拼接字符串的含义。
      •  -- 查询员工表中所有员工的姓名
           select last_name, first_name from s_emp;
      •  -- 将姓名拼接起来组成一个整体,并起别名为 "姓  名"
           select last_name||first_name "姓  名" from s_emp;
      •    -- 将姓名之间使用字符串'-'拼接起来
           select last_name||'-'||first_name "姓   名" from s_emp;
      •    -- 将姓名之间使用字符串'_'拼接起来
           select last_name||'_'||first_name "姓   名" from s_emp;
      •  -- 将姓名之间使用单引号拼接起来
           select last_name||'''||first_name "姓   名" from s_emp;  -- error
      •  -- 单引号代表转义字符 ''表示显示一个单引号
           select last_name||''''||first_name "姓   名" from s_emp;
           select last_name||''''''||first_name "姓   名" from s_emp;
           select last_name||''''||''''||first_name "姓   名" from s_emp;
      •    -- 查询常量列
           select '兄弟连' "公司 名称" from s_emp;
  •  where子句
    • select 列名1 [as] 列的别名1, 列名2 [as] 列的别名2, ... from 表名   where 查询的条件表达式;
  •  常用的比较运算符
    •  = 等于 <> 不等于   < 小于   <= 小于等于   > 大于    >= 大于等于

    • 注意:
         sql语句中没有赋值的概念,只有=表示等于的含义
      如:
         -- 查询员工表中薪水等于800的员工编号,名字以及薪水信息
         select id, first_name, salary from s_emp
         where salary = 800;    
         -- 查询员工表中薪水不等于800的员工编号,名字以及薪水信息
         select id, first_name, salary from s_emp
         where salary <> 800;
         -- 查询员工表中薪水大于1000的员工编号,名字以及薪水信息
         select id, first_name, salary from s_emp
         where salary > 1000;
         -- 查询员工表中薪水小于等于800的员工编号,名字以及薪水信息
         select id, first_name, salary from s_emp
         where salary <= 800;

  •  常用的逻辑运算符
    •  and(&&)  并且      or(||)  或者    not(!) 取反
      如:
         -- 查询员工表中薪水大于等于1000并且部门编号为41的员工信息
         select id, first_name, salary, dept_id from s_emp
         where salary >= 1000 and dept_id = 41;
         select id, first_name, salary, dept_id from s_emp
         where salary >= 1000 && dept_id = 41;               -- error
         -- 查询员工表中薪水大于等于1000 并且 部门编号不为41的员工信息
         select id, first_name, salary, dept_id from s_emp
         where salary >= 1000 and dept_id <> 41;
         select id, first_name, salary, dept_id from s_emp
         where salary >= 1000 and not dept_id = 41;
         -- 查询员工表中薪水小于800 或者 部门编号为42的员工信息
         select id, first_name, salary, dept_id from s_emp
         where salary < 800 or dept_id = 42;
         -- 查询员工表中薪水小于1000 并且 部门编号为31 或者 42
         select id, first_name, salary, dept_id from s_emp
         where salary < 1000 and dept_id = 31 or dept_id = 42;   -- 优先级
         select id, first_name, salary, dept_id from s_emp
         where salary < 1000 and (dept_id = 31 or dept_id = 42); -- 提高优先级
         
         -- 见识一下极限条件
         select * from s_emp where 1 = 1;  -- 全部查询完毕
         select * from s_emp where 1 != 1; -- 没有报错,但一条记录都没有查询出来
         select * from s_emp where 1 <> 1; -- 推荐该运算符
         -- 查询员工的日薪,last_name = 'Dancs';
         select last_name, salary, salary/21 from s_emp
         where last_name = 'dancs';        -- 没有查询到
         select last_name, salary, salary/21 from s_emp
         where last_name = 'Dancs';        -- 可以查询到

      注意:
         a.and运算符的优先级高于or,该运算符会被优先处理
         b.在where子句中的条件是从右向左依次判断的,
           对于and运算符来说,应该尽可能将条件更容易为假的放在右边;
           对于or运算符来说,应该尽可能将条件更容易为真的放在右边;

  • between...and的使用
    •  between ... and  表示在...和...之间,该语句表达的是闭区间。

      如:
         -- 查询员工表中薪水范围在800到1000之间的所有员工编号、名字以及薪水信息
         select id, first_name, salary from s_emp
         where salary between 800 and 1000;
         select id, first_name, salary from s_emp
         where salary >= 800 and salary <= 1000;  
         select id, first_name, salary from s_emp
         where salary > 800 and salary < 1000;  
         -- 查询员工表中薪水范围不在1000到1300之间
         select id, first_name, salary from s_emp
         where salary not between 1000 and 1300;
         select id, first_name, salary from s_emp
         where salary < 1000 or salary > 1300;

         -- 常见的错误,不会报错但啥也查不到
         select id, first_name, salary from s_emp
         where salary between 1000 and 800; 
         select id, first_name, salary from s_emp
         where salary >= 1000 and salary <= 800; 

  • 空值的处理
    • is null  - 用于判断是否为空
         is not null - 用于判断是否不为空

      如:
         -- 查询员工表中提成为空的员工编号,名字以及提成信息
         select id, first_name, commission_pct from s_emp    -- 查询有结果
         where commission_pct is null;
         -- 查询员工表中提成不为空的员工编号,名字以及提成信息
         select id, first_name, commission_pct from s_emp   -- 查询有结果
         where commission_pct is not null;       
         -- 查询员工表中所有员工的薪水,加上提成的薪水
         select salary, salary+commission_pct from s_emp;   -- 查询结果有问题 
         

         nvl(参数1, 参数2) - 若参数1不为空,则函数的结果就是参数1的数值
                           - 若参数1为空,则函数的结果就是参数2的数值
      如:
         -- 查询员工表中所有员工的薪水,加上提成的薪水
         select salary, salary+nvl(commission_pct, 0) from s_emp;

      注意:
         任何数据和空运算的结果还是空!

  • 去重处理
    • select [distinct] 列名1 [as] 列的别名1, 列名2 [as] 列的别名2, ... from 表名
         where 查询的条件表达式;

      如:
         -- 查询员工表中薪水大于800的员工编号,名字以及薪水信息
         select id, first_name, salary from s_emp
         where salary > 800;
         -- 查询员工表中薪水大于800的薪水等级,去掉重复的薪水
         select distinct salary from s_emp
         where salary > 800;
         -- 查询员工表中薪水、领导的编号信息
         select salary, manager_id from s_emp;
         -- 查询员工表中去重之后的薪水和领导编号
         -- 只有薪水和领导编号都相同时才能去重
         select distinct salary, manager_id from s_emp;   

7.Select查询(二)

  • 按照范围进行查找

    • between ... and ...   -- 表示查询在...和...之间的内容,而且是闭区间
         in ...                -- 表示查询在...里面的任何内容
         not in ...            -- 表示查询不在...里面的数据内容

      如:
         -- 查询员工表中部门编号在41和42之间的员工编号、员工名字以及部门编号
         select id, first_name, dept_id from s_emp
         where dept_id between 41 and 42;
         select id, first_name, dept_id from s_emp
         where dept_id >= 41 and dept_id <= 42;
         select id, first_name, dept_id from s_emp
         where dept_id in(41, 42);
        
         -- 查询员工表中所有部门编号的员工编号、员工名字以及部门编号
         select id, first_name, dept_id from s_emp;
         -- 查询员工表中所有部门编号并且进行去重处理
         select distinct dept_id from s_emp;
         -- 查询员工表中部门编号在41和42之间的员工编号、员工名字以及部门编号
         -- 由于not in使用太复杂而且效率较低,因此以后的开发中尽量不要使用
         select id, first_name, dept_id from s_emp
         where dept_id not in(43, 34, 44, 31, 35, 50, 45, 32, 33, 10);

  • 按照条件进行模糊查询
    •  like ...  -- 表示像...,通常进行模糊查询,搭配使用的通配符有:
              _  -- 表示任意一个字符
              %  -- 表示任意多个字符
         not like ... (了解)

      如:
         -- 查询员工表中名字使用B开头的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like 'b%';        -- 查询不到数据
         select id, first_name from s_emp
         where first_name like 'B%';
         -- 查询员工表中名字里含有'德'的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like '%德%';
         -- 查询员工表中名字末尾是'德'前面只有一个字符的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like '_德';
         -- 查询员工表中名字末尾是'克'的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like '%克';
         -- 查询员工表中名字中含有'拉'的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like '%拉%';
         -- 查询员工表中名字末尾是'拉'的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like '%拉';

         -- 向员工表中插入数据内容 '1001' '_欣霖'
         insert into s_emp (id, first_name) values('1001', '_欣霖');
         -- 查询员工表中使用'_'为开头的员工编号和员工名字
         select id, first_name from s_emp
         where first_name like '_%';      -- 其中_被当做通配符处理,查询到所有数据
         -- 尝试使用单引号进行转义
         select id, first_name from s_emp
         where first_name like''_%';      -- error: 无效的字符,单引号无法转义_
         -- 实现对_进行转义
         -- 表示将'\'当做转义字符来转义'\'后面字符的含义
         select id, first_name from s_emp
         where first_name like '\_%' escape '\'; 
         -- 表示将'#'当做转义字符来转义'\'后面字符的含义
         select id, first_name from s_emp
         where first_name like '#_%' escape '#'; 

    •  -- 查询“山东”的学生姓名、电话、住址 student学生表
         select studentname, phone, address from student
         where address = '山东';                          -- 语句无误,查不到数据
         select studentname, phone, address from student
         where address like '山东%'; 

         -- 查询名称中含有“p”字母的科目信息 subject课程表
         select * from subject
         where subjectname like '%p%';   

         -- 查询电话中以“1387”开头的学生信息 student学生表
         select * from student 
         where phone like '1387%';

         -- 查询姓姜的,单名的学生信息 student学生表 
         select * from student
         where studentname like '姜_';
         -- 查询学号为S1101004的指定1,2,3科目考试成绩  result成绩表
         select studentno, studentresult, subjectid from result
         where studentno = 'S1101004' and subjectid in (1, 2, 3);

  • order by子句 
    •  select [distinct] 字段名1 [as 别名1], 字段名2 [as 别名2], ...
         from 表名
         [where 查询的条件];
         [order by 字段/别名/位置编号 asc/desc] ;  -- 默认是从小到大排序(asc)

      如:
         -- 查询员工表中所有员工的名字和薪水,并且按照薪水进行排序
         select first_name, salary from s_emp
         order by salary;                      -- 默认按照升序排列,而且null放在最后
         select first_name, salary from s_emp
         order by salary asc;                  -- asc可以写也可以不写
         -- 查询员工表中所有员工的名字和薪水,要求按照薪水进行降序排列
         select first_name, salary from s_emp
         order by salary desc;                 -- null放在最前面,影响体验度
         -- 若希望将null值放在后面
         select first_name, salary from s_emp
         order by salary desc nulls last;
         
         -- 查询员工表中所有员工的名字和薪水,将薪水起别名为 sal并按照sal进行升序
         select first_name, salary sal from s_emp
         order by sal;
         -- 查询员工表中所有员工的名字和年薪,并按照年薪进行升序排列
         select first_name, salary, salary*16 "年 薪" from s_emp
         order by "年 薪";
         
         -- 查询员工表中所有员工的名字和薪水,并根据位置编号(下标)进行升序排序
         select first_name, salary from s_emp
         order by 0;                            -- error,位置编号从1开始
         select first_name, salary from s_emp
         order by 1;                            -- 表示按照位置编号1(名字)开始排序
         select first_name, salary from s_emp
         order by 2;                            -- 表示按照位置编号2(薪水)开始排序
         select first_name, salary from s_emp
         order by 3;                            -- error,查询的列数总共2列
         select first_name, salary, salary*16 from s_emp
         order by 3;                            -- 表示按照年薪排序

         -- 查询员工表中所有员工的部门编号,薪水,要求先按照部门编号进行降序排序
         select dept_id, salary from s_emp
         order by dept_id desc;   
         -- 查询员工表中所有员工的部门编号,薪水,先按照部门编号降序,再按照薪水升序
         select dept_id, salary from s_emp
         order by dept_id desc, salary;    
         -- 查询员工表中所有员工的部门编号,薪水,先按照部门编号降序,再按照薪水降序
         select dept_id, salary from s_emp
         order by dept_id desc, salary desc;    -- 多字段排序时,需要写多个desc
         -- 先按照部门编号降序,再按照薪水降序,再按照员工编号升序
         select dept_id, salary, id from s_emp
         order by dept_id desc, salary desc, id asc; 

  •  字符串相关的常用函数
    • 如:
         -- 实现计算字符串'hello'的长度
         select length('hello') 字符串长度 from dual;
         -- 实现将字符串'hello'转换为大写
         select upper('hello') 转换为大写 from dual;
         -- 实现将字符串'HELLO'转换为小写
         select lower('HELLO') 转换为小写 from dual;   
         -- 实现将字符串'hello'中的首字母转换为大写
         select initcap('hello') 首字母转大写 from dual;
         -- 实现将字符串'hello'中从下标2开始取出3个字符,下标从1开始
         select substr('hello', 2, 3) 获取子串 from dual;  -- ell
         -- 实现将字符串'hello'和'world'进行拼接
         select concat('hello', 'world') 拼接字符串 from dual; -- helloworld
         -- 实现字符串中内容的替换,将'e'替换为'E'
         select replace('hello', 'e', 'E') 字符串替换 from dual; -- hEllo
         -- 实现字符串中子串的查找,查找'l'第一次出现的下标位置
         select instr('hello', 'l') 子串查找 from dual; -- 3
         -- 实现去除字符串中两端的空白字符
         select length(trim('   hello     ')) 去除空白字符 from dual;
  • 数值相关的常用函数
    •  -- 查询数据3.1415926保留3位小数并四舍五入后的结果
         select round(3.1415926, 3) from dual;   -- 3.142
         -- 查询数据保留1位小数并四舍五入后的结果
         select round(3.1415926, 1) from dual;   -- 3.1
         -- 查询数据保留0位小数,也就是取整数并四舍五入的结果
         select round(3.1415926, 0) from dual;   -- 3
         -- 查询数据保留-1位小数,也就是将整数的最后一位进行四舍五入
         select round(13.1415926, -1) from dual; -- 10

         -- 查询数据3.1415926保留3位小数, 没有四舍五入后的结果
         select trunc(3.1415926, 3) from dual;   -- 3.141
         -- 查询数据保留1位小数并没有四舍五入后的结果
         select trunc(3.1415926, 1) from dual;   -- 3.1
         -- 查询数据保留0位小数,也就是取整数并没有四舍五入的结果
         select trunc(3.1415926, 0) from dual;   -- 3
         -- 查询数据保留-1位小数,也就是将整数的最后一位不进行四舍五入
         select trunc(13.1415926, -1) from dual; -- 10 

  • 日期相关的函数
    • to_date() - 主要用于将字符串类型转换为日期类型后插入到数据库中;
         to_char() - 主要用于将日期类型转换为字符串类型后从数据库中取出数据;
      如:
         -- 查询当前系统时间
         select sysdate from dual;
         -- 查询当前系统时间的昨天
         select sysdate-1 from dual;
         -- 查询当前系统时间的明天
         select sysdate+1 from dual;
         -- 查询员工表中员工的编号、名字以及入职日期,要求入职日期按照年月日
         select id, first_name, start_date from s_emp;
         select id, first_name, to_char(start_date, 'yyyy-mm-dd') 入职日期 from s_emp;
         -- 向员工表中插入编号为'1005', '张斌',to_date('2019-07-23', 'yyyy-mm-dd')
         insert into s_emp (id, first_name, start_date) values('1005', '张斌',to_date('2019-07-23', 'yyyy-mm-dd')); 

         -- 查询当前系统时间的下一个月
         select add_months(sysdate, 1) from dual;
         -- 查询当前系统时间的下两个月
         select add_months(sysdate, 2) from dual;
         -- 查询当前系统时间的上一个月
         select add_months(sysdate, -1) from dual;


         -- 查询当前系统时间+1个月+1天+1小时+1分钟后的时间
         select to_char(add_months(sysdate, 1) + 1 + 1/24 + 1/24/60, 'yyyy-mm-dd hh24:mi:ss') 处理后的时间 from dual;

         -- 查询当前系统时间并按照dd进行截取,也就是dd后面的数据全部丢弃
         select to_char(trunc(sysdate, 'dd'), 'yyyy-mm-dd hh24:mi:ss') from dual; 
         -- 查询当前系统时间并按照mm进行截取
         select to_char(trunc(sysdate, 'mm'), 'yyyy-mm-dd hh24:mi:ss') from dual;
         -- 查询当前系统时间并按照yyyy进行截图
         select to_char(trunc(sysdate, 'yyyy'), 'yyyy-mm-dd hh24:mi:ss') from dual;

  • 练习
    • 练习讲解:
         -- 求当前月份的最后一分钟0秒表示的date数据
         -- 2019-7-31  23:59:00
         select to_char(trunc(add_months(sysdate, 1), 'mm')-1/24/60, 'yyyy-mm-dd hh24:mi:ss') from dual;   

         -- 求下个月的第三天的倒数十分钟0秒表示的date数据
         -- 2019-8-03  23:50:00
         select to_char(trunc(add_months(sysdate, 1), 'mm')+3 - 1/24/60*10, 'yyyy-mm-dd hh24:mi:ss') from dual;

         -- 查询s_emp表格(id,last_name,start_date),按照start_date排序 
         -- 查询的条件为: 入职日期在2018年1月1日 到2018年12月31日
         select id, last_name, start_date from s_emp
         where start_date between to_date('2018-01-01', 'yyyy-mm-dd')
         and to_date('2018-12-31', 'yyyy-mm-dd')
         order by start_date;

  •  作业
    •  -- 查询员工表中部门在31、32、33的员工编号、员工姓名以及部门编号信息
         select id, last_name||first_name "姓 名", dept_id from s_emp
         where dept_id in (31, 32, 33);

         -- 查询成绩表中学生编号、课程编号以及学生成绩信息,要求按照学生编号
         -- 进行降序排列,若学生编号一样按照课程编号降序,
         -- 若课程编号一样按照成绩升序排序
         select id, subjectid, studentresult from result
         order by id desc, subjectid desc, studentresult asc; 

         -- 查询s_emp表所有first_name包含b或B的员工,显示id、first_name、salary信息
         select id, first_name, salary from s_emp
         where first_name like '%b%' or first_name like '%B%';
         select id, first_name, salary from s_emp
         where lower(first_name) like '%b%';

         -- 显示s_emp表中first_name中4个字符以后的内容
         select first_name, substr(first_name, 5, length(first_name)-4) from s_emp;

         -- 查询今天过生日的员工信息,假设入职日期就是出生日期 
         select id, first_name, to_char(start_date, 'yyyy-mm-dd') from s_emp
         where to_char(start_date, 'mm-dd') = to_char(sysdate, 'mm-dd');

8.Select查询(三)

  • 常用的聚合(多行)函数

    • 所谓单行函数主要指 单条数据传入给该函数后处理的结果还是单条数据;

    • 所谓聚合(多行)函数主要指 多条数据传入给函数后处理的结果是单条数据

      •  常用的聚合函数有:

        •  sum() - 主要用于实现多个数据累加和的计算,只能计算数值类型的数据;

        •  avg() - 主要用于实现多个数据平均值的计算,只能计算数值类型的数据;

        •  max() - 主要用于实现多个数据最大值的计算,可以计算任意类型的数据;

        • min() - 主要用于实现多个数据最小值的计算,可以计算任意类型的数据;

        • count() - 主要用于实现多个数据的计数,可以计算任意类型数据,如:count(*)

        • 如:
             -- 查询员工表中所有员工的总薪水信息
             select sum(salary) 人力成本 from s_emp;
             -- 查询员工表中所有员工的平均薪水信息
             select avg(salary) 平均薪水 from s_emp;
             -- 查询员工表中所有员工的最高薪水信息
             select max(salary) 最高薪水 from s_emp;
             -- 查询员工表中资历最小的员工信息
             select max(start_date) 资历最小 from s_emp;
             -- 查询员工表中的最低薪水
             select min(salary) 最低薪水 from s_emp;
             -- 查询员工表中的资历最老的员工信息
             select min(start_date) 资历最老 from s_emp;
             -- 查询员工表中的员工数量
             select count(*) 员工数量 from s_emp;

          练习:
             -- 查询成绩表中所有学员的总成绩
             select sum(studentresult) 总成绩 from result;
             -- 查询成绩表中所有学员成绩的平均成绩
             select avg(studentresult) 平均成绩 from result;
             -- 查询成绩表中所有学员的最高成绩
             select max(studentresult) 最高分 from result;
             -- 查询成绩表中所有学员的最低成绩
             select min(studentresult) 最低分 from result;
             -- 查询成绩表中所有学员的成绩个数
             select count(*) 成绩个数 from result;
             -- 查询员工表中所有员工提成的平均值
             select round(avg(nvl(commission_pct, 0)), 2) from s_emp;

  • group by子句

    • select 字段名1 [as 别名1], 字段名2 [as 别名2], ... from 表名
         [where 条件表达式]
         [group by 字段名1, 字段名2]
         [order by 字段名/别名/位置编号];

      如:
         -- 查询学生表中每个年级的总人数,显示年级编号和总人数
         select gradeid, count(*) from student
         group by gradeid
         order by count(*);

      注意:
         select后面允许出现的字段只能是group by后面跟的字段以及聚合函数

      练习:
         -- 查询每门课程的平均成绩,每...就表示按照...分组  result成绩表
         select subjectid 课程编号, round(avg(studentresult),2) 平均分 from result
         group by subjectid
         order by avg(studentresult);
         
         -- 查询学生表中每个年级中每种性别的总人数,,并按照年级排序
         select gradeid, sex, count(*) from student
         group by gradeid,sex
         order by gradeid;

         -- 查询员工表中每个部门的员工人数,并按照人数进行排序
         select dept_id, count(*) from s_emp
         group by dept_id
         order by count(*);

  • having子句 
    • select 字段名1 [as 别名1], 字段名2 [as 别名2], ... from 表名
         [where 条件表达式]
         [group by 字段名1, 字段名2]
         [having 条件表达式]
         [order by 字段名/别名/位置编号];

      如:
         -- 查询学生表中每个年级的总人数,并将总人数超过18人的年级编号显示出来
         select gradeid, count(*) from student
         where count(*) > 18
         group by gradeid;                     -- error: where子句中不能使用聚合函数

         select gradeid, count(*) from student
         group by gradeid
         having count(*) > 18                  -- having子句可以对分组的结果再次筛选
         order by count(*);

      练习:
         -- 查询每个年级的总课时,并升序排列 (subject表)
         select gradeid, sum(classhour) from subject
         group by gradeid
         order by sum(classhour) asc;

         -- 查询每个学员的平均分(result表)
         select studentno, round(avg(studentresult), 2) from result
         group by studentno;

         -- 查询每门课程的平均分,并降序排列(result表)
         select subjectid, round(avg(studentresult), 2) from result
         group by subjectid
         order by avg(studentresult) desc;

         -- 查询每个学生的总分,并降序排列(result表)
         select studentno, sum(studentresult) from result
         group by studentno
         order by sum(studentresult) desc;

         -- 查询每门课程的平均分超过60的课程信息 
         select subjectid, round(avg(studentresult), 2) from result
         group by subjectid
         having avg(studentresult) > 60;

         -- 查询员工表中每个部门的总人数超过2个人的部门信息
         select dept_id, count(*) from s_emp
         group by dept_id
         having count(*) > 2;

         -- 查询员工表中每个部门的平均薪水超过1000元的部门信息
         select dept_id, round(avg(salary), 2) from s_emp
         group by dept_id
         having avg(salary) > 1000; 
         

    • Select查询语句的执行流程:
         from 表名  =>  where子句 => group by分组 => having子句 => select取出数据
      => order by子句

  •  子查询(重点、难点)
    • 所谓子查询主要指 让一次查询的结果作为条件再次进行查询的过程,又叫做多次查询
      • 如:
           -- 从学生表中查询比'崔今生'年龄小的学生信息,也就是出生日期比'崔今生'大
           -- 首先从学生表中查询名字为'崔今生'的出生日期
           select borndate from student
           where studentname = '崔今生';          -- 查询结果: 1990-1-5

           -- 其次从学生表中查询出生日期比'崔今生'出生日期大的学生信息
           select borndate from student
           where borndate > to_date('1990-01-05', 'yyyy-mm-dd');
           
           -- 使用子查询来实现上述功能
           select borndate from student
           where borndate > (select borndate from student
               where studentname = '崔今生');   

        练习:
           -- 使用子查询在员工表中查询与'埃琳娜'在同一个部门的员工信息
           -- 首先查询员工表中'埃琳娜'所在的部门编号
           select dept_id from s_emp
           where first_name = '埃琳娜';               -- 查询结果:41

           -- 其次查询员工表中与'埃琳娜'所在部门编号相等的员工信息
           select * from s_emp
           where dept_id = 41;

           -- 合并为子查询语句
           select * from s_emp
           where dept_id = (select dept_id from s_emp
               where first_name = '埃琳娜');

        案例讲解:
            -- 查询'JavaSE'课程并且考了100分的学生信息
            select * from student
            where studentno = 'S1101019';

            -- 从课程表中查询'JavaSE'课程对应的课程编号
            select subjectid from subject
            where subjectname = 'JavaSE';                 -- 查询结果: 1

            -- 从成绩表中查询'JavaSE'课程并且考了100分的学生编号
            select studentno from result 
            where subjectid = 1 and studentresult = 100;  -- 查询结果:S1101019

            -- 合并上述代码
            select * from student
            where studentno = (select studentno from result 
                where subjectid = (select subjectid from subject
                    where subjectname = 'JavaSE' ) and studentresult = 100 );

        练习:
            -- 查询“青铜”阶段开设的课程
            -- 该需求涉及到  grade阶段表 和 subject课程表,表之间通过 gradeid 字段关联 
            -- 先由阶段名称可以查询到阶段编号,再由阶段的编号得到课程名称
            select subjectname from subject 
            where gradeid = (select gradeid from grade 
                where gradename = '青铜');   

            -- 查询参加最近一次“HTML和CSS网页技术”考试成绩的最高分和最低分
            -- 该需求涉及到 subject课程表 和 result成绩表,表之间通过subjectid字段关联
            -- 先由课程名称可以查询到课程编号,再由课程编号可以查询到考试成绩和
            -- 最近一次考试的时间,再根据考试成绩得到最高分和最低分
            select max(studentresult) 最高分, min(studentresult) from result
                where subjectid = ( select subjectid from subject
                    where subjectname = 'HTML和CSS网页技术')
                and examdate = ( select max(examdate) from result
                    where subjectid = ( select subjectid from subject
                        where subjectname = 'HTML和CSS网页技术')); 

        案例讲解:
            -- 查询'JavaSE'课程考试成绩不及格的学生名称
            -- 该需求涉及到 subject课程表 和 result成绩表 以及 student学生表
            -- 其中subject表和result表之间采用 subjectid 字段关联
            -- 其中result表和student表之间采用 studentno 字段关联
            -- 先由课程名称可以查询到课程编号,再由课程编号以及考试成绩可以查询到学号
            -- 再根据学生的学号可以得到学生的名字
            select studentname from student 
            where studentno = ( select studentno from result
                where studentresult < 60 and subjectid =(select subjectid from subject 
                    where subjectname  = 'JavaSE' ));     -- error: 有多个人不及格
            
            -- 当子查询的结果有多个数据内容时,则将 = 换成in即可
            select studentname from student 
            where studentno in ( select studentno from result
                where studentresult < 60 and subjectid =(select subjectid from subject 
                    where subjectname  = 'JavaSE' ));

            -- 当子查询的结果有多个数据内容时,则在 = 的后面加上any关键字即可
            select studentname from student 
            where studentno = any ( select studentno from result
                where studentresult < 60 and subjectid =(select subjectid from subject 
                    where subjectname  = 'JavaSE' )); 

        练习:
           -- 查询参加“JavaSE”课程最近一次考试的在读学生名单
           -- 该需求涉及到 subject课程表 和 result成绩表 以及 student学生表
           -- 其中subject表和result表之间采用 subjectid 字段关联
           -- 其中result表 和 student表之间采用 studentno 字段关联
           -- 先由课程名称得到课程编号,再由课程编号和最近一次考试时间得到学生编号
           -- 最后由学生编号得到学生的名字
           select studentname from student
           where studentno = ( select studentno from result
               where examdate = ( select max(examdate) from result 
                   where subjectid = ( select subjectid from subject 
                       where subjectname = 'JavaSE'))
               and subjectid = ( select subjectid from subject 
                   where subjectname = 'JavaSE'));

  • 作业
    • 查询和Ben一个部门的员工的id,first_name,dept_id,salary信息
       
    •  -- 显示所有工资超过Ben的员工的信息,包括:id,first_name,salary
         -- 显示工资高于全公司平均工资的员工信息,包括id,first_name,salary
         -- 显示工资高于部门id=43的平均工资 的员工信息,包括id,first_name,salary
         -- 显示所有工资等于 部门43的任意员工 的信息,包括id,first_name,salary
         -- 返回管理者的信息,id,first_name,salary,也就是id号和manager_id相同
         -- 显示所有工资大于 部门43的任意员工 的信息,包括id,first_name,salary
         -- 显示平均工资 比部门id=33高的 部门id和平均工资 

9.视图索引和JDBC

  • 视图
    • 什么是视图
      • 视图本质上就是一条sql(select)语句  是可以用来对同一份物理数据做出不同表现的对象
    • 创建一个视图 
      •  create or replace view my_account_view as 
           select  id,acc_no from  xdl_bank_account_33;
    • 删除视图
      •  drop  view   my_account_view;
  • 索引
    • 什么是索引 
      • 索引在数据库中叫 index   它是用来加速数据库查询的一个对象。
          底层使用树状结构  通过消耗大量的空间和时间 来加速查询
    • 主键 和 唯一键
      • 主键和唯一键 系统会自动建立索引   叫唯一性索引 
    •  如何建立索引
      • create   index  索引名  on   表名(字段名);
    • 删除索引
      •  drop   index  索引名;
  •  序列
    • 序列的作用
      • 在oracle 中 为表的主键提供不重复的值
    • 如何创建一个序列 
      • create  sequence  序列名;
    • 如何使用
      •  调用序列的  nextval  或者 currval   使用currval必须调用nextval
          select  dept_id_seq.nextval  from dual;
          insert  into  dept  values(dept_id_seq.nextval,'test'||dept_id_seq.currval,
         'bj');
    •  复杂的序列
      • create  sequence  序列名   start with 值  minvalue 值;
          create  sequence  emp_id_seq   start with 100;
          记住使用时 复杂序列 和 简单序列没有区别
    • 删除序列
      • drop   sequence  序列名;
  • 表关系设计
    • 表和表之间的关系有哪些
      • 1:1    
                表1(夫)      表2(妻)
                 maruzhong    xiaoli
             1              1
             1              1
             dengchao      sunli 
             1              1
             1              1 
           1:m    
                部门            员工
            1                m
                1                1
            
           m:m
                学生             课程
            1                 m
                m                  1
    • 基于表关系的表设计
      •  一对一
             hid   hname      hbir  wid  wname  wbir
              1     mayun     1965   2    test   1990
              2     mahuateng 1975   4    test2  1986
              3     maruzhong 2001   6    test5  2015
            
              hid   hname      hbir  mid
              1     mayun     1965   null
              2     mahuateng 1975   2
              3     maruzhong 2001   3
              
              wid  wname  wbir  mid 
              2    test   1990   1
              4    test2  1986   3
              6    test5  2015   2
            4.2.2  一对多的设计 
              eid  ename  eage   esalary did  dname dcity 
              1     ea     20     8000    1    da    bj
              2     ea     21     12000   1    da    bj
              3     ec     22     20000   1    da    bj
              4     ed     25     35000   2    db    nj
              5     ee     30     50000   2    db    nj
  • 范式
    • 第一范式    表中的字段不可再分 
    • 第二范式    满足第一范式的基础上  表中的数据可以被唯一区分 
                    表有主键即可 
    • 第三范式    满足第二范式的基础上  消除了传递依赖 
      • ​​​​​​​

        利用范式 进行拆表    
             eid  ename  eage   esalary did  
              1     ea     20     8000    1    
              2     ea     21     12000   1    
              3     ec     22     20000   1   
              4     ed     25     35000   2    
              5     ee     30     50000   2   

            did  dname dcity
            1    da    bj
            2    db    nj
         7.让下面的表 满足第三范式 
          id  sid   sname   sage   cid  cname ctime cpoint
          1    1    shq     33     1     java  100   80
          2    1    shq     33     2     python 90   70
          3    1    shq     33     3     php    80   60
          4    2    zly     25     1     java  100   80
          5    2    zly     25     2     python 90   70 
          学生选课关系表 
          id  sid      cid  
          1    1        1     
          2    1        2    
          3    1        3     
          4    2        1     
          5    2        2     
          课程表 
          cid  cname ctime cpoint
          1     java  100   80
          2     python 90   70
          3     php    80   60
          学生表
          sid   sname   sage
          1    shq      33
          2    zly      25 

  • JDBC访问数据库的步骤
    • 加载驱动 
    • 获取连接 Connection
    • 定义sql 并获取sql的执行环境 Statement 
    • 执行sql 处理sql 返回值
          select  返回ResultSet  遍历
          dml     返回int  代表影响的数据行数
    •  释放资源 
          Connection    Statement   ResultSe
      t

10.JDBC访问数据库的步骤 

1.1 加载驱动 
     Class.forName("包名.驱动名")
  1.2 获取连接 Connection
     DriverManager.getConnection(url,username,password)
             比如连接oracle 的url 是  jdbc:oracle:thin:@127.0.0.1:1521:xe
  1.3 定义sql 并获取sql的执行环境 Statement (PrepareadStatement)
      conn.createStatement() 这里以后会使用 prepareadStatement 
  1.4 执行sql 处理sql 返回值
    select  返回ResultSet  遍历       st.executeQuery
    dml     返回int  代表影响的数据行数  st.executeUpdate
  1.5 释放资源 
    Connection    Statement   ResultSet


2.重新建立一个项目   导入oracle 的驱动包  然后按照上面的编写步骤  编写一个可以
根据账号  和  密码  来查询银行账户   如果有银行账户则输出登录成功  否则 输出登录失败。账号和密码
采用键盘输入。
3.使用PreparedStatement  替换  Statement  
  3.1 可以防止拼接的sql注入   原理就是你输入的数据不拼接 直接作为真实数据
  3.2 由于采用预编译  会提前生成sql的执行计划  提高执行效率
  3.3 拼接sql 每次sql是不同的  这会给数据库服务器的sql缓冲造成冲击  无法实现批处理 
  3.4 由于不拼接sql  程序员出错的概率会降低  提高编码质量和速度 
 
4.使用PreparedStatement  完成从键盘录入银行账户的id值   完成根据id 删除银行账户 

5.使用PreparedStatement  完成从键盘录入银行账户的信息  把银行账户的数据插入到
数据库中 注意  id 使用序列产生值。

  • 工具类的思想 
    • 负责获取数据库的连接    以及资源的释放   提高代码复用度 
  • 配置文件的思想 
    • 可以不修改源代码的情况下 修改参数数据 
  • DAO
    •  什么是DAO
      •  Data Access  Object   数据访问对象
      • 它是对数据访问过程 封装的对象
    •  如何编写DAO 
      • 根据需求编写DAO 对应的接口 
      • 使用DBUtil 工具类  结合JDBC编程的五步  实现接口中对应的方法 
      • 练习
        • 仿照根据id查询银行账户 完成 根据账号和密码查询银行账户 
        • 使用DAO  查询银行账户表中的所有数据
        • 使用DAO 根据id 删除银行账户 

你可能感兴趣的:(JavaSE就业班四----数据库Oracle和JDBC)