Oracle独特的技术、JDBC

一. Oracle独特的技术

1. 过气技术

下面技术在历史长河中已经被淘汰但老项目,小项目依然在用,只做了解.

2. 虚表 dual

dual是一个虚拟表,MySQL没有,用来构成select的语法规则,Oracle保证dual里永远只有一条记录,用它可以做很多事.

将结果存储在dual表中:

select 1 from dual;					虚拟出一个数字列
select 'abc' from dual;				虚拟出一个字符串列
select sysdate from dual;		获取系统当前日期
select sys_guid() from dual;	获取uuid

3. 序列 sequence

Oracle自身提供的自增主键支持,和MySQL的实现思路完全不同.
在这里插入图片描述
在这里插入图片描述

4. 授权视图

使用system登录,修改ht的权限为dba,否则无法创建视图.
在这里插入图片描述
在这里插入图片描述
或者

使用system账户执行,分配视图权限.

grant create any view to ht;

5. 视图 view

视图本质就是一个查询,和我们自己查询的区别是,它执行完会有缓存,下次查询就直接使用.但其它因为实现缓存,无法做优化,大型项目中禁止使用.
在这里插入图片描述注意: 视图只需创建一次,后面就可以类似表来使用,只是用来查询不能更新和删除.

创建视图 ,本质上就是缓存一个查询结果
create or replace view STU_V as
  select * from  stu where ssex=0
查询表结构
select * from  stu where ssex=0
直接查询视图,高效,但是无法优化
select * from  STU_V
可以看到两者查询结果没有分别

6. 触发器 trigger

记录生效点:BEFORE/AFTER

记录的操作:INSERT/UPDATE/DELETE
在这里插入图片描述
在这里插入图片描述
需求:当修改sex值时触发逻辑.

--设置触发器 ---禁用,因为无法控制程序员的权限,可能有安全隐患
create or replace trigger UPDATE_STU_TRI
  before update on stu 
  for each row
declare
  -- local variables here
begin
  --如果 SEX>0,统一设置成1
  IF :NEW.SSEX>5 THEN 
       :NEW.SSEX := 1;
  END IF;
end UPDATE_STU_TRI;

--使用触发器:
SELECT * FROM STU
update stu set ssex=10;--触发器执行,都是1了
update stu set ssex=3;--不满足触发器,就是3

7. 存储过程 procedure

概念:

存储过程(Stored Procedure)其实就是数据库端的编程,在数据库为王的时代,虽然已经过去,当时数据库大集中,部署在超级好的服务器,甚至是小型机,所以执行的性能超群,运行在上面的程序自然也就性能极佳。但当分布式架构兴起后,数据库在整个架构中的作用一再衰落,逐步边缘化。再者存储过程中的SQL是依赖数据库厂商,每个厂商都有其个性的SQL,导致程序迁移数据库时,如从oracle迁移到mysql时基本重写,工作量巨大,造成修改的风险。于是主流方式已经将其从数据库端前置到java程序端实现,这样迁移数据库变得轻松。

二. JDBC

1. 概念

我们学习了数据库,数据库实现了数据的持久化,但我们最终要在程序里处理数据,那java代码中怎么去访问数据库读写数据呢?

这就要用到sun公司设定的一套数据库标准了,这套标准就是JDBC(Java Database Connectivity)。但它只是规范,不做具体实现。于是数据库厂商又根据JDBC标准,实现自家的驱动Driver。如:MySQL驱动com.mysql.cj.jdbc.Driver,Oracle的驱动oracle.jdbc.OracleDriver。有了这套解决方案,java就可以访问数据库中的数据了。

public interface Connection  extends Wrapper, AutoCloseable {}

public interface Statement extends Wrapper, AutoCloseable {}

public interface PreparedStatement extends Statement {}

public interface CallableStatement extends PreparedStatement {}

public interface ResultSet extends Wrapper, AutoCloseable {}

Java中提倡面向接口开发,而最经典的接口设计莫过于JDBC数据库接口。

Connection链接、Statement语句、PreparedStatement预处理语句、CallableStatement存储过程、ResultSet结果集。

