JDBC简介
DBC是什么?
由于数据库的厂商有很多,例如MySQL,Oracle等厂商,数据可能来自多个数据库或者我们需要切换数据库,DBC就是为了降低数据库与应用之间的耦合度而诞生的,下图是没有DBC的示意图:
下图为有DBC(JDBC)的示意图,JDBC API相对于JDBC Driver Manager来说为更高级的模块:
JDBC的意义
ODBC(Open Data Base Connectivity)是使用最广的、用于访问关系数据库的编程接口,它能在几乎所有平台上连接几乎所有的数据库,ODBC不适合直接在Java中使用,因为ODBC API是C的库函数,在Java程序中调用本地C代码有比较大的局限性,如安全性、健壮性、可移植性等;从ODBC C API到Java API的字面翻译是不可取的,例如Java没有指针而ODBC却对指针用得很广泛
JDBC(Java Database Connectivity)是Java平台中用于连接和操作数据库的标准应用程序编程接口(API)。它允许Java应用程序与各种不同类型的关系型数据库进行交互,执行SQL语句、处理结果集、管理数据库连接和事务等操作
JDBC的使用:
JDBC的使用主要分为三步:
建立与数据库的连接
执行SQL语句
在数据库连接上创建Statement对象,将各种SQL语句发送到所连接的数据库执行
对于多次执行但参数不同的SQL语句,可以使用PreparedStatement对象
可以使用CallableStatement对象调用数据库上的存储过程
处理结果集
结果集是查询语句返回的数据库记录的集合
在结果集中通过游标(cursor)控制具体记录的访问
SQL数据类型与Java数据类型的转换—— 根据SQL数据类型的不同,使用不同的方法读取数据
关闭数据库连接
更详细的解释:
加载驱动程序:
加载的方式有两种:
从系统属性java.sql中读取Driver的类名,并一一注册。
程序中使用Class.forName()
方法动态装载并注册Driver,如:
1 2 3 4 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver" ) Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver" ) Class.forName("oracle.jdbc.driver.OracleDriver" ) Class.forName("com.mysql.jdbc.Driver" )
建立数据库连接:
通过DriverManager.getConnection()
与数据库建立连接
1 public static Connection getConnection (String url, String user, String password) throws SQLException
url 是数据库连接串,指定数据库访问协议以及数据源。一般格式:jdbc:<subprotocol>:<subname>
例:通过 JDBC-ODBC 桥接驱动与 wombat 数据源建立连接
1 Connection con = DriverManager.getConnection("jdbc:odbc:wombat" , "myUsername" , "myPassword" );
Statement对象
在数据库连接上创建 Statement 对象,将各种SQL语句发送到所连接的数据库执行
1 2 public ResultSet executeQuery (String sql) throws SQLExceptionpublic int executeUpdate (String sql) throws SQLException
例子:传送SQL语句并得到结果集 rs
1 2 Statement stmt = con.createStatement( );ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1" );
PreparedStatement
DriverManager 角色:事实上,一般我们操作 Driver,获取 Connection 对象都是交给 DriverManager 统一管理的。DriverManger 可以注册和删除加载的驱动程序,可以根据给定的 url 获取符合 url 协议的驱动 Driver 或者是建立 Conenction 连接,进行数据库交互
Drive 角色:驱动加载进内存,其实就是实现了Java.sql.Driver接口的类。比如使用Class.forName()
将对应的驱动类加载到内存中,然后执行内存中的 static 静态代码段,代码段中,会创建一个驱动Driver的实例,放入 DriverManager 中,供 DriverManager 使用
Connection 角色:表示与特定数据库的连接(建立数据通信通道),可以获取到数据库的一些信息,包括:其表信息,应该支持的SQL语法,数据库内有什么存储过程,此链接功能的信息等等
Statement 角色:根据传入的 sql 语句,将其整理组合成数据库能够识别的 sql 语句,然后传递 sql 请求,之后会得到返回的结果。对于查询 sql,结果会以 ResultSet 的形式返回
ResultSet 角色:查询 sql 执行后,会得到 ResultSet 对象,作为数据库结果的映射。ResultSet 对从数据库返回的结果进行了封装,使用迭代器的模式逐条取出结果集中的记录 (假如是 List,大数据库的情况下会直接撑爆)
代码示例解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 import java.sql.*;public class JdbcTest { public static void main (String args[]) { String url= "jdbc:mysql://localhost/test" ; Connection con; String sql; Statement stmt; String num,name,sex; int age,math,eng,spec; try { Class.forName("com.mysql.jdbc.Driver" ); } catch (java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: " ); System.err.println(e.getMessage()); } try { con = DriverManager.getConnection(url, "root" , "java" ); stmt = con.createStatement(); sql = "INSERT INTO STUDENT " + "VALUES('200108','赵小龙','男',20,71,62,76)" ; stmt.executeUpdate(sql); sql = " SELECT * FROM STUDENT" ; ResultSet rs = stmt.executeQuery(sql); System.out.println("学号 姓名 性别 年龄" + " 高等数学 英语 专业课" ); while (rs.next()){ num = rs.getString(1 ); name = rs.getString(2 ); sex = rs.getString(3 ); age = rs.getInt(4 ); math = rs.getInt(5 ); eng = rs.getInt("英语" ); spec = rs.getInt("专业课" ); System.out.println(num+" " +name+" " +sex+" " +age+" " +math +" " +eng+" " +spec); } rs = stmt.executeQuery("SELECT 学号,姓名,高等数学,英语,专业课 " + "FROM STUDENT " + "WHERE 高等数学>=80" ); System.out.println(); System.out.println("The students whose math mark is beyond 80 are:" ); while (rs.next()){ num = rs.getString(1 ); name = rs.getString(2 ); math = rs.getInt(3 ); eng = rs.getInt("英语" ); spec = rs.getInt("专业课" ); System.out.println("学号=" +num+" " +"姓名=" +name+" " +"高等数学=" + math+" " +"英语=" +eng+" " +"专业课=" +spec); } stmt.close(); con.close(); } catch (SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); } } }
初始化数据库URL、连接对象(Connection)、SQL语句(Statement),以及用于存储查询结果的变量
1 2 3 4 5 6 String url= "jdbc:mysql://localhost/test" ; Connection con; String sql; Statement stmt; String num,name,sex;int age,math,eng,spec;
使用Class.forName()
加载并注册MySQL JDBC驱动
1 2 3 4 5 6 try { Class.forName("com.mysql.jdbc.Driver" ); } catch (ClassNotFoundException e) { System.err.print("ClassNotFoundException: " ); System.err.println(e.getMessage()); }
获取数据库连接,创建Statement对象,并执行SQL语句向STUDENT表中插入一条记录
1 2 3 4 5 6 7 try { con = DriverManager.getConnection(url, "root" , "java" ); stmt = con.createStatement(); sql = "INSERT INTO STUDENT VALUES('200108','小张','男',20,71,62,76)" ; stmt.executeUpdate(sql);
执行SQL查询获取STUDENT表中的所有记录,并打印所有学生信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 sql = "SELECT * FROM STUDENT" ;ResultSet rs = stmt.executeQuery(sql); System.out.println("学号 姓名 性别 年龄" + " 高等数学 英语 专业课" );while (rs.next()){ num = rs.getString(1 ); name = rs.getString(2 ); sex = rs.getString(3 ); age = rs.getInt(4 ); math = rs.getInt(5 ); eng = rs.getInt("英语" ); spec = rs.getInt("专业课" ); System.out.println(num+" " +name+" " +sex+" " +age+" " +math +" " +eng+" " +spec); }
执行SQL查询获取数学成绩超过80分的学生信息,并打印这些学生的记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 rs = stmt.executeQuery("SELECT 学号,姓名,高等数学,英语,专业课 " + "FROM STUDENT " + "WHERE 高等数学>=80" ); System.out.println("\nThe students whose math mark is beyond 80 are:" ); while (rs.next()){ num = rs.getString(1 ); name = rs.getString(2 ); math = rs.getInt(3 ); eng = rs.getInt("英语" ); spec = rs.getInt("专业课" ); System.out.println("学号=" +num+" " +"姓名=" +name+" " +"高等数学=" + math+" " +"英语=" +eng+" " +"专业课=" +spec); }
关闭Statement和Connection以释放资源。
1 2 3 4 5 6 7 8 stmt.close(); con.close(); } catch (SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); } } }