Java笔记 – JDBC编程

       JDBC通过分层技术实现了跨数据库编程。为不同的数据库开发了统一的编程接口,为不同的数据库提供了不同的JAR类库。

一、JDBC基础

1、开发环境

(1)下载对应的Jar包

        Oracle的本地Jar包位于【Oracle11gproduct11.2.0dbhome_1jdbclib】

       官网下载地址:【http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html

       Mysql的jar包可以在【https://dev.mysql.com/downloads/connector/j/】下载

(2)增加扩展jar包

        首先,将下载的JAR包放到lib目录下,然后在jar包上右击,选择【Bulid Path  -> Add to Bulid Path】,即可将JDBC的jar包加入到项目的扩展jar包中。如下图是ODBC的jar包加入结果。

                                     image

(3)测试Oracle数据库连接程序

       在eclipse中运行以下程序,若不报错,则表明已经可以成功连接到Oracle数据库。

  1 import java.sql.*;
  2 public class Main {
  3 	public static void main(String[] args) throws Exception{
  4 		String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
  5 		Class.forName("oracle.jdbc.driver.OracleDriver");
  6 		Connection conn = DriverManager.getConnection(url, "scott", "tiger");
  7 	}
  8 }

(4)测试Mysql数据库连接程序

import java.sql.*;
public class Main {
   	public static void main(String[] args) throws Exception{
       	 	String url = "jdbc:mysql://localhost:3306/scott";
		Class.forName("com.mysql.jdbc.Driver");
		Connection conn = DriverManager.getConnection(url,"root","su486213");
   	}
}

(5)两种连接数据库的方式

① getConnection(mysql连接地址,用户名,密码);

//包含数据库基本的连接信息
String url = "jdbc:mysql://localhost:3306/scott";
//包含字符编码格式等其余连接信息
String url = "jdbc:mysql://localhost:3306/scott?characterEncoding=utf-8";
//连接各式
Connection conn = DriverManager.getConnection(url,"root","su486213");

② getConnection(包含所有信息的URL);

String url = "jdbc:mysql://localhost:3306/scott?user=root&password=su486213";
//连接数据库
Connection conn = DriverManager.getConnection(url);

2、连接步骤

(1)Load Driver

  1 //在实例化时自动向DriverManager注册,不需显式调用DriverManager.register()
  2 
  3 //方法一:类装载器,可以根据字符串创建一个对象
  4 Class.forName()
  5 Class.forName().newInstance();
  6 //举例
  7 Class.forName("oracle.jdbc.driver.OracleDriver");
  8 
  9 //方法二:使用关键字new
 10 new DriverName();
 11 //举例
 12 new oracle.jdbc.driver.OracleDriver();

(2)Connection to the DataBase

  1 DriverManager.getConnection();
  2 //举例
  3 String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
  4 Connection conn = DriverManager.getConnection(url,"scott","tiger");

(3)Execute the SQL

  1 Connection.createStatement();
  2 Statement.executeQuery();//查询
  3 Statement.executeUpdate();//增、删、改

(4)Retrieve the result data

  1 //循环取得结果集
  2 while(rs.next())

(5)Show the result data

  1 //将数据库中的各种类型转换为JAVA中的类型
  2 getXXX();

(6)Close

  1 close the resultset;
  2 close the statement;
  3 close the connection;