调用方式有三种:Statement语句、PreparedStatement预处理语句、CallableStatement存储过程,推荐使用第二种PreparedStatement,防止SQL注入,其也是预编译性能高。

2. 使用

2.1 导入jar包(丰富的工具类)

2.2 获取和数据库的连接(用户名、密码)

2.3 通过程序执行SQL

2.4 通过程序处理结果

3. 向IDEA中导入jar包

3.1 创建Java工程

3.2 创建lib目录,拷贝驱动 objbc6-11.1.0.7.0 到 lib 目录下

3.2 项目引用这个外部jar包
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 入门案例

import java.sql.*;

public class Test1 {
    public static void main(String[] args) throws Exception {
        // 1. 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2. 获取和数据库的连接
        // String url = "jdbc:mysql://localhost:3306/py_school_db?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";
        String url = "jdbc:mysql:///py_school_db?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";
        String user = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, user, password);
        // 3. 获取传输器
        Statement st = conn.createStatement();
        // 4. 执行SQL
        ResultSet rs = st.executeQuery("select * from students");
        // 5. 解析结果
        while (rs.next()){
            // 获取数据
            for (int i = 1 ; i <= 5 ; i++){
                System.out.println(resultSet.getString(i));
            }
        }
        // 6. 释放资源
        rs.close();
        st.close();
        conn.close();
    }
}

5. SQL攻击注入的解决方案

5.1 不安全:

private static void login() throws Exception {
    Class.forName("com.mysql.cj.jdbc.Driver");
    String url = "jdbc:mysql:///lz?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";
    String user = "root";
    String password = "root";
    Connection connection = DriverManager.getConnection(url, user, password);
    /**
     * 传输器在执行SQL时不安全
     */
    Statement statement = connection.createStatement();

    System.out.println("请输入用户名: ");
    String name = new Scanner(System.in).nextLine();
    System.out.println("请输入密码: ");
    String pass = new Scanner(System.in).nextLine();
    // SQL注入攻击问题: 本质上是因为SQL语句中出现了特殊符号#,改变了SQL语义
    String sql = "select * from user where name='" + name + "' and password='" + pass + "'";
    ResultSet resultSet = statement.executeQuery(sql);
    if (resultSet.next()){
        System.out.println("登陆成功!");
    }else {
        System.out.println("查无此人!");
    }
    resultSet.close();
    statement.close();
    connection.close();
}

5.2 解决办法

/*总结:
	作用: java程序和数据库连接的技术
		    SQL注入攻击问题:拼接SQL时,出现了特殊符号#,只需要输入用户名而不需要密码都可以登录
		    SQL注入攻击解决方案:不用Statement,换成了PreparedStatement,
		            新的工具类的好处:不用自己拼SQl的字符串了,安全,高效
		    PreparedStatement的解决过程:先把SQL骨架发给数据库,数据库进行预编译
		            等到设置好了参数,再和骨架一起执行,避免了人为的恶意的拼串造成的隐患
		 */
private static void login2() throws Exception {
    Class.forName("com.mysql.cj.jdbc.Driver");
    String url = "jdbc:mysql:///lz?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";
    String user = "root";
    String password = "root";
    Connection connection = DriverManager.getConnection(url, user, password);
    System.out.println("请输入用户名: ");
    String name = new Scanner(System.in).nextLine();
    System.out.println("请输入密码: ");
    String pass = new Scanner(System.in).nextLine();
    /**
     * ?: 占位符
     * SQL骨架
     */
    String sql = "select * from user where name=? and password=?";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    // 给SQL设置参数
    /**
     * preparedStatement.setString(参数索引,参数值);
     */
    preparedStatement.setString(1,name);
    preparedStatement.setString(2,pass);
    ResultSet resultSet = preparedStatement.executeQuery();
    if (resultSet.next()){
        System.out.println("登陆成功!");
    }else {
        System.out.println("查无此人!");
    }
    resultSet.close();
    preparedStatement.close();
    connection.close();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘刘刘刘刘先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值