zoukankan      html  css  js  c++  java
  • 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 的预处理功能默认是关闭的,需要自己手动打开.

    参考资料:

  • 相关阅读:
    图书管理系统---基于form组件和modelform改造添加和编辑
    Keepalived和Heartbeat
    SCAN IP 解释
    Configure Active DataGuard and DG BROKER
    Oracle 11gR2
    我在管理工作中積累的九種最重要的領導力 (李開復)
    公募基金公司超融合基础架构与同城灾备建设实践
    Oracle 11g RAC for LINUX rhel 6.X silent install(静默安装)
    11gR2 静默安装RAC 集群和数据库软件
    Setting Up Oracle GoldenGate 12
  • 原文地址:https://www.cnblogs.com/linkworld/p/7617937.html
Copyright © 2011-2022 走看看