3、简单的JDBC程序

  1 import java.sql.*;
  2 
  3 public class Main {
  4 
  5 	public static void main(String[] args) {
  6 		ResultSet rs = null;
  7 		Statement stmt = null;
  8 		Connection conn = null;
  9 		try {
 10 			//第一步:实例化OracleDriver对象
 11 			Class.forName("oracle.jdbc.driver.OracleDriver");
 12 			//第二部:连接数据库
 13 			String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
 14 			conn = DriverManager.getConnection(url,"scott","tiger");
 15 			//第三部:执行SQL语句
 16 			stmt = conn.createStatement();
 17 			//① 执行 增删改类 的SQL语句
 18 			stmt.executeUpdate("insert into dept values (60, 'NAME', 'TEST')");
 19 			//② 执行 查询类 的SQL语句
 20 			rs = stmt.executeQuery("select * from dept where deptno = 60");
 21 			//第四步:遍历结果集
 22 			while(rs.next()) {
 23 				//只要字段值可以转化成该类型的数据,就可以以该类型取出
 24 				System.out.println(rs.getString("deptno"));
 25 				System.out.println(rs.getInt("deptno"));
 26 			}
 27 		} catch (ClassNotFoundException e) {
 28 			e.printStackTrace();
 29 		} catch (SQLException e) {
 30 			e.printStackTrace();
 31 		} finally {
 32 			//最后一步:关闭资源(倒着释放资源)
 33 			try {
 34 				if(rs != null) {//释放结果集
 35 					rs.close();
 36 					rs = null;
 37 				}
 38 				if(stmt != null) {//释放Statement
 39 					stmt.close();
 40 					stmt = null;
 41 				}
 42 				if(conn != null) {//释放数据库链接
 43 					conn.close();
 44 					conn = null;
 45 				}
 46 			} catch (SQLException e) {
 47 				e.printStackTrace();
 48 			}
 49 		}
 50 	}
 51 
 52 }
 53 

二、JDBC进阶

1、预编译语句

   (1)使用Statement书写SQL语句过于复杂

  1 int deptno = 0;
  2 String dname = "Name";
  3 String loc = "LOC";
  4 
  5 Statement stmt = conn.createStatement();
  6 //SQL语句的书写方式过于复杂
  7 String sql = "insert into dept values (" + deptno + ",'" + dname + "','" + loc + "')"; 
  8 stmt.executeUpdate(sql);

(2) PreparStatement是Statement的子类,可以灵活的指定SQL语句中的变量

  1 int deptno = 0;
  2 String dname = "Name";
  3 String loc = "Loc";
  4 
  5 PreparedStatement pstmt = conn.prepareStatement("insert into dept2 values (?, ?, ?)");
  6 pstmt.setInt(1, deptno);
  7 pstmt.setString(2, dname);
  8 pstmt.setString(3, loc);
  9 //执行SQL语句,若是查询语句,还需遍历结果集
 10 pstmt.executeUpdate();

2、存储过程

(1)存储过程

  1 //存储过程
  2 create or replace procedurce p
  3        (v_a  in  number  , v_b  number , v_ret out number  , v_temp  in  out number)
  4 is
  5    begin
  6           if( v_a > v_b )    then
  7                    v_ret  := v_a;
  8           else
  9                   v_ret   := v_b;
 10           end  if;
 11           v_temp  := v_temp  + 1;
 12    end;

(2)CallableStatement 调用存储过程

  1 CallableStatement cstmt = conn.prepareCall("{call p(?, ?, ?, ?)}");
  2 //注册输出参数
  3 cstmt.registerOutParameter(3, Types.INTEGER);
  4 cstmt.registerOutParameter(4, Types.INTEGER);
  5 //设置输入参数
  6 cstmt.setInt(1, 3);
  7 cstmt.setInt(2, 4);
  8 cstmt.setInt(4, 5);
  9 //调用存储过程
 10 cstmt.execute();
 11 //取出输出参数
 12 System.out.println(cstmt.getInt(3));
 13 System.out.println(cstmt.getInt(4));

3、批处理

(1)使用PreparedStatement中的addBatch方法

  1 PreparedStatement ps = conn.prepareStatement("insert into dept2 values (?, ?, ?)");
  2 //增加第一个批处理过程	
  3 ps.setInt(1, 10);
  4 ps.setString(2, "test");
  5 ps.setString(3, "test");
  6 ps.addBatch();
  7 //增加第二个批处理过程		
  8 ps.setInt(1, 11);
  9 ps.setString(2, "test");
 10 ps.setString(3, "test");
 11 ps.addBatch();
 12 //执行批处理		
 13 ps.executeBatch();

(2)使用Statement中的addBatch方法

  1 Statement stmt = conn.createStatement();
  2 //添加批处理过程
  3 stmt.addBatch("insert into dept2 values (10, '10', 'test')");
  4 stmt.addBatch("insert into dept2 values (11, '11', 'test')");
  5 stmt.addBatch("insert into dept2 values (12, '12', 'test')");
  6 //执行批处理
  7 stmt.executeBatch();

