• JDBC 入门


    1. JDBC 简介

    • JDBC (Java DataBase Connectivity) 就是 Java 数据库连接, 说白了就是用 Java 语言向
      数据库发送 SQL 语句.
    • JDBC 其实是访问数据库的规范(就是一组接口). 而驱动就是该接口的实现类.

    2. java 代码操作数据库步骤:

    - 导 jar 包: 驱动!! mysql 对应的是 `mysql-connector-java`
    - 加载驱动类: `Class.forName('类名');`
    - 给出 url, username, password;
    - 使用 DriverManager 类得到 Connection 对象.
    - 需要声明两个异常: `ClassNotFoundException` 和 `SQLException`.
    
    public class Demo{
    
        /*
         * 连接数据库, 得到 Connection 对象
         * 对数据库进行增, 删, 改
         *
         */
    
         public void fun() throws ClassNotFoundException, SQLException{
                // 加载驱动类(注册驱动)
                Class.forName("com.mysql.jdbc.Driver");
                    /*
                     * 与下面代码等同
                     *    com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
                     *    DriverManager.registerDriver(driver);
                     *
                     *  每种数据库的驱动都需要实现 java.sql.Driver 接口.
                     *  Class.forName 用来加载一个类,在加载类的过程中, 会执行该类的静态代码块.
                     *  所有的 java.sql.Driver 实现类, 都提供了静态代码块, 块内的代码就是把
                     *  自己注册到 DriverManager 中.
                     *
                     *  jdbc 4.0 之后, 每个驱动 jar 包中, 在 META-INF/services 目录下提供了
                     *  一个名为 java.sql.Driver 的文件, 文件的内容就是 java.sql.Driver 的实现类名称.
                     *  
                     */
    
                 // jdbc 协议的格式, jdbc:厂商的名称:子协议(由厂商自己来规定)
                 // 对 MySql 而言, 它的子协议结构: //主机:端口号/数据库名称
                 String url = "jdbc:mysql://localhost:3306/mydb1";
    
                 // 数据库用户名和密码
                 String username = "root";
                 String password = "root";
    
                 // 使用 DriverManager, 得到 Connection. 需要导入 java.sql.Connection 包
                 Connection con = DriverManager.getConnection(url,username,password);
    
            /*
            *  对数据库做增, 删, 改
            *     1. 通过 Connection 对象得到 Statement 对象, 它的功能是向数据库发送 sql 语句.
            *     2. 调用它的 int executeUpdate(String sql), 发送 DML, DDL 语句.
            */
                 // java.sql.Statement 包
                  Statement stmt = con.createStatement();
    
                  // 向数据库中添加数据
                  String sql = "INSERT INTO stu VALUES(1113,'zhangsan',24,'male')";
    
                  // 返回值为 int 类型, 表示 sql 语句所影响的行数
                  int r = stmt.executeUpdate(sql);
    
            /*
             * 执行查询
             *    1. 得到 Connection 对象
             *    2. 得到 Statement 对象,发送 select 语句
             *       调用 Statement 对象的 ResultSet rs = stmt.executeQuery(String querySql);
             *    3. 对查询返回的"表格"进行解析!
             *       返回的"表格" rs, 有两个虚拟的位置: beforeFirst, afterLast
             *       rs 的内部有一个行光标, 默认位置为 beforeFirst.
             *       ResultSet 的 next() 方法可以把光标向下移动一行.
             *       next() 返回 boolean 类型的值, 表示当前行是否存在.
             *       ResultSet 提供了一系列的 getXxxx() 方法, 获取某一列中的数据.
             *                 其中, getString() 和 getObject() 两个方法较为常用.
             *         JavaSE  java.sql.ResultSet 包
             */
    
                 // 查询 t_stu 表格
                 String sql2 = "SELECT * FROM t_stu";
                 ResultSet rs = stmt.executeQuery(sql2);
    
                 // 解析"表格"
                 while(rs.next()){
                    String name = rs.getString("sname");
                    int age = rs.getInt("age");
                    String gender = rs.getString("gender");
    
                    System.out.println(name+','+age+','+gender);
                }
                
                /*
                 * 如果不知道列的内容, 还可以使用下面的方法获取
                 *
                 *  获取列数
                 * int count = rs.getMetaData().getColumnCount();
                 * while(rs.next()){
                 *      for(int i=1; i<=count; i++){
                 *            获取列中的数据
                 *            System.out.print(rs.getObject(i));
                 *            如果不是一行结尾, 则在每个列后面加逗号
                 *            if(i<count){
                 *                System.out.print(", ");
                 *            }
                 *        }  
                 *       每一行之后, 换行
                 *       System.out.println();
                 * }
                 */
    
            // 关闭资源
            // 倒关: 先得到的对象后关闭, 后得到的对象先关闭.
            rs.close();
            stmt.close();
            con.close(); // 这个东西必须关闭!!
       }
    }
    

    3. JDBC 之代码规范化

    1. 所谓规范化代码就是无论是否出现异常, 都要关闭 ResultSet, Statement 以及 Connection.
    public void query(){
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
    
        try{
            con = DriverManager.getConnection();
            stmt = con.createStatement();
    
            String sql = "SELECT * FROM user";
            rs = stmt.executeQuery(sql);
    
            while(rs.next()){
                String username = rs.getString(1); // 获取第一列的值, 参数为列编号或列名
                String password = rs.getString(2); // 获取第二列的值
                System.out.println(username+","+password);
            }
        } catch(Exception e){
            throw new RuntimeException(e);
        } finally{
            try{
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            } catch(SQLException e){
                throw new RuntimeException(e);
            }
        }
    }
    

    4. JDBC 对象介绍

    • JavaSE 文档中 java.sql 目录下

    1. DriverManager

    2. Connection 对象

    • 主要用来获取 Statement 对象: Statement stmt = con.createStatement();

    3. Statement 对象

    • int executeUpdate(String sql); 执行更新操作, 即执行 insert, update, delete 语句.
      返回 int 类型, 表示 SQL 操作影响的行数.
    • ResultSet executeQuery(String sql); 执行查询操作, 返回 ResultSet.
    • boolean execute(); 可以用来执行增, 删, 改, 查所有 SQL 语句. 返回的是 boolean 类型,
      表示 SQL 语句是否有结果集.

    4. ResultSet 之滚动结果集

    • ResultSet 表示结果集, 它是一个二维的表格! ResultSet 内部维护一个行光标, Result 提供了一系列的
      方法来移动光标.
    • 其他数据库默认的结果集不可滚动,不敏感, 不可更新!! 只能使用 next() 方法来移动光标.
      MySql 获得的默认结果集是可滚动.
    • ResultSet 提供了一系列的 getXxx() 方法, 来获取某一列中的数据.
      其中, getString() 和 getObject() 两个方法较为常用, 参数为列编号或列名.
    • 当使用 Connection 的 createStatement 时, 已经确定了 Statement 生成的结果集是什么特性!
    • 结果集特性: 是否可滚动, 是否敏感, 是否可更新!

    5. 获取列相关的内容

    • 获取结果即元数据: rs.getMetaData(); 返回值为 ResultSetMetaData();
    • 获取结果集列数: int getColumnCount();
    • 获取指定列的列名: String getColumnName(int colIndex);

    5. PreparedStatement 接口

    1. 它是 Statement 接口的子接口.
    2. 它的强大之处:
    • 防 SQL 攻击
    • 提高代码的可读性, 可维护性
    • 提高效率
    3. 使用步骤:
    • 给出 SQL 模板!! 即 SQL 语句中所有的参数使用问号来替代!
    • 调用 Connection 的 PreparedStatement prepareStatement(String sql模板);
    • 调用 pstmt 的 setXxx() 系列方法, 为 SQL 模板中的 "?" 赋值.
    • 调用 pstmt 的 executeUpdate() 或 executeQuery(), 注意, 这两个方法都不需要参数.
    // 示例:查询表中的姓名为张三, 年龄为24 的详细信息
    
        // 给出 SQL 模板
        String sql = "SELECT * FROM t_user WHERE username=? AND age=?";
    
        // 获取 PreparedStatement 对象, 注意 con.prepareStatement, 为 prepare
        PreparedStatement pstmt = con.prepareStatement(sql);
    
        // 为参数赋值
        pstmt.setString(1,"张三"); // 给第一个问号赋值, 值为 "张三"
        pstmt.setInt(2,24); // 给第二个问号赋值, 值为 24, 不需要使用引号.
    
        // 向数据库发送查询语句
        ResultSet rs = pstmt.executeQuery();
    
    4. 预处理的原理
    1. 服务器执行 sql 语句,需要执行的工作:
    • 校验 sql 语句的语法!
    • 编译: 将 sql 语句变成一个与函数相似的东西.
    • 执行: 相当于调用函数.
    2. PreparedStatement
    • 使用该接口的前提: 连接的数据库必须支持预处理! 几乎没有不支持的.
    • 每个 pstmt 都与一个 sql 模板绑定在一起, 先把 sql 模板给数据库, 数据库进行校验.
      再进行编译, 执行时,只是把参数传递过去而已!
    • 若二次执行时,就不用再次校验语法, 也不用再次编译! 直接执行!

    6. MySql 的预处理

    • MySql 的预处理功能默认是关闭的,需要自己手动打开.

    参考资料:

  • 相关阅读:
    地区表设计(包括数据插入) Dear
    本博客的内容
    linux msn
    相关的一些技术
    相关的一些产品
    考第一名的学生的发言
    AIX&LINUX操作系统调优
    shell for循环
    自动化测试
    DB2数据库日志
  • 原文地址:https://www.cnblogs.com/linkworld/p/7617937.html
Copyright © 2020-2023  润新知