Java笔记 – JDBC编程
JDBC通过分层技术实现了跨数据库编程。为不同的数据库开发了统一的编程接口,为不同的数据库提供了不同的JAR类库。
一、JDBC基础
1、开发环境
(1)下载对应的Jar包
Oracle的本地Jar包位于【Oracle11g\product\11.2.0\dbhome_1\jdbc\lib】
官网下载地址:【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包加入结果。
(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();