使用 PreparedStatement 的 JDBC 程序示例

在之前的 JDBC 教程中,我们开发了 JDBC 程序来使用 PreparedStatement 对象插入、更新、选择和显示记录。现在在本教程中,我们将使用 PreparedStatement 对象开发更多 JDBC 或 Java 程序示例。

我们使用的是 Oracle 数据库,但您可以使用任何具有所需信息(如 Jar 文件、URL 语法、用户名、密码)的数据库。在 Oracle 数据库中,我们在 Scott 用户下有一个 emp 表。我们将使用这张表。

选择记录的 JDBC PreparedStatement 示例

程序描述:- 编写一个 JDBC 应用程序,根据给定的部门编号提供员工详细信息。

准备 SQL 查询

SQL> SELECT * FROM emp;

它将显示emp表的所有详细信息。

SQL> SELECT empno, ename, job, sal, deptno FROM emp;

上面的查询将仅显示 emp 表中的 empno、ename、job、sal 和 deptno 列。

SQL> SELECT empno, ename, job, sal, 
     deptno FROM emp 
     WHERE deptno IN (10, 20);

它显示 emp 表中的 empno、ename、job、sal 和 deptno 列,仅针对其部门编号为 10 或 20 的列。

SQL> SELECT empno, ename, job, sal,
     deptno FROM emp
     WHERE deptno IN (10, 20) 
     ORDER BY deptno;

它显示emp表中的empno、ename、job、sal和deptno列,仅针对部门编号为10或20的列,按deptno的顺序显示。

现在,我们的查询已准备就绪。让我们开发应用程序。

开发应用程序

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class SelectTest {

   // SQL query
   private static final String SELECT_EMPLOYEE_QUERY = 
      "SELECT EMPNO, ENAME, JOB, SAL, DEPTNO FROM EMP "
      + " WHERE DEPTNO IN (?,?) ORDER BY DEPTNO";

   public static void main(String[] args ) {

      // declare variables
      Scanner scan = null;
      int deptno1 = 0, deptno2 = 0;
      Connection con = null;
      PreparedStatement ps = null;
      ResultSet rs = null;
      boolean flag = false;

      try {
    	 // read input
    	 scan = new Scanner(System.in);
    	 if(scan != null) {
             System.out.print("Enter deptno1: ");
             deptno1 = scan.nextInt();
             System.out.print("Enter deptno2: ");
             deptno2 = scan.nextInt();
    	 }

         // establish the connection
         con = DriverManager.getConnection(
           "jdbc:oracle:thin:@localhost:1521:knowprogram",
           "scott", "tiger");

         // compile SQL query and 
         // store it in PreparedStatemet object
         if(con != null)
         ps = con.prepareStatement(SELECT_EMPLOYEE_QUERY);

         // set input value to query parameter
         if(ps != null) {
            ps.setInt(1, deptno1);
            ps.setInt(2, deptno2);
         }

         // execute the query
         if(ps != null) 
         rs = ps.executeQuery();

         // process the result
         if(rs != null) {
            while(rs.next()) {
               flag = true;
               // SELECT EMPNO, ENAME, JOB
               // SAL, DEPTNO FROM EMP
               System.out.println(""
                     + rs.getInt("EMPNO") +" "
                     + rs.getString("ENAME") +" "
                     + rs.getString("JOB") +" "
                     + rs.getInt("SAL") +" "
                     + rs.getInt("DEPTNO"));
            }
        }

        if(flag)
        System.out.println("Records fetched & displayed");
        else
        System.out.println("Records not found");

     } catch(SQLException se) {
        se.printStackTrace();
     } catch(Exception e) {
        e.printStackTrace();
     } // end of try-catch block 

     finally {
        // close JDBC objects
        try {
           if(rs != null) rs.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(ps != null) ps.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(con != null) con.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(scan != null) scan.close();
        } catch(Exception e) {
           e.printStackTrace();
        }
     }

   } //end of main
} //end of class

输出:-

Enter deptno1: 10
Enter deptno2: 20
7934 MILLER CLERK 1300 10
7782 CLARK MANAGER 2450 10
………
7902 FORD ANALYST 2850 20
7876 ADAMS CLERK 1100 20
………
Records fetched & displayed

Enter deptno1: 10
Enter deptno2: 30
7782 CLARK MANAGER 2450 10
7839 KING PRESIDENT 5000 10
………
7698 BLAKE MANAGER 2850 30
7844 TURNER SALESMAN 1500 30
………
Records fetched & displayed

