了解JDBC
JDBC Intro
JDBC stands for Java Database Connectivity. Java与各种数据库连接的标准Java api.
The JDBC library includes APIs for each of the tasks commonly associated with database usage:
Making a connection to a database
Creating SQL or MySQL statements
Executing that SQL or MySQL queries in the database
Viewing & Modifying the resulting records
jdbc API由以下两个package构成:
Package java.sql Description
javax.sql.RowSet
group of interfaces, can be customized to use and update data from a spread sheet, flat file, or any other tabular data source.Package javax.sql Description
java.sql
package and, as of the version 1.4 release, is included in the Java Platform, Standard Edition (Java SETM). It remains an essential part of the Java Platform, Enterprise Edition (Java EETM).
The javax.sql
package provides for the following:
- The
DataSource
interface as an alternative to theDriverManager
for establishing a connection with a data source - Connection pooling and Statement pooling
- Distributed transactions
- Rowsets
Applications use the DataSource
and RowSet
APIs directly, but the connection pooling and distributed transaction APIs are used internally by the middle-tier infrastructure.
JDBC API主要包括(斜体代表接口,需驱动程序提供者来具体实现):
- DriverManager:负责加载各种不同驱动程序(Driver),并根据不同的请求,向调用者返回相应的数据库连接(Connection)。
- Driver:驱动程序,会将自身加载到DriverManager中去,并处理相应的请求并返回相应的数据库连接(Connection)。
- Connection:数据库连接,负责进行与数据库间的通讯,SQL执行以及事务处理都是在某个特定Connection环境中进行的。可以产生用以执行SQL的Statement。
- Statement:用以执行SQL查询和更新(针对静态SQL语句和单次执行)。
- PreparedStatement:用以执行包含动态参数的SQL查询和更新(在服务器端编译,允许重复执行以提高效率)。
- CallableStatement:用以调用数据库中的存储过程。
- SQLException:代表在数据库连接的建立和关闭和SQL语句的执行过程中发生了例外情况(即错误)。
指定driver的方法(old):
Class.forName("com.mysql.jdbc.Driver"); // method 1 new com.mysql.jdbc.Driver() ; //method 2, mysql as an exmple, 创建driver对象,加载数据库驱动 System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver"); // method 3
注意JDBC 4.0 已不需要手动注册driver, JDBC文档原文:
Applications no longer need to explictly load JDBC drivers using Class.forName()
. Existing programs which currently load JDBC drivers using Class.forName()
will continue to work without modification.
JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver
JDBC4.0 Example
mysql-connector-java:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.4</version> </dependency>
Code Example
Driver: mysql-connector-java
1 /** 2 * Created by artificerPi on 2016/2/23. 3 * JDBC Program, create database 4 * 5 */ 6 7 // STEP 1. Import required packages 8 import java.sql.*; 9 10 public class JDBCExample { 11 // JDBC driver name and database URL 12 static final String JDBC_DRIVER="com.mysql.jdbc.Driver"; 13 static final String DB_URL="jdbc:mysql://localhost"; 14 15 // Database credentials 16 static final String USER ="root"; 17 static final String PASS="passw0rd"; 18 19 public static void main(String[] args){ 20 Connection conn = null; 21 Statement stmt = null; 22 23 try{ 24 //STEP2 : Register JDBC driver 25 Class.forName(JDBC_DRIVER); // load driver class 26 27 //STEP3 : Open a connection 28 System.out.println("Connecting to database..."); 29 conn = DriverManager.getConnection(DB_URL,USER,PASS); 30 31 // STEP 4: Execute a query 32 System.out.println("Creating statement ..."); 33 stmt = conn.createStatement(); 34 35 String sql; 36 sql="CREATE DATABASE STUDENTS"; 37 stmt.executeUpdate(sql); 38 System.out.println("Database created successfully..."); 39 }catch(SQLException se){ 40 //Handle errors for JDBC 41 se.printStackTrace(); 42 }catch (Exception e){ 43 // Handle errors for Class.forName 44 e.printStackTrace(); 45 }finally { 46 //STEP5: finally block used to close resources 47 try{ 48 if (stmt != null) 49 stmt.close(); 50 }catch (SQLException se2){// nothing we can do 51 }try{ 52 if(conn!=null) 53 conn.close(); 54 }catch (SQLException se){ 55 se.printStackTrace(); 56 }// end finally try 57 }// end try 58 System.out.println("GoodBye!"); 59 }//end main 60 }// end FirstExample
使用PreparedStatement
1 PreparedStatement ps = null; 2 ResultSet rs = null; 3 try { 4 ps = conn.prepareStatement("SELECT i.*, j.* FROM Omega i, Zappa j WHERE i = ? AND j = ?"); 5 // 使用问号作为参数的标示 6 7 // 进行参数设置 8 // 与大部分Java API中下标的使用方法不同,字段的下标从1开始,1代表第一个问号 9 // 当然,还有其他很多针对不同类型的类似的PreparedStatement.setXXX()方法 10 ps.setString(1, "Poor Yorick"); 11 ps.setInt(2, 8008); 12 13 // 结果集 14 rs = ps.executeQuery(); 15 while (rs.next()) { 16 int numColumns = rs.getMetaData().getColumnCount(); 17 for (int i = 1; i <= numColumns; i++) { 18 // 与大部分Java API中下标的使用方法不同,字段的下标从1开始 19 // 当然,还有其他很多的方式(ResultSet.getXXX())获取数据 20 System.out.println("COLUMN " + i + " = " + rs.getObject(i)); 21 } 22 } 23 } catch (SQLException e) { 24 // 异常处理 25 } finally { // 使用finally进行资源释放 26 try { 27 rs.close(); 28 ps.close(); 29 } catch (SQLException e) { 30 } // 异常处理:忽略close()时的错误 31 }
事务 Example
1 boolean autoCommitDefault = conn.getAutoCommit(); 2 try { 3 conn.setAutoCommit(false); 4 5 /* 在此基于有事务控制的conn执行你的代码 */ 6 7 conn.commit(); 8 } catch (Throwable e) { 9 try { 10 conn.rollback(); 11 } catch (Throwable ignore) { 12 } 13 throw e; 14 } finally { 15 try { 16 conn.setAutoCommit(autoCommitDefault); 17 } catch (Throwable ignore) { 18 } 19 }
JDBC Cycle
参考:
http://www.tutorialspoint.com/jdbc/
https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/
https://zh.wikipedia.org/wiki/Java%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5
https://www.ntu.edu.sg/home/ehchua/programming/java/JDBC_Basic.html