zoukankan      html  css  js  c++  java
  • JDBC 详解

    工作原理流程:装载驱动程序---->获得数据库连接---->使用Statement或PreparedStatement执行SQL语句---->

                  返回执行的结果---->关闭相关的连接

    JDBC 原理浅析
    一.本节目的:
    了解JDBC的概念及工作原理
    写在详解前
    对JAVA基础知识的回顾:
    JAVA接口:
    是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,
    因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
    通过接口可以实现不相关的类的相同行为.
    通过接口可以指明多个类需要实现的方法.
    通过接口可以了解对象的交互方法而不需要了解对象所对应的类.
    二.JDBC 概念:
         什么是JDBC?
         通俗地说:JDBC是java和关系数据库的之间的桥梁;
         根据"百科名片"所描述:
         JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。
    三.JDBC组成:
        JDBC有两部分组成:JDBC API和JDBC Driver Interface.
        JDBC API:是提供给开发者的一组独立于数据库的API,对任何数据库的操作,都可以用这组API来进行.那么要把这些通用的API翻译成特定数据库能懂的"指令",就要由JDBC Driver Interface来实现了;
        JDBC Driver Interface 是面向JDBC驱动程序开发商的编程接口,它会把我们通过JDBC API发给数据库的通用指令翻译给他们自己的数据库.
        为了使客户端程序独立于特定数据库驱动程序,JDBC规范建议开发者使用接口编程方式,即尽量使应用依赖java.sql 及javax.sql中的接口和类.
       如下图:

    JDBC的工作原理

    四.JDBC驱动程序类型:
        <1>.JDBC-ODBC桥加ODBC驱动程序:需要ODBC驱动,适合于企业网或三层结构应用程序(通过将JDBC调用委托给ODBC接口)
        <2>.本地API:需要驱动程序的二进制代码支持(一部分java编写,一部分委托给数据库客户端代码实现)
        <3>.JDBC网络纯java驱动程序:将JDBC转换为与DBMS无关的网络协议,又被某服务器转换为一种DBMS协议,以操作各种数据库(驱动程序由中间件服务器提供)
        <4>.本地协议纯java驱动程序:将JDBC调用直接转换成JDBC所使用的网络协议 (全部由JAVA实现,直接和数据库访问)
    五.详解JDBC原理:
    <1>. 结构:
     DriverManager (桥接模式)
        |
     Dirver  (是驱动程序对象的接口,指向具体数据库驱动程序对象=DriverManager.getDriver(String URL))
        |
     Connection (是连接对象接口,指向具体数据库连接对象=Drivermanager.getConnection(String URL))
        |
     Statement (执行静态SQL语句接口,=Connection.CreateStatement())
        |
     ResultSet  (是指向结果集对象的接口,=Statement.excuteXXX())
    <2>.工作原理:
    1.装载驱动程序:(实例化时自动向DriverManager注册(DriverManager.registerDriver())
     <1>.Class.forName(driver)
          <2>.Class.forName(driver).newInstance()
           <3>.new driver()
    2.取得数据库连接(Connect to the DataBase)
     <1>.用DriverManager取数据库连接
         Connection cn = DriverManager.getConnection(url,uid,pwd);
     <2>.用jndi(java的命名和目录服务)方式:多用于jsp
         Context ctx = (Context) new InitialContext().lookup("java:comp/env");
                   DataSource ds = (DataSource) ctx.lookup(jndi);
         Connection cn = ds.getConnection();
    3.执行sql语句(Execute the SQL)
     <1>.用Statement来执行sql语句(主要是不带参的SQL)
                   Statement sm = cn.createStatement();
         sm.executeQuery(sql); // 执行数据查询语句(select)
         sm.executeUpdate(sql); // 执行数据更新语句(delete、update、insert、drop等)
     <2>.用PreparedStatement来执行sql语句(带参SQL)
         String  sql  = "insert into CUSTOMER(id,name) values (?,?)";
                   PreparedStatement ps = cn.prepareStatement(sql);
                  ps.setInt(1,xxx);
                   ps.setString(2,xxx);
                  ...
                  ResultSet rs = ps.executeQuery(); // 查询
                  int c = ps.executeUpdate(); // 更新
     <3>.用PreparedStatement来执行sql语句(批量更新或删除SQL)
         PreparedStatement pstmt  =  con.prepareStatement("UPDATE EMPLOYEES  SET SALARY = ? WHERE ID = ?");
            for(int i =0;i<length;i++){
                     pstmt.setBigDecimal(1, param1[i]);
                     pstmt.setInt(2, param2[i]);
                     pstmt.addBatch();
             }
             pstmt. executeBatch();
     <4>.用CallablePrepareStatement来调用存储过程
         CallableStatement cstmt = con.prepareCall("{call getTestData(?, ?)}");
         cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
         cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3);
         cstmt.executeQuery();
         byte x = cstmt.getByte(1);
         java.math.BigDecimal n = cstmt.getBigDecimal(2, 3);

    4.事务的处理(JDBC的事务处理简单,在执行多条更新语句后,加cn.commit()或cn.rollback()就可以)
     <1>.关闭Connection的自动提交
         connection.setAutoCommit(false);

     <2>.执行一系列sql语句:执行新sql前,以前的Statement(或PreparedStatemet)须close
         Statement sm ;
               sm = cn.createStatement(insert into user...);
               sm.executeUpdate();
               sm.close();
               sm = cn.createStatement("insert into corp...);
               sm.executeUpdate();
               sm.close();

     <3>.提交
         cn.commit();
     <4>.如果发生异常,回滚:
         cn.rollback();
    5.处理执行结果:
     <1>.查询语句,返回记录集ResultSet
     <2>.更新语句,返回数字,表示该更新影响的记录数(0,表示未更新,-1表示更新失败)
     <3>.ResultSet的方法:while(re.next())
             next(),将游标往后移动一行,如果成功返回true;否则返回false
             getInt("id")或getSting("name"),返回当前游标下某个字段的值
    6.关闭数据库连接
     rs.close();
     ps.close(); /stat.close();
     con.close();
    完!!!

  • 相关阅读:
    求循环小数
    Android中Intent的用法总结
    Java中@Override的作用
    三种继承方式和访问控制方式对子类成员的影响
    设计一个用于人事管理的People(人员)类
    QSort函数对不同类型数据快速排序浅谈
    QSQLITE 使用
    c++控制内存分配
    dll加载过程全局变量会先初始化
    二维数组
  • 原文地址:https://www.cnblogs.com/sdream/p/5163999.html
Copyright © 2011-2022 走看看