• JDBC使用详解


    一、概述

      1、什么是JDBC  

       JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统(DBMS)、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,使用这个类库可以以一种标准的方法、方便地访问数据库资源JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。

         

      2、JDBC API  

        JDBC API是一系列的接口,它统一和规范了应用程序与数据库的连接、执行SQL语句,并到得到返回结果等各类操作。声明在java.sql与javax.sql包中

        

      3、环境准备:引入JDBC驱动程序

        1)驱动程序由数据库提供商提供下载。 MySQL的驱动下载地址:http://dev.mysql.com/downloads/
        2)在Java Project项目应用中添加数据库驱动jar:把jar拷贝到项目中目录中lib

          

        3)添加到项目的类路径下在驱动jar上右键-->Build Path-->Add to Build Path
          

    二、JDBC详细步骤

       1、加载并注册驱动:

          1)加载驱动,把驱动类加载到内存
               注册驱动,把驱动类的对象交给DriverManager管理,用于后面创建连接等使用。

          2)调用Class类的静态方法forName(),向其传递要加载的JDBC驱动的类名

           //通过反射,加载与注册驱动类,解耦合(不直接依赖)
           Class.forName("com.mysql.jdbc.Driver");

        2、获取数据库连接:DriverManager.getConnection()

         1) 可以通过 DriverManager 类建立到数据库的连接Connection,DriverManager试图从已注册的JDBC驱动程序集中选择一个适当的驱动程序。
            public static Connection getConnection(String url)
                    public static Connection getConnection(String url,String user, String password)
                    public static Connection getConnection(String url,Properties info)其中Properties info通常至少应该包括 "user" 和 "password" 属性

        2)JDBC URL用于标识一个被注册的驱动程序,驱动程序管理器通过这个URL选择正确的驱动程序,从而建立到数据库的连接。JDBC URL的标准由三部分组成,各部分间用冒号分隔。
          jdbc:<子协议>:<子名称>
                   ① 协议:JDBC URL中的协议总是jdbc
                   ② 子协议:子协议用于标识一个数据库驱动程序
                   ③ 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息
                   

        3)常用数据库URL地址的写法:
        Oracle:jdbc:oracle:thin:@localhost:1521:库名
        SqlServer:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=库名
        MySql:jdbc:mysql://localhost:3306/库名

        4)Connection()对象的常用方法:

    方法 描述
    createStatement() 创建向数据库发送sql的statement对象
    prepareStatement(sql) 创建向数据库发送预编译sql的PrepareSatement对象
    prepareCall(sql) 创建执行存储过程的callableStatement对象
    setAutoCommit(boolean autoCommit) 设置事务是否自动提交
    commit() 在连接上提交事务
    rollback() 在此连接上回滚事务

      3、执行增删改查:

       1)PreparedStatement vs Statement

         ① 代码的可读性和可维护性. Statement的sql拼接是个难题。

         ② PreparedStatement 可以防止SQL注入

         ③ PreparedStatement 可以处理Blob类型的数据

         ④ PreparedStatement 能最大可能提高性能:(Oracle和PostgreSQL8是这样,但是对于MySQL不一定比Statement高)

        2)PreparedStatement概述:可以通过调用Connection对象的preparedStatement(String sql)方法获取PreparedStatement对象

         ① PreparedStatement接口是Statement的子接口,它表示一条预编译过的SQL语句

           ② PreparedStatement对象所代表的SQL语句中的参数用问号(?)来表示,调用PreparedStatement对象的setXX()方法来设置这些参数. setXX()方法有两个参数,第一个参数是要设置的SQL语句中的参数的索引(从 1 开始),第

    二个SQL语句中的参数的值。若不清楚数据的类型,则直接使用setObject()方法

          setXX(占位符索引,占位符的值):设置对应索引的占位符的值,类型为XX类型

          setObject(占位符索引,占位符的值):设置对应索引的占位符的值,类型为Object类型

     1 @Test
     2     public void add() throws Exception {
     3         Scanner input = new Scanner(System.in);
     4         System.out.println("请输入用户名:");
     5         String name = input.nextLine();
     6         
     7         System.out.println("请输入密码:");
     8         String gender = input.nextLine();
     9         
    10         //1、加载并注册驱动
    11         Class.forName("com.mysql.jdbc.Driver");
    12         
    13         //2、建立数据库连接
    14         String url = "jdbc:mysql://localhost:3306/girls";
    15         String user = "root";
    16         String password = "";
    17         Connection conn = DriverManager.getConnection(url, user, password);
    18 
    19         //3、编写带?的SQL
    20         String sql = "INSERT INTO admin VALUES(null,?,?)";
    21         
    22         //4、实例化PreparedStatement,对带?的sql进行预编译
    23         PreparedStatement Statement = conn.prepareStatement(sql);
    24 
    25         //5、把?用具体的值进行代替
    26         Statement.setString(1, name);
    27         Statement.setObject(2, gender);
    28 
    29         //6、执行sql
    30         int len = Statement.executeUpdate();
    31         System.out.println(len>0?"添加成功":"添加失败");
    32 
    33         //7、释放资源
    34         Statement.close();
    35         conn.close();
    36         input.close();
    37     }
    View Code

         ③ Statement对象常用方法:

    方法 含义
    executeQuery(String sql) 用于向数据发送查询语句
    executeUpdate(String sql) 用于向数据库发送insert、update或delete语句
    execute(String sql) 用于向数据库发送任意sql语句
    addBatch(String sql) 把多条sql语句放到一个批处理中
    executeBatch() 向数据库发送一批sql语句执行

         ④ int executeUpdate():执行更新,包括增、删、改,返回受影响的行数

         ⑤ ResultSet executeQuery():执行查询,并返回该查询生成的ResultSet对象。

          ResultSet对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet接口由数据库厂商实现;ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next()方法,可以使

    游标指向具体的数据行,进行调用方法获取该行的数据。

           A、获取行:ResultSet提供了对结果集进行滚动的方法:

            next():移动到下一行

            Previous():移动到前一行

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

                        beforeFirst():移动resultSet的最前面。

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

         B、获取值:ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:

          获取任意类型的数据:  

            getObject(int index):通过索引

            getObject(string columnName):通过列名,若sql语句中使用了AS关键字重命名列名,则使用重命名后的列名

          获取指定类型的数据,如获取字符串类型的数据:

            getString(int index)

            getString(String columnName)

     1 @Test
     2     public void select() throws Exception {
     3         
     4         Scanner input = new Scanner(System.in);
     5         System.out.println("请输入姓名:");
     6         String name = input.nextLine();
     7         
     8         //1、加载并注册驱动
     9         Class.forName("com.mysql.jdbc.Driver");
    10         
    11         //2、建立数据库连接
    12         String url = "jdbc:mysql://localhost:3306/girls";
    13         String user = "root";
    14         String password = "";
    15         Connection conn = DriverManager.getConnection(url, user, password);
    16 
    17         //3、编写带?的sql
    18         String sql = "SELECT id,username,password FROM admin WHERE username = ?";
    19                 
    20         //4、把带?的sql语句进行预编译
    21         PreparedStatement statement = conn.prepareStatement(sql);
    22 
    23         //5、把?用具体的变量的赋值
    24         statement.setString(1, name);
    25 
    26         //6、执行查询sql
    27         ResultSet set = statement.executeQuery();
    28         while (set.next()) {
    29             
    30             int id = set.getInt("id");
    31             String username = set.getString("username");
    32             Object pwd = set.getObject("password");
    33 
    34             System.out.println(id + "	" + username + "	" + pwd);
    35         }
    36 
    37         // 6、释放资源
    38         set.close();
    39         statement.close();
    40         conn.close();
    41         input.close();
    42     }
    View Code

      4、释放资源:ResultSet.close()、statement.close()、connection.close()

        JDBC程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象。

          注意:为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。

    三、封装JDBCUtils

      1、封装类

     1 public class JDBCUtils {
     2     
     3     static String user;
     4     static String password;
     5     static String url;
     6     static String driver;
     7     
     8     //代码块
     9     static{
    10         try {
    11             //读取配置文件
    12             Properties info = new Properties();
    13             info.load(new FileInputStream("src\jdbc.properties"));
    14             user = info.getProperty("user");
    15             password = info.getProperty("password");
    16             url = info.getProperty("url");
    17             driver = info.getProperty("driver");
    18             //1.注册驱动
    19             Class.forName(driver);
    20         } catch (Exception e) {
    21             //将编译异常转换为运行异常
    22             throw new RuntimeException(e);
    23         }
    24     }
    25     /**
    26      * 功能:获取可用的连接对象
    27      * @return 连接
    28      * @throws Exception
    29      */
    30     public static Connection getConnection(){
    31         
    32         try {
    33             return DriverManager.getConnection(url, user, password);
    34         } catch (Exception e) {
    35             throw new RuntimeException(e);
    36         }
    37     }
    38     /**
    39      * 功能:释放资源
    40      * @param set
    41      * @param statement
    42      * @param connection
    43      * @throws Exception
    44      */
    45     public static void close(ResultSet set,Statement statement,Connection connection){
    46         try {
    47             if (set!=null) {
    48                 set.close();
    49             }
    50             if (statement!=null) {
    51                 statement.close();
    52             }
    53             if (connection!=null) {
    54                 connection.close();
    55             }
    56         } catch (SQLException e) {
    57             throw new RuntimeException(e);
    58         }    
    59     }
    60 }
    View Code

       2、示例

     1 public class TestPreparedStatementByUtils {
     2     
     3     @Test
     4     public void testUpdate() {
     5         
     6         Scanner input  = new Scanner(System.in);
     7         
     8         System.out.println("请输入待修改的编号:");
     9         int id = input.nextInt();
    10         
    11         System.out.println("请输入新用户名:");
    12         String name = input.next();
    13         
    14         //----------------------连接数据库的步骤----------------
    15         Connection connection = null;
    16         PreparedStatement statement = null;
    17         try {
    18             //1.获取连接
    19             connection = JDBCUtils.getConnection();
    20             
    21             //2.执行修改
    22             String sql = "update admin set username=? where id=?";
    23             statement = connection.prepareStatement(sql);
    24             statement.setString(1, name);
    25             statement.setInt(2, id);
    26             int update = statement.executeUpdate();
    27             System.out.println(update>0?"修改成功!":"修改失败!");
    28         } catch (SQLException e) {
    29             e.printStackTrace();
    30             
    31         }finally{
    32         
    33             //3.关闭连接
    34             JDBCUtils.close(null, statement, connection);
    35         }    
    36     }
    37 
    38 }
    View Code

    四、事务

      1、JDBC程序中当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。

      2、JDBC程序中为了让多个SQL语句作为一个事务执行:(重点)

        1)调用Connection对象的setAutoCommit(false); 以取消自动提交事务

        2)在所有的SQL语句都成功执行后,调用commit(); 方法提交事务

        3)在其中某个操作失败或出现异常时,调用rollback(); 方法回滚事务

        4)若此时Connection没有被关闭, 则需要恢复其自动提交状态setAutoCommit(true);

       注意:要求开启事务的连接对象和获取命令的连接对象必须是同一个!否则事务无效。如果多个操作,每个操作使用的是自己单独的连接,则无法保证事务。即同一个事务的多个操作必须在同一个连接下

      3、使用步骤:

        1)开启新事务

          取消隐式事务自动提交的功能:setAutoCommit(false);

        2)编写组成事务的一组sql语句

        3)结束事务

          commit();提交

          rollback();回滚

      4、实例

     1 @Test
     2     public void testTransaction(){
     3         
     4         Connection connection  = null;
     5         PreparedStatement statement = null;
     6         
     7         try {
     8             //1.获取连接
     9              connection = JDBCUtils.getConnection();
    10              
    11             //①事务的使用步骤1:开启事务
    12             connection.setAutoCommit(false);
    13             
    14             //②事务的使用步骤2:编写sql语句,并且执行
    15             statement = connection.prepareStatement("update admin set password = ? where id=?");
    16              
    17             //操作1:张三丰的钱-5000
    18             statement.setInt(2, 1);
    19             statement.setString(1, "888");
    20             statement.executeUpdate();
    21             
    22             //模拟异常
    23             int i = 1/0;
    24             
    25             //操作2:张三丰的钱-5000
    26             statement.setInt(2, 50053);
    27             statement.setString(1, "111");
    28             statement.executeUpdate();
    29             
    30             //③事务的使用步骤3:结束事务
    31             connection.commit();
    32             
    33         } catch (SQLException e) {
    34             try {
    35                 //回滚事务
    36                 connection.rollback();
    37             } catch (SQLException e1) {
    38                 e1.printStackTrace();
    39             }
    40         }finally{
    41             
    42             JDBCUtils.close(null, statement, connection);
    43         }
    44         
    45     }
    View Code

    五、批处理

      1、需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率。

       2、JDBC的批量处理语句包括下面两个方法:

        addBatch():添加需要批量处理的SQL语句或参数

        executeBatch():执行批量处理语句;

          clearBatch():清空批处理包的语句

              

     4、注意:

       1)JDBC连接MySQL时,如果要使用批处理功能,请再url中加参数?rewriteBatchedStatements=true。url=jdbc:mysql://localhost:3306/girls?rewriteBatchedStatements=true

       2)PreparedStatement作批处理插入时使用values(使用value没有效果)

       3)批处理往往和PreparedStatement一起搭配使用,可以既减少编译次数,又减少运行次数,效率大大提高

     1 //没有使用批处理:耗时长
     2     @Test
     3     public void testNoBatch() throws SQLException{
     4         
     5         //1.获取连接
     6         Connection connection = JDBCUtils.getConnection();
     7         
     8         //2.执行批量插入
     9         PreparedStatement statement = connection.prepareStatement("insert into admin values(null,?,?)");
    10         
    11         for(int i=1;i<=50000;i++){
    12             statement.setString(1,"john"+i);
    13             statement.setString(2, "0000");
    14             statement.executeUpdate();//执行
    15         }
    16         //3.释放资源
    17         JDBCUtils.close(null, statement, connection);
    18     }
    19     
    20     //使用批处理
    21     @Test
    22     public void testBatch() throws SQLException{
    23         
    24         //1.获取连接
    25         Connection connection = JDBCUtils.getConnection();
    26         
    27         //2.执行批量插入
    28         PreparedStatement statement = connection.prepareStatement("insert into admin values(null,?,?)");
    29         
    30         for(int i=1;i<=50000;i++){
    31             statement.setString(1,"john"+i);
    32             statement.setString(2, "0000");
    33             
    34             statement.addBatch();//添加sql语句到批处理包中
    35             if(i%1000==0){
    36                 statement.executeBatch();//执行批处理包中的sql语句
    37                 statement.clearBatch();//清空批处理包中的sql语句
    38             }
    39         }
    40         
    41         //3.释放资源
    42         JDBCUtils.close(null, statement, connection);
    43     }
    View Code
  • 相关阅读:
    Python学习【第五篇】:面向对象及相关
    Python之路【第四篇】:模块
    Python之路【第三篇】:python基础(二)
    Python之路【第二篇】:Python基础(一)
    Python之路【第一篇】:Python简介和入门
    Open-source Tutorial
    Algorithms
    Mathematics Base
    Mathematics Base
    Open-source Tutorial
  • 原文地址:https://www.cnblogs.com/zhufeng123/p/13874921.html
Copyright © 2020-2023  润新知