zoukankan      html  css  js  c++  java
  • JDBC详解(一)

    一.相关概念介绍

      1.1.数据库驱动

      这里驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道理,我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道。其实也就是数据库厂商对JDBC接口的实现,即对Connection,ResultSet,Statement等接口的实现类的jar文件。如下所示:

      

      1.2.JDBC介绍

      SUN公司为了简化,统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC。这套接口由数据库厂商去实现,这样,开发人员只需要学习jdbc接口,并通过jdbc加载具体的驱动,就可以操作数据库。如下图所示:

      

      JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成。组成JDBC的2个包:java.sql(如Connection,ResultSet,Statement);javax.sql,这两个包是由JDK提供的。

      开发JDBC应用需要以上两个包的支持以外,还需要导入JDBC的数据库实现(即数据库驱动,这个主要是由数据库厂商提供和开发的),如sqljdbc4-4.0.jar;mysql-connector-java-5.0.8-bin.jar等。

    二.常用接口

      2.1.Driver接口

      Driver接口由JDBC提供,作为java开发人员,只需要使用Driver接口就可以了。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的数据库驱动,因此装载方法也会有所不同。如:

      装载mysql驱动:Class.forName("com.mysql.jdbc.Driver");

      装载Oracle驱动:Class.forName("oracle.jdbc.driver.OracleDriver");

      装载sqlserver驱动:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

      总结:此接口我们一般不使用,都是不通的厂商驱动实现类去实现JDK的java.sql包中的Driver接口。下面以mysql的驱动类:com.mysql.jdbc.Driver来看一下源码:

      

      从这里可以看出,mysql的驱动类Driver实现了JDBC定义的接口Driver。然后静态代码块中将此驱动注册到DriverManager类中。后面会详细聊一下这部分。

      2.2.Connection接口

      Connection与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定义的数据库Connection连接上。

      连接mysql数据库:Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database","user","password");

      连接Oracle数据库:Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user", "password");

      连接SqlServer数据库:Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database", "user", "password");

      常用方法:

      createStatement():创建向数据库发送sql的statement。

      如:Connection conn = DriverManager.getConnection(url,user,password);

        Statement stmt = conn.createStatement();

        ResultSet rs = stmt.executeQuery(sql); 

      prepareStatement(sql):创建向数据库发送预编译sql的prepareStatement对象。

      如:String sql = "insert into user(name,pwd) values(?,?);

        Connection conn = DriverManager.getConnection(url,user,password);

        PrepareStatement ps = conn.prepareStatement(sql);

        ps.setString(1,"tom");

        ps.setString(2,"123456");

        ResultSet rs = ps.executeQuery();

      prepareCall(sql):创建执行存储过程的callableStatement对象。

      如:String execSql = "call SMSP_ListDevices(?,#PageIndex#,1000,'',0,'{#key#}')"

        Connection conn = DriverManager.getConnection(url,user,password);

        CallableStatement call = conn.prepareCall("{"+execSql+"}",ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);

        call.registerOutParameter(outParamName,Types.BIGINT);

        ResultSet rs = call.execute();

      setAutoCommit(boolean autoCommit):设置事务是否自动提交

      commit():在连接上提交事务。

      rollback():在连接上回滚事务。

      2.3.Statement接口

      用于执行静态sql语句并返回它所生成结果的对象。

      三种Statement类型的接口

      Statement:由conn.createStatement()创建,用于发送简单的SQL语句(不带参数)。

      PrepareStatement:继承自Statement接口,由conn.prepareStatement()创建,用于发送含有一个或多个参数的SQL语句。PrepareStatement对象比Statement对象的效率更高,并且可以防止SQL中注入,所以我们一般使      PrepareStatement。

      CallableStatement:继承自PrepareStatement接口,由conn.prepareCall()创建,用于调用存储过程。

       Statement常用的方法:

      execute(String sql):运行语句,返回是否有结果集。

      executeQuery(String sql):运行select语句,返回RequestSet结果集。

      executeUpdate(String sql):运行insert/update./delete操作,返回影响的行数。

      addBatch(String sql):把多条sql语句放到一个批处理中。

      2.4.ResultSet接口

       ResultSet提供检索不同类型字段的方法,常用的有:

      getString(int index),getString(String columnName):获得在数据库里varchar,char等类型的数据对象。

      getFloat(int index),getFloat(String columnName):获得在数据库里Float类型的数据对象。

      getDate(int index),getDate(String columnName):获得在数据库里Date类型的数据。

      getBoolean(int index),getBoolean(String columnName):获得在数据库里Boolean类型的数据。

      getObject(int index),getObject(String columnName):获得数据库里任意类型的数据。

      ResultSet还提供了对结果集进行滚动的方法:

      next():移动到下一行。

      previous():移动到前一行。

      absolute(int row):移动到指定行。

      beforeFirst():移动到ResultSet的最前面。

      afterLast():移动到ResultSet的最后面。

      使用后依次关闭的对象及连接是:ResultSet->Statement->Connection。(实际中跟申明的顺序相反)

    三.使用JDBC的步骤

      加载JDBC驱动程序→建立数据库连接Connection→创建执行SQl的语句Statement→处理执行结果Result→释放资源。

      3.1.注册驱动(只做一次)

       方式一:Class.forName("com.mysql.jdbc.Driver");

      推荐使用这种方式,不会对具体的驱动类产生依赖。

      方式二:DriverMaager.registerDriver("com.mysql.jdbc.Driver");

      会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。

      3.2.建立连接

      Connection conn = DriverManager.getConnection(url,user,password);

      url用于标识数据库的位置,通过url地址告诉JDBC连接的是哪个数据库,url写法:

      

      其他参数如:useUnicode=true&characterEncoding=utf8等。

      3.3.创建执行SQL语句的Statement

      

      存在sql注入的危险,如果用户传入的id为“5 or 1=1”,那么将删除表中的所有记录。那么建议用下面这种写法较合适:

      

      PreparedStatement有效的防止sql注入(SQl语句在程序运行前已经进行了预编译,当运行时动态的把参数传给PreparedStatement时,及时参数里有敏感字符如:“or 1=1”,数据库也会作为一个字段的属性值来处理而不会作为一个SQL指令)

      3.4.处理执行结果

      ResultSet rs = ps.executeQuery();

      while(rs.next()){

        rs.getString("col_name");

        rs.getInt(1);

        //...

      }

      3.5.释放资源

      

    四.事物(ACID特点,隔离级别,提交commit,回滚rollback)

      3.1.事物的基本概念

      一组要么同时执行成功,要么同时执行失败的SQL语句。是数据库操作的一个执行单元。

      事物开始于:连接到数据库上,并执行一条DML语句(INSERT,DELETE或UPDATE)。前一个事物结束后,又输入了另外一条DML语句。

      事务结束于:

      执行commit或rollback语句。

      执行一条DDL语句(data definition language:主要的命令有CREATE、ALTER、DROP等),例如CREATE TABLE语句;在这种情况下,会自动执行commit语句。

      执行一条DCL语句(Data Control Language:是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句),例如GRANT语句;在这种情况下,会自动执行commit语句。

      断开与数据库的连接。

      执行一条DML(data manipulation language:它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言。)语句,该语句失败了;在这种情况下,会为这个无效的DML语句执行      rollback语句。

      3.2.事务的四大特点(ACID)

      ✔atomicity(原子性)

      表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败。

      ✔consistency(一致性)

      表示一个事务内有一个操作失败时,所有更改过的数据都必须回滚到修改前的状态。

      ✔isolation(隔离性)

       事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是修改它之后的状态,事务不会查看中间状态的数据。

      ✔durability(持久性)

      持久性事务完成之后,他对系统的影响是永久性的。

      3.3.事务的隔离级别

      ✔读取未提交

      ✔读取已提交

      ✔可重复读

      ✔序列化

      关于JDBC的的一些实战例子,我将放在JDBC详解(二)http://www.cnblogs.com/vanl/p/7495864.html里面来描述。

  • 相关阅读:
    Leetcode 15 3Sum
    Leetcode 383 Ransom Note
    用i个点组成高度为不超过j的二叉树的数量。
    配对问题 小于10 1.3.5
    字符矩阵的旋转 镜面对称 1.2.2
    字符串统计 连续的某个字符的数量 1.1.4
    USACO twofive 没理解
    1002 All Roads Lead to Rome
    USACO 5.5.1 求矩形并的周长
    USACO 5.5.2 字符串的最小表示法
  • 原文地址:https://www.cnblogs.com/vanl/p/5766000.html
Copyright © 2011-2022 走看看