JDBC回顾

2.JDBC

JDBC是什么?

  • Java Database Connectivity,简称JDBC(Java语言来连接数据库)

JDBC本质是什么?

  • JDBC是SUN公司制定的一套接口(interface)
    • java.sql. *;(这个软件包下有很多接口。)
  • 接口都有调用者和实现者。
  • 面向接口调用、面向接口写实现类,这都属于面向接口编程。
    • 为什么要面向接口编程?
      • 解耦合:降低程序的耦合度,提高程序的扩展力.
      • 多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)
        建议:
        Animal a = new cat() ;
        Animal a = new Dog () ;//喂养的方法
        public void feed(Animal a) { //面向父类型编程。
        
        )
        
        不建议:
        Dog d = new Dog () ;
        cat c = new cat( ;
        
  • 思考:为什么sun要制订一套jdbc接口呢?
    因为每一个数据库的底层实现原理都不一样。
    oracle数据库有自己的原理。
    MysQL数据库也有自己的原理。
    Ms sqlserver数据库也有自己的原理。

    每一个数据库产品都有自己独特的实现原理。
    • 图解:
      在这里插入图片描述
  • JDBC本质到底是什么?
    一套接口

JDBC开发前的准备工作是什么?

先从官网下载对应的驱动jar包,然后将其配置到环境变量classpath当中。

  • classpath=.;D: \course\06-JDBC\resourcesMysq1 connector Java 5.1.23\mysq1-connector-java-5.1.23-bin.jar

以上的配置是针对于文本编辑器的方式开发,使用IDEA工具的时候,不需要配置以上的环境变量。工DA有自己的配置方式。

JDBC编程六步的概述

第一步:注册驱动 (作用:告诉Java程序,即将要连接的是哪个品牌的数据库)
第二步:获取连接(表示jvm的进程和数据库进程之间的通道打开了这属于金承志假案的通信,重量级的,是用完之后一定要关闭)
第三步:获取数据库操作对象(专门执行SQL语句的对象)
第四步:执行SQL语句(DQL,DML…)
第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集)
第六步:释放资源(使用完资源一定要关闭资源,Java和数据库属于进程间的通信,开启后一定要关闭!)

  • 实例1: 执行的是添加语句
package com.buba.JDBC;


import java.sql.*;

