JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC为数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯 Java API 编写数据库应用程序,并且可跨平台运行,并且不受数据库供应商的限制。
1、跨平台运行:这是继承了Java语言的“一次编译,到处运行”的特点;
2、不受数据库供应商的限制:巧妙在于JDBC设有两种接口,一个是面向应用程序层,其作用是使得开发人员通过SQL调用数据库和处理结果,而不需要考虑数据库的提供商;另一个是驱动程序层,处理与具体驱动程序的交互,JDBC驱动程序可以利用JDBC API创建Java程序和数据源之间的桥梁。应用程序只需要编写一次,便可以移到各种驱动程序上运行。Sun提供了一个驱动管理器,数据库供应商——如MySQL、Oracle,提供的驱动程序满足驱动管理器的要求就可以被识别,就可以正常工作。所以JDBC不受数据库供应商的限制。
JDBC API可以作为连接Java应用程序与各种关系数据库的纽带,在带来方便的同时也有负面影响,以下是JDBC的优、缺点。优点如下:
操作便捷:JDBC使得开发人员不需要再使用复杂的驱动器调用命令和函数;
可移植性强:JDBC支持不同的关系数据库,所以可以使同一个应用程序支持多个数据库的访问,只要加载相应的驱动程序即可;
通用性好:JDBC-ODBC桥接驱动器将JDBC函数换成ODBC;
面向对象:可以将常用的JDBC数据库连接封装成一个类,在使用的时候直接调用即可。
缺点如下:
访问数据记录的速度受到一定程度的影响;
更改数据源困难:JDBC可支持多种数据库,各种数据库之间的操作必有不同,这就给更改数据源带来了很大的麻烦
创建一个以JDBC连接数据库的程序,包含7个步骤:
在连接数据库之前,首先要加载想要连接的数据库的驱动,就是数据库厂商提供的jar包,将它加载到JVM(Java虚拟机)中,这通过java.lang.Class类的静态方法forName(String className)实现。
例如:
01 | try{ |
02 | |
03 | //加载MySql的驱动类 |
04 | //不同的数据库提供的驱动包是不一样的,在下面大家将会看到常用的驱动类。 |
05 | Class.forName("com.mysql.jdbc.Driver") ; |
06 | System.out.println("成功加载驱动"); |
07 | |
08 | }catch(ClassNotFoundException e){ |
09 | |
10 | System.out.println("找不到驱动程序类 ,加载驱动失败!"); |
11 | |
12 | e.printStackTrace() ; |
13 | |
14 | } |
成功加载后,会将Driver类的实例注册到DriverManager类中,我们在下一步中,就可以直接调用类中的方法。
•连接URL定义了连接数据库时的协议、子协议、数据源标识。
•书写形式:协议:子协议:数据源标识
协议:在JDBC中总是以jdbc开始
子协议:是桥连接的驱动程序或是数据库管理系统名称。
数据源标识:标记找到数据库来源的地址与连接端口。
下面列出常用的数据库连接URL:
Oracle8/8i/9i数据库(thin模式)
1 | Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); |
2 | String url="jdbc:oracle:thin:@localhost:1521:orcl"; |
3 | //orcl为数据库的SID |
DB2数据库
1 | Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); |
2 | String url="jdbc:db2://localhost:5000/sample"; |
3 | //sample为你的数据库名 |
Sql Server7.0/2000数据库
1 | Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); |
2 | String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; |
3 | //mydb为数据库 |
Sybase数据库
1 | Class.forName("com.sybase.jdbc.SybDriver").newInstance(); |
2 | String url =" jdbc:sybase:Tds:localhost:5007/myDB"; |
3 | //myDB为你的数据库名 |
Informix数据库
1 | Class.forName("com.informix.jdbc.IfxDriver").newInstance(); |
2 | String url ="jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver; |
MySQL数据库
1 | Class.forName("com.mysql.jdbc.Driver").newInstance(); |
2 | String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" |
3 | //myDB为数据库名 |
PostgreSQL数据库
1 | Class.forName("org.postgresql.Driver").newInstance(); |
2 | String url ="jdbc:postgresql://localhost/myDB" |
3 | //myDB为数据库名 |
说明:useUnicode=true:表示使用Unicode字符集。如果characterEncoding设置为gb2312或GBK,本参数必须设置为true 。aracterEncoding=gbk:字符编码方式。
•要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。
•使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。
例如:
01 | String url = "jdbc:mysql://localhost:3306/test" ; |
02 | |
03 | String username = "root" ; |
04 | |
05 | String password = "root" ; |
06 | |
07 | try{ |
08 | |
09 | Connection con = |
10 | |
11 | DriverManager.getConnection(url , username , password ) ; |
12 | |
13 | }catch(SQLException se){ |
14 | |
15 | System.out.println("数据库连接失败!"); |
16 | |
17 | se.printStackTrace() ; |
18 | |
19 | } |
也可以不单独定义上面username和password,直接将用户名、密码附加在url上,作为参数发送给数据库服务器,例如
1 | jdbc:mysql://localhost:3306/test?user=root&password=root |
•要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3
种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
具体的实现方式:
1 | Statement stmt = con.createStatement() ; |
2 | PreparedStatement pstmt = con.prepareStatement(sql) ; |
3 | CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ; |
Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate
和execute
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句
,返回一个结果集(ResultSet)对象。
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或
DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的
语句。
具体实现的代码:
1 | ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ; |
2 | int rows = stmt.executeUpdate("INSERT INTO ...") ; |
3 | boolean flag = stmt.execute(String sql) ; |
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些
行中数据的访问。
• 使用结果集(ResultSet)对象的访问方法获取数据:
1 | while(rs.next()){ |
2 | |
3 | String name = rs.getString("name") ; |
4 | |
5 | String pass = rs.getString(1) ; // 此方法比较高效 |
6 | |
7 | } |
(列是从左到右编号的,并且从列1开始)
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声
明顺序相反:
1、关闭记录集
2、关闭声明
3、关闭连接对象
01 | if(rs != null){ // 关闭记录集 |
02 | |
03 | try{ |
04 | rs.close() ; |
05 | |
06 | }catch(SQLException e){ |
07 | |
08 | e.printStackTrace() ; |
09 | |
10 | } } |
11 | |
12 | if(stmt != null){ // 关闭声明 |
13 | |
14 | try{ |
15 | |
16 | stmt.close() ; |
17 | |
18 | }catch(SQLException e){ |
19 | |
20 | e.printStackTrace() ; |
21 | } } |
22 | |
23 | if(conn != null){ // 关闭连接对象 |
24 | |
25 | try{ |
26 | |
27 | conn.close() ; |
28 | |
29 | }catch(SQLException e){ |
30 | |
31 | e.printStackTrace() ; |
32 | |
33 | } } |
34 |
实验使用mysql数据库,使用myeclipse工具新建一个类,命名为 JDBCTest,可以使用Navicat for MySQL可视化数据库操作,新建数据库users,在数据库users里添加 表user_table( UserId,UserName,PassWord)),有三个字段,本示例主要用于演示数据库连接,连接成功后,插入一条数据。具体内容如下
01 | import java.sql.*; |
02 | public class JDBCTest { |
03 | |
04 | /** |
05 | * @param args |
06 | * @throws ClassNotFoundException |
07 | * @throws SQLException |
08 | */ |
09 | public static void main(String[] args) throws ClassNotFoundException, SQLException { |
10 | //第一步:打开数据库 需要用户名,密码,数据库地址,数据库名称; |
11 | String username = "root"; |
12 | String password = "123456"; |
13 | |
14 | String url = "jdbc:mysql://localhost:3306/users"; |
15 | //1.加载数据库驱动 |
16 | Class.forName("com.mysql.jdbc.Driver"); |
17 | //2.创建是数据库连接 |
18 | Connection conn = DriverManager.getConnection(url, username, password); |
19 | |
20 | System.out.println("数据库连接成功!"); |
21 | //第二步:操作数据库; |
22 | String sql=" insert into user_table ( UserId,UserName,PassWord) values (5,'song','ss') "; |
23 | PreparedStatement pt=conn.prepareStatement( sql ); |
24 | pt.executeUpdate( ); |
25 | //第三步:关闭数据库; |
26 | conn.close(); |
27 | System.out.println("数据库操作成功!"); |
28 | |
29 | } |
30 | |
31 | } |
001 002 <PRE class=java name="code">package chp07;003 004 import java.sql.Connection;005 import java.sql.DriverManager;006 import java.sql.ResultSet;007 import java.sql.SQLException;008 import java.sql.Statement;009 010 public class JDBC_Test {011 // 创建静态全局变量
012 static Connection conn;013 014 static Statement st;015 016 public static void main(String[] args) {017 insert(); //插入添加记录018 update(); //更新记录数据019 delete(); //删除记录020 query(); //查询记录并显示021 }
022 023 /* 插入数据记录,并输出插入的数据记录数*/
024 public static void insert() {025 026 conn = getConnection(); // 首先要获取连接,即连接到数据库027 028 try {029 String sql = "INSERT INTO staff(name, age, sex,address, depart, worklen,wage)"030 + " VALUES ('Tom1', 32, 'M', 'china','Personnel','3','3000')"; // 插入数据的sql语句031 032 st = (Statement) conn.createStatement(); // 创建用于执行静态sql语句的Statement对象033 034 int count = st.executeUpdate(sql); // 执行插入操作的sql语句,并返回插入数据的个数035 036 System.out.println("向staff表中插入 " + count + " 条数据"); //输出插入操作的处理结果037 038 conn.close(); //关闭数据库连接039 040 } catch (SQLException e) {041 System.out.println("插入数据失败" + e.getMessage());042 }
043 }
044 045 /* 更新符合要求的记录,并返回更新的记录数目*/
046 public static void update() {047 conn = getConnection(); //同样先要获取连接,即连接到数据库048 try {049 String sql = "update staff set wage='2200' where name = 'lucy'";// 更新数据的sql语句050 051 st = (Statement) conn.createStatement(); //创建用于执行静态sql语句的Statement对象,st属局部变量052 053 int count = st.executeUpdate(sql);// 执行更新操作的sql语句,返回更新数据的个数054 055 System.out.println("staff表中更新 " + count + " 条数据"); //输出更新操作的处理结果056 057 conn.close(); //关闭数据库连接058 059 } catch (SQLException e) {060 System.out.println("更新数据失败");061 }
062 }
063 064 /* 查询数据库,输出符合要求的记录的情况*/
065 public static void query() {066 067 conn = getConnection(); //同样先要获取连接,即连接到数据库068 try {069 String sql = "select * from staff"; // 查询数据的sql语句070 st = (Statement) conn.createStatement(); //创建用于执行静态sql语句的Statement对象,st属局部变量071 072 ResultSet rs = st.executeQuery(sql); //执行sql查询语句,返回查询数据的结果集073 System.out.println("最后的查询结果为:");074 while (rs.next()) { // 判断是否还有下一个数据075 076 // 根据字段名获取相应的值
077 String name = rs.getString("name");078 int age = rs.getInt("age");079 String sex = rs.getString("sex");080 String address = rs.getString("address");081 String depart = rs.getString("depart");082 String worklen = rs.getString("worklen");083 String wage = rs.getString("wage");084 085 //输出查到的记录的各个字段的值
086 System.out.println(name + " " + age + " " + sex + " " + address087 + " " + depart + " " + worklen + " " + wage);088 089 }
090 conn.close(); //关闭数据库连接091 092 } catch (SQLException e) {093 System.out.println("查询数据失败");094 }
095 }
096 097 /* 删除符合要求的记录,输出情况*/
098 public static void delete() {099 100 conn = getConnection(); //同样先要获取连接,即连接到数据库101 try {102 String sql = "delete from staff where name = 'lili'";// 删除数据的sql语句103 st = (Statement) conn.createStatement(); //创建用于执行静态sql语句的Statement对象,st属局部变量104 105 int count = st.executeUpdate(sql);// 执行sql删除语句,返回删除数据的数量106 107 System.out.println("staff表中删除 " + count + " 条数据\n"); //输出删除操作的处理结果108 109 conn.close(); //关闭数据库连接110 111 } catch (SQLException e) {112 System.out.println("删除数据失败");113 }
114 115 }
116 117 /* 获取数据库连接的函数*/
118 public static Connection getConnection() {119 Connection con = null; //创建用于连接数据库的Connection对象120 try {121 Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动122 123 con = DriverManager.getConnection(124 "jdbc:mysql://localhost:3306/myuser", "root", "root");// 创建数据连接125 126 } catch (Exception e) {127 System.out.println("数据库连接失败" + e.getMessage());128 }
129 return con; //返回所建立的数据库连接130 }
131 }
132 PRE><BR>133 <PRE>PRE>134 <P>P>135 <P><STRONG>项目部署到服务器,然后运行结果:STRONG>P>136 <P>P>137 <PRE>PRE>138 <PRE>PRE>139 <PRE>PRE>140