一、什么是JDBC
JDBC(Java Data Base Connectivity,java數據庫連接)是一種用於執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基准,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。
二、JDBC編碼步驟
0、前提:拷貝數據庫的驅動到構建路徑中(classpath)
1、注冊驅動
2、獲取與數據庫的鏈接
3、創建代表SQL語句的對象
4、執行SQL語句
5、如果是查詢語句,需要遍歷結果集
6、釋放占用的資源
三、代碼實現
1、在終端或者navicat中創建一個表:users, 如下圖:
2、創建一個名為JdbcDemo1的類,並導入包:mysql-connector-java-5.0.8-bin.jar, JdbcDemo1代碼如下:
1 package com.bigshow1949.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 9 /* 10 create table users( 11 id int primary key auto_increment, 12 name varchar(40), 13 password varchar(40), 14 email varchar(60), 15 birthday date 16 )character set utf8 collate utf8_general_ci; 17 18 insert into users(name,password,email,birthday) values('zs','123456','zs@sina.com','1980-12-04'); 19 insert into users(name,password,email,birthday) values('lisi','123456','lisi@sina.com','1981-12-04'); 20 insert into users(name,password,email,birthday) values('wangwu','123456','wangwu@sina.com','1979-12-04'); 21 */ 22 23 //JDBC的編碼步驟: 24 //查詢users表中的所有數據,打印到控制台上 25 public class JdbcDemo1 { 26 27 public static void main(String[] args) throws SQLException { 28 // 1、注冊驅動 29 DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 30 // 2、獲取與數據庫的鏈接 31 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15", "root", "sorry"); 32 //System.out.println(conn.getClass().getName()); 要想知道具體類型,就這么辦 33 // 3、創建代表SQL語句的對象 34 Statement stmt = conn.createStatement(); 35 // 4、執行SQL語句 36 ResultSet rs = stmt.executeQuery("select id,name,password,email,birthday from users"); 37 // 5、如果是查詢語句,需要遍歷結果集 38 while(rs.next()){ 39 System.out.println("---------------------"); 40 System.out.println(rs.getObject("id")); 41 System.out.println(rs.getObject("name")); 42 System.out.println(rs.getObject("password")); 43 System.out.println(rs.getObject("email")); 44 System.out.println(rs.getObject("birthday")); 45 } 46 // 6、釋放占用的資源 47 rs.close(); 48 stmt.close(); 49 conn.close(); 50 } 51 52 }
3、運行代碼,打印結果:
成功連接, 並讀取了數據庫中的數據!!!
四、DriverManager詳解
DriverManager作用:
a、注冊驅動:
方式一:(不建議使用)
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
原因:1、依賴具體驅動。2、導致驅動注冊2遍
方式二:(建議)
Class.forName("com.mysql.jdbc.Driver");
b、獲取與數據庫的鏈接
url:SUN和數據庫廠商間的協議。具體查閱數據庫的文檔。
public static Connection getConnection(String url,String user,String password) throws SQLException
public static Connection getConnection(String url,Properties info) throws SQLException
public static Connection getConnection(String url) throws SQLException
Connection作用:
所有的數據庫操作都是基於鏈接之上的。
Statement createStatement():創建向數據庫發送sql的statement對象。
所以代碼修改為:
1 package com.bigshow1949.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.Properties; 9 10 //DriverManager詳解 11 public class JdbcDemo2 { 12 13 public static void main(String[] args) throws Exception { 14 //方式一:不建議使用 15 // DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 16 //方式二: 17 Class.forName("com.mysql.jdbc.Driver"); 18 19 //--------------------------------------------------------------------------------------- 20 // 2、獲取與數據庫的鏈接 21 //方式一: 22 // Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15", "root", "sorry"); 23 24 //方式二: 25 // Properties props = new Properties(); 26 // props.setProperty("user", "root");// 參數名:參考數據庫的文檔 27 // props.setProperty("password", "sorry"); 28 // props.setProperty("useUnicode", "true");//編碼有關的參數 29 // props.setProperty("characterEncoding", "utf8"); 30 // Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15",props); 31 32 //方式三 33 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15?user=root&password=sorry"); 34 35 //System.out.println(conn.getClass().getName()); 要想知道具體類型,就這么辦 36 // 3、創建代表SQL語句的對象 37 Statement stmt = conn.createStatement(); 38 // 4、執行SQL語句 39 ResultSet rs = stmt.executeQuery("select id,name,password,email,birthday from users"); 40 // 5、如果是查詢語句,需要遍歷結果集 41 while(rs.next()){ 42 System.out.println("---------------------"); 43 System.out.println(rs.getObject("id")); 44 System.out.println(rs.getObject("name")); 45 System.out.println(rs.getObject("password")); 46 System.out.println(rs.getObject("email")); 47 System.out.println(rs.getObject("birthday")); 48 } 49 // 6、釋放占用的資源 50 rs.close(); 51 stmt.close(); 52 conn.close(); 53 } 54 55 }
五、Statement詳解
作用:代表SQL語句對象。可以向數據庫發送任何的SQL語句
ResultSet executeQuery(String sql):sql一般都是查詢語句
int executeUpdate(String sql):sql一般是DML語句。insert update delete。返回值,操作幾條記錄。
boolean execute(String sql):sql可以是任意的語句。返回值不是代表成功與否。如果是查詢語句,就有結果集,返回true。沒有返回結果集的,返回false。
代碼展示:
1 package com.itheima.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.Properties; 9 10 //Statement詳解 11 public class JdbcDemo3 { 12 13 public static void main(String[] args) throws Exception { 14 Class.forName("com.mysql.jdbc.Driver"); 15 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15", "root", "sorry"); 16 // 3、創建代表SQL語句的對象 17 Statement stmt = conn.createStatement(); 18 19 // int num = stmt.executeUpdate("update users set password=123"); 20 // System.out.println(num); 21 22 // boolean b = stmt.execute("update users set password=111"); 23 // System.out.println(b); 24 25 // boolean b = stmt.execute("select * from users"); 26 // System.out.println(b); 27 // if(b){ 28 // ResultSet rs = stmt.getResultSet(); 29 // } 30 31 stmt.close(); 32 conn.close(); 33 } 34 35 }
六、ResultSet詳解
作用:封裝了查詢的結果集
boolean next():游標下移。返回值是有無記錄
boolean previous():游標上移。
boolean absolute(int count):定位到指定的行。第一行是1。
void beforeFirst():移動游標到第一行的前面。
void afterLast():移動游標到最后一行的后面。
先創建一個User類,代碼:
1 package com.bigshow1949.user; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 //實體Bean:Enity JavaBean 6 //Java類型和數據庫類型:對應關系。相對固定的 7 public class User implements Serializable { 8 private int id; 9 private String name; 10 private String password; 11 private String email; 12 private Date birthday; 13 public int getId() { 14 return id; 15 } 16 public void setId(int id) { 17 this.id = id; 18 } 19 public String getName() { 20 return name; 21 } 22 public void setName(String name) { 23 this.name = name; 24 } 25 public String getPassword() { 26 return password; 27 } 28 public void setPassword(String password) { 29 this.password = password; 30 } 31 public String getEmail() { 32 return email; 33 } 34 public void setEmail(String email) { 35 this.email = email; 36 } 37 public Date getBirthday() { 38 return birthday; 39 } 40 public void setBirthday(Date birthday) { 41 this.birthday = birthday; 42 } 43 @Override 44 public String toString() { 45 return "User [id=" + id + ", name=" + name + ", password=" + password 46 + ", email=" + email + ", birthday=" + birthday + "]"; 47 } 48 49 }
ResultSet代碼展示:
1 package com.bigshow1949.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.Statement; 7 import java.util.ArrayList; 8 import java.util.List; 9 10 import com.bigshow1949.user.User; 11 12 //ResultSet詳解 13 public class JdbcDemo4 { 14 15 public static void main(String[] args) throws Exception { 16 Class.forName("com.mysql.jdbc.Driver"); 17 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15", "root", "sorry"); 18 Statement stmt = conn.createStatement(); 19 ResultSet rs = stmt.executeQuery("select id,name,password,email,birthday from users"); 20 // rs.afterLast(); 21 // boolean b = rs.previous(); 22 // if(b){ 23 // User user = new User(); 24 // user.setId(rs.getInt("id")); 25 // user.setName(rs.getString("name")); 26 // user.setPassword(rs.getString("password")); 27 // user.setEmail(rs.getString("email")); 28 // user.setBirthday(rs.getDate("birthday")); 29 // System.out.println(user); 30 // }else{ 31 // System.out.println("沒有結果"); 32 // } 33 34 // 5、如果是查詢語句,需要遍歷結果集 35 List<User> users = new ArrayList<User>(); 36 while(rs.next()){ 37 System.out.println("---------------------"); 38 // System.out.println(rs.getObject("id"));//不考慮字段的類型 39 // System.out.println(rs.getObject("name")); 40 // System.out.println(rs.getObject("password")); 41 // System.out.println(rs.getObject("email")); 42 // System.out.println(rs.getObject("birthday")); 43 44 // System.out.println(rs.getObject(1));//第一列。所用從1開始。 一般很少用,做JDBC有關的框架時用 45 // System.out.println(rs.getObject(2)); 46 // System.out.println(rs.getObject(3)); 47 // System.out.println(rs.getObject(4)); 48 // System.out.println(rs.getObject(5)); 49 User user = new User(); 50 // user.setId((Integer)rs.getObject("id")); 51 user.setId(rs.getInt("id")); 52 user.setName(rs.getString("name")); 53 user.setPassword(rs.getString("password")); 54 user.setEmail(rs.getString("email")); 55 user.setBirthday(rs.getDate("birthday")); 56 57 users.add(user); 58 59 } 60 rs.close(); 61 stmt.close(); 62 conn.close(); 63 64 for(User u:users) 65 System.out.println(u); 66 } 67 68 }
七、釋放資源&JDBC編碼的代碼模板
如果當程序運行到users.add(user);就拋出異常了,那么rs.close();stmt.close();conn.close();就不會運行了,資源就不會釋放了,所以要加上finally,不論程序是否異常都會執行,在這里釋放資源。如果程序運行到stmt = conn.createStatement();就拋出異常,那么rs的值仍然是null,所以在finally里要判斷下是否為null。
1 package com.bigshow1949.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.ArrayList; 9 import java.util.List; 10 11 import com.bigshow1949.user.User; 12 13 //釋放資源 14 //JDBC編碼的代碼模板 15 public class JdbcDemo5 { 16 17 public static void main(String[] args) { 18 Connection conn = null; 19 Statement stmt = null; 20 ResultSet rs = null; 21 try { 22 Class.forName("com.mysql.jdbc.Driver"); 23 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15", "root", "sorry"); 24 stmt = conn.createStatement(); 25 rs = stmt.executeQuery("select id,name,password,email,birthday from users"); 26 List<User> users = new ArrayList<User>(); 27 while(rs.next()){ 28 User user = new User(); 29 user.setId(rs.getInt("id")); 30 user.setName(rs.getString("name")); 31 user.setPassword(rs.getString("password")); 32 user.setEmail(rs.getString("email")); 33 user.setBirthday(rs.getDate("birthday")); 34 users.add(user); 35 } 36 37 } catch (Exception e) { 38 e.printStackTrace(); 39 }finally{ 40 if(rs!=null){ 41 try { 42 rs.close(); 43 } catch (SQLException e) { 44 e.printStackTrace(); 45 } 46 rs = null; 47 } 48 if(stmt!=null){ 49 try { 50 stmt.close(); 51 } catch (SQLException e) { 52 e.printStackTrace(); 53 } 54 stmt = null; 55 } 56 if(conn!=null){ 57 try { 58 conn.close(); 59 } catch (SQLException e) { 60 e.printStackTrace(); 61 } 62 conn = null; 63 } 64 } 65 66 } 67 68 }
八、Jdbc工具類
我們發現每次增刪改查,finally里跟注冊里的代碼都一樣,所以這部分代碼單獨抽取出來,寫一個工具類,所以就有了JdbcUtil工具類。
首先,新建配置文件:dbcfg.properties,把一些字符串變量寫在配置文件里,然后程序直接讀取配置文件
代碼:
1 driverClass=com.mysql.jdbc.Driver 2 url=jdbc:mysql://localhost:3306/day15 3 user=root 4 password=sorry
JdbcUtil工具類代碼:
1 package com.bigshow1949.util; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.sql.Connection; 6 import java.sql.DriverManager; 7 import java.sql.ResultSet; 8 import java.sql.SQLException; 9 import java.sql.Statement; 10 import java.util.Properties; 11 12 //工具類 13 public class JdbcUtil { 14 15 private static String driverClass; 16 private static String url; 17 private static String user; 18 private static String password; 19 20 static{ 21 try { 22 ClassLoader cl = JdbcUtil.class.getClassLoader(); 23 InputStream in = cl.getResourceAsStream("dbcfg.properties"); 24 Properties props = new Properties(); 25 props.load(in); 26 driverClass = props.getProperty("driverClass"); 27 url = props.getProperty("url"); 28 user = props.getProperty("user"); 29 password = props.getProperty("password"); 30 31 Class.forName(driverClass); 32 } catch (Exception e) { 33 throw new ExceptionInInitializerError(e); 34 } 35 } 36 37 38 public static Connection getConnection() throws Exception{ 39 Connection conn = DriverManager.getConnection(url,user, password); 40 return conn; 41 } 42 public static void release(ResultSet rs,Statement stmt,Connection conn){ 43 if(rs!=null){ 44 try { 45 rs.close(); 46 } catch (SQLException e) { 47 e.printStackTrace(); 48 } 49 rs = null; 50 } 51 if(stmt!=null){ 52 try { 53 stmt.close(); 54 } catch (SQLException e) { 55 e.printStackTrace(); 56 } 57 stmt = null; 58 } 59 if(conn!=null){ 60 try { 61 conn.close(); 62 } catch (SQLException e) { 63 e.printStackTrace(); 64 } 65 conn = null; 66 } 67 } 68 }
注意:注冊驅動 Class.forName(driverClass);不要寫在連接里,不然每次連接都要注冊一次驅動,沒有必要,初始化一次就夠了。
測試代碼:
1 package com.bigshow1949.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.ResultSet; 5 import java.sql.Statement; 6 7 import org.junit.Test; 8 9 import com.bigshow1949.util.JdbcUtil; 10 11 public class JdbcDemo6 { 12 13 @Test 14 public void testAdd(){ 15 Connection conn = null; 16 Statement stmt = null; 17 ResultSet rs = null; 18 try{ 19 conn = JdbcUtil.getConnection(); 20 stmt = conn.createStatement(); 21 stmt.executeUpdate("insert into users (name,password,email,birthday) values ('wangwu','123','wangwu@itcast.cn','2000-10-01')"); 22 }catch(Exception e){ 23 throw new RuntimeException(e); 24 }finally{ 25 JdbcUtil.release(rs, stmt, conn); 26 } 27 } 28 @Test 29 public void testUpdate(){ 30 Connection conn = null; 31 Statement stmt = null; 32 ResultSet rs = null; 33 try{ 34 conn = JdbcUtil.getConnection(); 35 stmt = conn.createStatement(); 36 stmt.executeUpdate("update users set password=111 where id=4"); 37 }catch(Exception e){ 38 throw new RuntimeException(e); 39 }finally{ 40 JdbcUtil.release(rs, stmt, conn); 41 } 42 } 43 @Test 44 public void testDelete(){ 45 Connection conn = null; 46 Statement stmt = null; 47 ResultSet rs = null; 48 try{ 49 conn = JdbcUtil.getConnection(); 50 stmt = conn.createStatement(); 51 stmt.executeUpdate("delete from users where id=1"); 52 }catch(Exception e){ 53 throw new RuntimeException(e); 54 }finally{ 55 JdbcUtil.release(rs, stmt, conn); 56 } 57 } 58 }
九、項目文件結構
項目代碼下載:
https://github.com/BigShow1949/01-JDBC