Enter deptno1: 40
Enter deptno2: 80
Records not found

JDBC程序显示第N高薪

程序描述:- 使用 PreparedStatement 编写一个 JDBC 应用程序示例,该示例从 emp 表中提供具有第 n 高 Sal 的员工详细信息。

从 emp 表中,我们必须获取薪水第 n 高的员工,然后显示这些记录。

准备 SQL 查询,

SQL> SELECT * FROM
    (SELECT ename, sal, dense_rank()
    over(ORDER BY sal desc) r 
    FROM emp) WHERE r=&n;

Enter value for n: 9
ENAME    SAL     R
-------- ------- ---
WARD     1250    9
MARTIN   1250    9

开发应用程序,

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class SelectTest {

   // SQL query
   private static final String SELECT_EMPLOYEE_QUERY = 
      " SELECT * FROM " +
      " (SELECT ENAME, SAL, DENSE_RANK() OVER " +
      " (ORDER BY SAL DESC) R FROM EMP) WHERE R = ? ";

   public static void main(String[] args ) {

      // declare variables
      Scanner scan = null;
      int n = 0;
      Connection con = null;
      PreparedStatement ps = null;
      ResultSet rs = null;
      boolean flag = false;

      try {

    	 // read input
    	 scan = new Scanner(System.in);
    	 if(scan != null) {
    	     System.out.print("Enter n value: ");
             n = scan.nextInt();
    	 }

         // establish the connection
         con = DriverManager.getConnection(
           "jdbc:oracle:thin:@localhost:1521:knowprogram",
           "scott", "tiger");

         // compile SQL query and 
         // store it in PreparedStatemet object
         if(con != null)
         ps = con.prepareStatement(SELECT_EMPLOYEE_QUERY);

         // set input value to query parameter
         if(ps != null) {
            ps.setInt(1, n);
         }

         // execute the query
         if(ps != null) 
            rs = ps.executeQuery();

         // process the result
         if(rs != null) {
            while(rs.next()) {
               flag = true;
               // SELECT ENAME, SAL, DENSE_RANK()
               System.out.println(""
                    + rs.getString("ENAME") +" "
                    + rs.getInt("SAL") +" "
                    + rs.getInt("R"));
            }
        }

        if(flag)
        System.out.println("Records fetched & displayed");
        else
        System.out.println("Records not found");

     } catch(SQLException se) {
        se.printStackTrace();
     } catch(Exception e) {
        e.printStackTrace();
     } // end of try-catch block 

     finally {
        // close JDBC objects
        try {
           if(rs != null) rs.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(ps != null) ps.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(con != null) con.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(scan != null) scan.close();
        } catch(Exception e) {
           e.printStackTrace();
        }
    }

  } //end of main
} //end of class

输出:-

Enter n value: 1
KING 5000 1
Records fetched & displayed

Enter n value: 9
WARD 1250 9
MARTIN 1250 9
Records fetched & displayed

Enter n value: 20
Records not found

使用 PreparedStatement 的非选择 SQL 查询的 JDBC 程序示例

要在数据库软件中发送和执行非选择 SQL 查询,请使用 executeUpdate(-) 或 executeLargeUpdate(-)。executeLargeUpdate(-) 方法是从 java8 版本中给出的。

  • public int executableUpdate(String query) throws SQLException
  • public long executableLargeUpdate(String query) throws SQLException

程序描述:- 编写一个 JDBC 应用程序,使用 PreparedStatement 对象根据给定的学生城市/地址删除学生详细信息。

在 Oracle 数据库中创建包含一些记录的表,

SQL> select * from student;

 SNO  SNAME    SADD        AVG
----  -------  ----------- ----------
2000  Sophia   Manchester  89
3000  William  London      75
1000  Alex     Boise       80
1005  Ameila   Washington  59

在 SQL plus 工具中,默认情况下自动提交模式是关闭的。因此,每当我们从表中删除任何记录时,它都不会永久删除。我们可以使用“回滚”命令获取这些删除记录。要永久删除它们,我们应该使用“commit”命令。