public class JDBCTest01 {
    public static void main(String[] args)  {
        Statement statement = null;
        Connection conn = null;
        try {
            //1.注册驱动
            Driver driver = new com.mysql.jdbc.Driver();//多态 父类型指向子类型对象
            DriverManager.registerDriver(driver);
            //2.获取连接
            String url = "jdbc:mysql://127.0.0.1:3306/text1?serverTimezone=Asia/Shanghai";
            String user = "root";
            String password = "root";
             conn = DriverManager.getConnection(url,user,password);
            System.out.println("数据库连接对象="+conn);
            //3.获取数据库操作对象(statement专门执行SQL语句的)
            statement = conn.createStatement();
            //4.执行SQL语句
            String sql = "insert into class(cid,caption) value(4,'1234567890')";
            //专门执行DM江语句的(insert delete update)
            // 返回值是"影响数据库中的记录条数"
            int count = statement.executeUpdate(sql) ;
            System.out.println (count == 1 ?"保存成功":"保存失败");

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            //为了保证资源一定释放 在finally语句块中释放资源
            //必须遵循从小到大依次关闭
            //分别对其try catch
            if (statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

  • 实例2.:执行的是删除和修改语句
package com.buba.JDBC;

import java.sql.*;

public class JDBCTest02 {
    public static void main(String[] args)  {
        Statement statement = null;
        Connection conn = null;
        try {
            //1.注册驱动
            Driver driver = new com.mysql.jdbc.Driver();//多态 父类型指向子类型对象
            DriverManager.registerDriver(driver);
            //2.获取连接
            String url = "jdbc:mysql://127.0.0.1:3306/text1?serverTimezone=Asia/Shanghai";
            String user = "root";
            String password = "root";
            conn = DriverManager.getConnection(url,user,password);
            System.out.println("数据库连接对象="+conn);
            //3.获取数据库操作对象(statement专门执行SQL语句的)
            statement = conn.createStatement();
            //4.执行SQL语句
            //String sql = "delete from class where cid = 4";
            //jdbc中的SQL语句不需要提供分号结尾
            String sql = "update class set cid=4,caption='你好吗' where cid = 3";
            //专门执行DM江语句的(insert delete update)
            // 返回值是"影响数据库中的记录条数"
            int count = statement.executeUpdate(sql) ;
            System.out.println (count == 1 ?"删除成功":"删除失败");

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            //为了保证资源一定释放 在finally语句块中释放资源
            //必须遵循从小到大依次关闭
            //分别对其try catch
            if (statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

  • 实例3: 查询语句.别着急啊 在下面呢 往下翻呀!

注册驱动的两种方式

在上面的实例中已经写出了一种:

  • 第一种:
      DriverManager.registerDriver(new com.mysql.jdbc.Driver());//多态 父类型指向子类型对象
    
  • 第二种(常用的):
    • 为什么这种方式常用?因为参数是一个字符串,字符串可以写到xxx.properties文件中。
    • 以下方法不需要接收返回值,因为我们只想用它的类加载动作。
    Class.forName("com.mysql.jdbc.Driver");
    

处理查询结果集

  • 实例3:查询语句!
    处理查询结果集也称为遍历结果集,话不多说上代码:
package com.buba.JDBC;

import java.sql.*;

public class JDBCTest04 {
    public static void main(String[] args)  {
        Statement statement = null;
        Connection conn = null;
        ResultSet rs = null;
        try {
            //1.注册驱动
            Driver driver = new com.mysql.jdbc.Driver();//多态 父类型指向子类型对象
            DriverManager.registerDriver(driver);
            //2.获取连接
            String url = "jdbc:mysql://127.0.0.1:3306/text1?serverTimezone=Asia/Shanghai";
            String user = "root";
            String password = "root";
            conn = DriverManager.getConnection(url,user,password);
            System.out.println("数据库连接对象="+conn);
            //3.获取数据库操作对象(statement专门执行SQL语句的)
            statement = conn.createStatement();
            //4.执行SQL语句
            //   int       executeUpdate(insert delete update)
            //  ResultSet  executeQuery(select)
            String sql = "select  * from class";
            rs = statement.executeQuery(sql); //专门执行DQL语句的方法,
            //5.处理查询结果集
                //如果为真 说明光标指向的行有数据
                //取数据
                //getString()方法的特点是,不管数据库中的数据是什么类型,都已String形式取出
                //以下程序说的 1 2 3是第几列
                while(rs.next()){
                    //String cid = rs.getString(1); //jdbc中所有的下标从1开始.不是从0开始
                    //String caption = rs.getString(2);
                    //System.out.println(cid+","+caption);
                    //以下这个不是以下标获取  而是通过查询语句的列名获取
                    String cid = rs.getString("cid");
                    String caption = rs.getString("caption");
                    System.out.println(cid+","+caption);

                }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}

  • 图解:
    在这里插入图片描述

SQL注入

导致SQL注入的根本原因是什么?
  • 用户输入的信息中含有sql语句的关键字,并且这些关键字参与sql语句的编译过程,导致sql语句的原意被扭曲,进而达到sql注入。
怎么解决SQL注入问题?
  • 只要用户提供的信息不参与SQL的编译过程 问题就解决了
  • 即使用户提供的信息中含有SQL语句的关键字 但是不参与编译,就不会起作用
  • 要想用户信息不参与SQL语句的编译 必须使用Java.sql.PreparedStatement
  • PreparedStatement接口继承了java.sql.Statement
  • PreparedStatement是属于预编译的数据库操作对象
  • PreparedStatement的原理是,预先对SQL语句的框架进行编译,然后再给SQL语句传"值";

实例:

class JDBCTest05 {
    public static void main(String[] args) {
        // 初始化界面
        Map<String,String> userLoginInfo = initUI();
        // 验证用户名和密码
        boolean loginSuccess = login(userLoginInfo);
        // 输出最后结果
        System.out.println(loginSuccess ? "登录成功" : "登录失败");
    }

    /**
     * 用户登录
     * @param userLoginInfo 用户登录信息
     * @return true表示登录成功,false表示登录失败
     */
    private static boolean login(Map<String, String> userLoginInfo) {
        boolean loginSuccess = false;
        //自定义变量
        String username = userLoginInfo.get("username");
        String password = userLoginInfo.get("password");
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // 1、注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2、获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/text1?serverTimezone=Asia/Shanghai","root","root");
            // 3、获取预编译的数据库操作对象
            //SQL语句的框子  其中一个?代表一个占位符 一个?将来接收一个"值".注意: 占位符不能引用单引号括起来
            String sql = "select * from login where username = ? and password = ?";
            //程序执行到此处,会发送sql语句框子给DBMS,然后DBMS进行sql语句的预先编译。
            ps = conn.prepareStatement(sql);
            //给占位符?传值(第1个问号下标是1,第2个问号下标是2,JDBC中所有下标从1开始。)
            ps.setString(1,"123");
            ps.setString(2,"123");
            // 4、执行sql语句
            rs = ps.executeQuery();
            // 5、处理结果集
            if(rs.next()) {
                loginSuccess = true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            // 6、释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return loginSuccess;
    }


    /**
     * 初试化界面
     * @return 用户输入的用户名和密码等登录信息
     */
    private static Map<String, String> initUI() {
        Scanner s = new Scanner(System.in);

        System.out.print("请输入用户:");
        String userName = s.nextLine();
        System.out.print("请输入密码:");
        String userPassword = s.nextLine();

        Map<String,String> userLoginInfo = new HashMap<>();
        userLoginInfo.put("userName",userName);
        userLoginInfo.put("userPassword",userPassword);

        return userLoginInfo;
    }
}

测试结果:
请输入用户:123
请输入密码:456or1= 1
登录失败

解决SQL注入的关键问题是什么?
  • 用户提供的信息中即使含有sql语句的关键字,但是这些关键字并没有参与编译。不起作用

本节完

C3P0数据库连接池

Druid

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值