4、事务处理

  1 import java.sql.*;
  2 public class Main {
  3 	public static void main(String[] args) {
  4 		Connection conn = null;
  5 		Statement stmt = null;
  6 
  7 		try {
  8 			Class.forName("oracle.jdbc.driver.OracleDriver");
  9 			String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
 10 			conn = DriverManager.getConnection(url, "scott", "tiger");
 11 
 12 			//默认自动提交,要想使用事物,需将该值设置为false,不让其自动提交
 13 			conn.setAutoCommit(false);
 14 
 15 			//将事物过程进行批处理
 16 			stmt = conn.createStatement();
 17 			stmt.addBatch("insert into dept2 values (10, '10', 'text')");
 18 			stmt.addBatch("insert into dept2 values (11, '11', 'text')");
 19 			stmt.addBatch("insert into dept2 values (12, '12', 'text')");
 20 			stmt.executeBatch();
 21 
 22 			//手动提交
 23 			conn.commit();
 24 			//恢复默认设置:自动提交
 25 			conn.setAutoCommit(true);
 26 		} catch (ClassNotFoundException e) {
 27 			e.printStackTrace();
 28 		} catch(SQLException e) {
 29 			e.printStackTrace();
 30 			try {
 31 				if(conn != null)
 32 				{
 33 					//回滚操作
 34 					conn.rollback();
 35 					//恢复默认设置:自动提交
 36 					conn.setAutoCommit(true);
 37 				}
 38 			} catch (SQLException e1) {
 39 				e1.printStackTrace();
 40 			}
 41 		}finally {
 42 			try {
 43 				if(stmt != null)
 44 					stmt.close();
 45 				if(conn != null)
 46 					conn.close();
 47 			} catch (SQLException e) {
 48 				e.printStackTrace();
 49 			}
 50 		}
 51 	}
 52 }

5、结果集

(1)可以前后移动的结果集

  1 //将结果集设置为对滚动不敏感
  2 Statement stmt = conn.createStatement(
  3 		ResultSet.TYPE_SCROLL_INSENSITIVE,//对滚动不敏感
  4 		ResultSet.CONCUR_READ_ONLY);//并发、只读
  5 //执行SQL语句
  6 ResultSet rs = stmt.executeQuery("select * from emp order by sal");
  7 
  8 //测试可移动的结果集
  9 //定位到下一个
 10 rs.next();
 11 System.out.println(rs.getInt(1));
 12 //定位到最后一个			
 13 rs.last();
 14 System.out.println(rs.getString(1));
 15 System.out.println(rs.isLast());//是不是最后一条
 16 System.out.println(rs.isAfterLast());//是不是最后一条的下一条
 17 System.out.println(rs.getRow());//当前记录是第几条记录			
 18 //向前滚动
 19 rs.previous();
 20 System.out.println(rs.getString(1));
 21 //定位到第六行
 22 rs.absolute(6);
 23 System.out.println(rs.getString(1)

(2)可更新的结果集

  1 Statement stmt=conn.createStatement(
  2 		ResultSet.TYPE_SCROLL_INSENSITIVE,
  3 		ResultSet.CONCUR_UPDATABLE);//并发、可更新
  4 
  5 ResultSet rs=stmt.executeQuery("select * from emp");
  6 
  7 rs.next();
  8 //更新一行数据(数据库中的数据)
  9 rs.updateString("ename","AAAA");
 10 rs.updateRow();
 11 
 12 //插入新行
 13 rs.moveToInsertRow();
 14 rs.updateInt(10, 10);
 15 rs.updateString("ename","test");
 16 rs.updateInt("mgr", 10);
 17 rs.updateDouble("sal", 10.10);
 18 rs.insertRow();
 19 //将光标移动到新建的行
 20 rs.moveToCurrentRow();
 21 
 22 //删除行
 23 rs.absolute(5);
 24 rs.deleteRow();
 25 
 26 //取消更新
 27 //rs.cancelRowUpdates();
原文地址:https://www.cnblogs.com/sh086/p/8320656.html