但是在 JDBC 应用程序中,默认情况下自动提交模式是打开的。因此,每当我们从 JDBC 应用程序中删除记录时,它就会永久删除。我们无法取回那些已删除的记录。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class DeleteStudent {

   // SQL query
   private static final String DELETE_STUDENT_QUERY = 
              "DELETE FROM STUDENT WHERE SADD = ?";

   public static void main(String[] args ) {

      // declare variables
      Scanner scan = null;
      String address = null;
      Connection con = null;
      PreparedStatement ps = null;
      int result = 0;

      try {
        // read input 
        scan = new Scanner(System.in);
        if(scan != null) {
           System.out.print("Enter address: ");
           address = scan.next();
        }

        // establish the connection
        con = DriverManager.getConnection(
           "jdbc:oracle:thin:@localhost:1521:knowprogram",
           "scott", "tiger");

        // compile SQL query and 
        // store it in PreparedStatemet object
        if(con != null)
        ps = con.prepareStatement(DELETE_STUDENT_QUERY);

        // set input values and execute query
        if(ps != null) {
           // set input values to query parameters
           ps.setString(1, address);
           // execute the query
           result = ps.executeUpdate();
        }

        // process the result
        if(result == 0)
        System.out.println("No records found for deletion");
        else
        System.out.println(result + " records deleted");

     } catch(SQLException se) {
        se.printStackTrace();
     } catch(Exception e) {
        e.printStackTrace();
     } // end of try-catch block

     finally {
        // close JDBC objects
        try {
           if(ps != null) ps.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(con != null) con.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(scan != null) scan.close();
        } catch(Exception e) {
           e.printStackTrace();
        }
     }

  } //end of main
} //end of class

输出:-

Enter address: London
1 records deleted

Enter address: London
No records found for deletion

在 SQL plus 工具中默认自动提交模式是关闭的,而在 JDBC 应用程序中自动提交模式是打开的。每当我们使用 SQL* Plus 工具删除记录但没有提交时,JDBC 应用程序就无法访问这些数据,就会出现死锁情况。JDBC 应用程序挂起,直到我们没有提交或回滚 SQL plus 工具中的数据,然后只有 JDBC 应用程序做出进一步的决定。

为了演示它,在 SQL plus 工具中删除,然后不使用or ,执行上面的 JDBC 应用程序并从 JDBC 应用程序中尝试删除。怎么了?sadd = Washingtoncommitrollbacksadd = Washington

从 SQL Plus 工具中删除,

SQL> delete from student 
   where sadd = ‘Washington’;
1 row deleted.

SQL> select * from student;

Now, executing JDBC program
Enter address: Washington

JDBC 程序进入挂起模式。目前记录在流中,所以不能说没有找到记录,但不能删除,因为记录不在表中。

现在,从 SQL 工具中,如果我们执行“commit”命令,那么 jdbc 程序将显示“No records found for delete”。或者,如果我们从 SQL 工具中执行“回滚”命令,那么 JDBC 程序将显示“1 条记录已删除”。

此应用程序的要点

  • 在处理非选择查询时,不需要使用 ResultSet 对象。
  • JDBC 应用程序中的所有操作都通过 JDBC 驱动程序在数据库软件上进行。

自动提交模式的要点

  • 从 SQL 提示符执行的非选择 SQL 查询可以是committedrolled back显式的,因为它们将通过禁用自动提交模式在数据库软件中执行。
  • 来自前端(如 java 应用程序)在数据库软件中执行的非选择 SQL 查询不能committedrolled back因为它们将通过启用自动提交模式在数据库软件中执行。查询执行结果会立即提交,这样我们以后就不能回滚了。
  • JDBC 应用程序无法读取和操作未提交的记录。如果这些记录即将被操纵,那么应用程序将挂起,直到记录在数据库中变得稳定。

根据开始和结束范围删除记录

程序描述:- 编写一个 JDBC 应用程序,根据给定的学号​​开始、结束范围删除学生详细信息。

准备 SQL 查询,

SQL> DELETE FROM student WHERE
    sno>=100 AND sno<=1000;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class DeleteStudent {

   // SQL query
   private static final String DELETE_STUDENT_QUERY = 
         "DELETE FROM STUDENT WHERE" +
         " SNO >= ? AND SNO <= ?";

   public static void main(String[] args ) {

      // declare variables
      Scanner scan = null;
      int startSno = 0, endSno = 0;
      Connection con = null;
      PreparedStatement ps = null;
      int result = 0;

      try {
         // read input 
         scan = new Scanner(System.in);
         if(scan != null) {
            System.out.print("Enter start sno: ");
            startSno = scan.nextInt();
            System.out.print("Enter end sno: ");
            endSno = scan.nextInt();
         }

         // establish the connection
         con = DriverManager.getConnection(
           "jdbc:oracle:thin:@localhost:1521:knowprogram",
           "scott", "tiger");

         // compile SQL query and 
         // store it in PreparedStatemet object
         if(con != null)
         ps = con.prepareStatement(DELETE_STUDENT_QUERY);

         // set input values and execute query
         if(ps != null) {
           // set input values to query parameters
           ps.setInt(1, startSno);
           ps.setInt(2, endSno);
           // execute the query
           result = ps.executeUpdate();
         }

         // process the result
         if(result == 0)
         System.out.println("No records found"+ 
                            " for deletion");
         else
         System.out.println(result + " records deleted");

     } catch(SQLException se) {
        se.printStackTrace();
     } catch(Exception e) {
        e.printStackTrace();
     } // end of try-catch block 

     finally {
        // close JDBC objects
        try {
           if(ps != null) ps.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(con != null) con.close();
        } catch(SQLException se) {
           se.printStackTrace();
        }
        try {
           if(scan != null) scan.close();
        } catch(Exception e) {
           e.printStackTrace();
        }
     }

   } //end of main
} //end of class

输出:-

Enter start sno: 1000
Enter end sno: 2000
3 records deleted

Enter start sno: 100
Enter end sno: 1000
No records found for deletion

使用单一方法执行选择和非选择查询

我们可以使用一个方法同时执行 Select 和 non-select 查询吗?
是的,我们可以使用一个方法同时执行选择和非选择查询。execute(-)

execute(-) 方法的原型/签名:-
public boolean execute(String qry) throws Exception

  • 此方法在执行选择查询时返回 true,我们应该使用 getResultSet() 来获取选择查询给出的记录。
  • 它在执行非选择查询时返回 false,我们应该使用 st.getUpdateCount(-) 来获取表示受影响记录数的数值。
  • 此方法不是行业标准,因为它使程序员单独执行查询或单独收集查询结果,因此对选择查询使用 executeQuery(-),对非选择查询使用 executeUpdate(-)。
  • 在执行插入、创建表、删除表查询时,如果查询执行失败,我们将得到一个异常。
  • 在处理删除、更新查询时,如果查询执行有效,我们将得到零。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class DeleteStudent {

   public static void main(String[] args ) {

      // declare variables
      Scanner scan = null;
      String query = null;
      Connection con = null;
      PreparedStatement ps = null;
      boolean flag = false; 
      ResultSet rs = null;
      int count = 0;

      try {
         // read input 
         scan = new Scanner(System.in);
         if(scan != null) {
            System.out.print("Enter query: ");
            query = scan.nextLine();
         }

         // establish the connection
         con = DriverManager.getConnection(
            "jdbc:oracle:thin:@localhost:1521:knowprogram",
            "scott", "tiger");

         // compile SQL query and 
         // store it in PreparedStatemet object
         if(con != null)
            ps = con.prepareStatement(query);

         // execute the query
         if(ps != null)
            flag = ps.execute();

         // process the result
         if(flag) {
           System.out.println("Select query is executed");
           rs = ps.getResultSet();

           // process the resultSet
           while(rs.next()) {
               System.out.println(rs.getString(1)+" "
                                +rs.getString(2)+" "
                                +rs.getString(3) );
           }

         } else {
           System.out.println("The non-select query"
                                    " is executed");
           count = ps.getUpdateCount();
           System.out.println("Number of records that"+ 
                    " are affected = "+ count);
         }

      } catch(SQLException se) {
         se.printStackTrace();
      } catch(Exception e) {
         e.printStackTrace();
      } // end of try-catch block

      finally {
         // close JDBC objects
         try {
             if(rs != null) rs.close();
         } catch(SQLException se) {
             se.printStackTrace();
         }
         try {
            if(ps != null) ps.close();
         } catch(SQLException se) {
            se.printStackTrace();
         }
         try {
            if(con != null) con.close();
         } catch(SQLException se) {
            se.printStackTrace();
         }
         try {
            if(scan != null) scan.close();
         } catch(Exception e) {
            e.printStackTrace();
         }
      }

   } //end of main
} //end of class

输出:-

Enter query: select sno, sname, avg from student
Select query is executed
2000 Sophia 89
3000 William 75
1000 Alex 80
1005 Amelia 65

Enter query: update student set avg = 95 where sno = 2000
The non-select query is executed
Number of records that are affected = 1

如果您喜欢这篇文章,请与您的朋友分享。您想分享有关上述主题的更多信息,还是您发现任何不正确的地方?让我们在评论中知道。谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值