JDBC詳解

一撞蜂、相關(guān)概念

  1. 什么是JDBC
    JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL語(yǔ)句的Java API,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪問俭嘁,它由一組用Java語(yǔ)言編寫的類和接口組成。JDBC提供了一種基準(zhǔn),據(jù)此可以構(gòu)建更高級(jí)的工具和接口,使數(shù)據(jù)庫(kù)開發(fā)人員能夠編寫數(shù)據(jù)庫(kù)應(yīng)用程序遭庶。

  2. 數(shù)據(jù)庫(kù)驅(qū)動(dòng)
    我們安裝好數(shù)據(jù)庫(kù)之后,我們的應(yīng)用程序也是不能直接使用數(shù)據(jù)庫(kù)的稠屠,必須要通過相應(yīng)的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序峦睡,通過驅(qū)動(dòng)程序去和數(shù)據(jù)庫(kù)打交道。其實(shí)也就是數(shù)據(jù)庫(kù)廠商的JDBC接口實(shí)現(xiàn)完箩,即對(duì)Connection等接口的實(shí)現(xiàn)類的jar文件赐俗。

二、常用接口

  1. Driver接口
    Driver接口由數(shù)據(jù)庫(kù)廠家提供弊知,作為java開發(fā)人員,只需要使用Driver接口就可以了粱快。在編程中要連接數(shù)據(jù)庫(kù)秩彤,必須先裝載特定廠商的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,不同的數(shù)據(jù)庫(kù)有不同的裝載方法事哭。如:
    裝載MySql驅(qū)動(dòng):Class.forName("com.mysql.jdbc.Driver");
    裝載Oracle驅(qū)動(dòng):Class.forName("oracle.jdbc.driver.OracleDriver");

  2. Connection接口
    Connection與特定數(shù)據(jù)庫(kù)的連接(會(huì)話)漫雷,在連接上下文中執(zhí)行sql語(yǔ)句并返回結(jié)果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定義的數(shù)據(jù)庫(kù)Connection連接上鳍咱。

    • 連接MySql數(shù)據(jù)庫(kù):Connection conn = - DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");
    • 連接Oracle數(shù)據(jù)庫(kù):Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user", "password");
    • 連接SqlServer數(shù)據(jù)庫(kù):Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database", "user", "password");

    常用方法:

    • createStatement():創(chuàng)建向數(shù)據(jù)庫(kù)發(fā)送sql的statement對(duì)象降盹。
    • prepareStatement(sql) :創(chuàng)建向數(shù)據(jù)庫(kù)發(fā)送預(yù)編譯sql的PrepareSatement對(duì)象。
    • prepareCall(sql):創(chuàng)建執(zhí)行存儲(chǔ)過程的callableStatement對(duì)象谤辜。
    • setAutoCommit(boolean autoCommit):設(shè)置事務(wù)是否自動(dòng)提交蓄坏。
    • commit() :在鏈接上提交事務(wù)。
    • rollback() :在此鏈接上回滾事務(wù)丑念。
  3. Statement接口
    用于執(zhí)行靜態(tài)SQL語(yǔ)句并返回它所生成結(jié)果的對(duì)象涡戳。
    三種Statement類:

    • Statement:由createStatement創(chuàng)建,用于發(fā)送簡(jiǎn)單的SQL語(yǔ)句(不帶參數(shù))脯倚。
    • PreparedStatement :繼承自Statement接口渔彰,由preparedStatement創(chuàng)建,用于發(fā)送含有一個(gè)或多個(gè)參數(shù)的SQL語(yǔ)句推正。PreparedStatement對(duì)象比Statement對(duì)象的效率更高恍涂,并且可以防止SQL注入,所以我們一般都使用PreparedStatement植榕。
    • CallableStatement:繼承自PreparedStatement接口再沧,由方法prepareCall創(chuàng)建,用于調(diào)用存儲(chǔ)過程内贮。

    常用Statement方法:

    • execute(String sql):運(yùn)行語(yǔ)句产园,返回是否有結(jié)果集
    • executeQuery(String sql):運(yùn)行select語(yǔ)句汞斧,返回ResultSet結(jié)果集。
    • executeUpdate(String sql):運(yùn)行insert/update/delete操作什燕,返回更新的行數(shù)粘勒。
    • addBatch(String sql) :把多條sql語(yǔ)句放到一個(gè)批處理中。
    • executeBatch():向數(shù)據(jù)庫(kù)發(fā)送一批sql語(yǔ)句執(zhí)行屎即。
  4. ResultSet接口
    ResultSet提供檢索不同類型字段的方法庙睡,常用的有:

    • getString(int index)、getString(String columnName):獲得在數(shù)據(jù)庫(kù)里是varchar技俐、char等類型的數(shù)據(jù)對(duì)象乘陪。
    • getFloat(int index)、getFloat(String columnName):獲得在數(shù)據(jù)庫(kù)里是Float類型的數(shù)據(jù)對(duì)象雕擂。
    • getDate(int index)啡邑、getDate(String columnName):獲得在數(shù)據(jù)庫(kù)里是Date類型的數(shù)據(jù)。
    • getBoolean(int index)井赌、getBoolean(String columnName):獲得在數(shù)據(jù)庫(kù)里是Boolean類型的數(shù)據(jù)谤逼。
    • getObject(int index)、getObject(String columnName):獲取在數(shù)據(jù)庫(kù)里任意類型的數(shù)據(jù)仇穗。

    ResultSet還提供了對(duì)結(jié)果集進(jìn)行滾動(dòng)的方法:

    • next():移動(dòng)到下一行
    • Previous():移動(dòng)到前一行
    • absolute(int row):移動(dòng)到指定行
    • beforeFirst():移動(dòng)resultSet的最前面流部。
    • afterLast() :移動(dòng)到resultSet的最后面。

使用后依次關(guān)閉對(duì)象及連接:ResultSet → Statement → Connection

三纹坐、使用JDBC的步驟

加載JDBC驅(qū)動(dòng)程序 → 建立數(shù)據(jù)庫(kù)連接Connection → 創(chuàng)建執(zhí)行SQL的語(yǔ)句Statement → 處理執(zhí)行結(jié)果ResultSet → 釋放資源

  1. 注冊(cè)驅(qū)動(dòng) (只做一次)
    方式一:Class.forName(“com.MySQL.jdbc.Driver”);
     推薦這種方式枝冀,不會(huì)對(duì)具體的驅(qū)動(dòng)類產(chǎn)生依賴。
     方式二:DriverManager.registerDriver(com.mysql.jdbc.Driver);
     會(huì)造成DriverManager中產(chǎn)生兩個(gè)一樣的驅(qū)動(dòng)耘子,并會(huì)對(duì)具體的驅(qū)動(dòng)類產(chǎn)生依賴果漾。

  2. 建立連接

    Connection conn = DriverManager.getConnection(url, user, password);
    

    URL用于標(biāo)識(shí)數(shù)據(jù)庫(kù)的位置,通過URL地址告訴JDBC程序連接哪個(gè)數(shù)據(jù)庫(kù)拴还,URL的寫法為:



    其他參數(shù)如:useUnicode=true&characterEncoding=utf8

  3. 創(chuàng)建執(zhí)行SQL語(yǔ)句的statement

//Statement
String id = "5";
String sql = "delete from table where id=" +  id;
Statement st = conn.createStatement();
st.executeQuery(sql);
//存在sql注入的危險(xiǎn)
//如果用戶傳入的id為“5 or 1=1”跨晴,那么將刪除表中的所有記錄
1 //PreparedStatement 有效的防止sql注入(SQL語(yǔ)句在程序運(yùn)行前已經(jīng)進(jìn)行了預(yù)編譯,當(dāng)運(yùn)行時(shí)動(dòng)態(tài)地把參數(shù)傳給PreprareStatement時(shí),即使參數(shù)里有敏感字符如 or '1=1'也數(shù)據(jù)庫(kù)會(huì)作為一個(gè)參數(shù)一個(gè)字段的屬性值來處理而不會(huì)作為一個(gè)SQL指令)
2 String sql = “insert into user (name,pwd) values(?,?)”;  
3 PreparedStatement ps = conn.preparedStatement(sql);  
4 ps.setString(1, “col_value”);  //占位符順序從1開始
5 ps.setString(2, “123456”); //也可以使用setObject
6 ps.executeQuery(); 
  1. 處理執(zhí)行結(jié)果(ResultSet)
1 ResultSet rs = ps.executeQuery();  
2 While(rs.next()){  
3     rs.getString(“col_name”);  
4     rs.getInt(1);  
5     //…
6 } 
  1. 釋放資源
 //數(shù)據(jù)庫(kù)連接(Connection)非常耗資源片林,盡量晚創(chuàng)建端盆,盡量早的釋放 //都要加try catch 以防前面關(guān)閉出錯(cuò),后面的就不執(zhí)行了
 1 try {
 2     if (rs != null) {
 3         rs.close();
 4     }
 5 } catch (SQLException e) {
 6     e.printStackTrace();
 7 } finally {
 8     try {
 9         if (st != null) {
10             st.close();
11         }
12     } catch (SQLException e) {
13         e.printStackTrace();
14     } finally {
15         try {
16             if (conn != null) {
17                 conn.close();
18             }
19         } catch (SQLException e) {
20             e.printStackTrace();
21         }
22     }
23 }

四费封、事務(wù)(ACID特點(diǎn)焕妙、隔離級(jí)別、提交commit弓摘、回滾rollback)

  • 事務(wù)基本概率

    一組要么同時(shí)執(zhí)行成功焚鹊,要么同時(shí)執(zhí)行失敗的SQL語(yǔ)句。是數(shù)據(jù)庫(kù)操作的一個(gè)單元韧献!

    • 事務(wù)開始于:
      連接到數(shù)據(jù)庫(kù)上末患,并執(zhí)行一條DML語(yǔ)句(INSERT研叫、UPDATE或DELETE)。
      前一個(gè)事務(wù)結(jié)束后璧针,又輸入了另一個(gè)DML語(yǔ)句嚷炉。
    • 事務(wù)結(jié)束于:
      執(zhí)行COMMIT或ROLLBACK語(yǔ)句。
      執(zhí)行一條DDL語(yǔ)句探橱,例如CREATE TABLE語(yǔ)句申屹;在這種情況下,會(huì)自動(dòng)執(zhí)行COMMIT語(yǔ)句隧膏。
      執(zhí)行一條DCL語(yǔ)句哗讥,例如GRANT語(yǔ)句;在這種情況下胞枕,會(huì)自動(dòng)執(zhí)行COMMIT語(yǔ)句杆煞。
      斷開與數(shù)據(jù)庫(kù)的連接。
      執(zhí)行了一條DML語(yǔ)句腐泻,該語(yǔ)句卻失敗了索绪;在這種情況下,會(huì)為這個(gè)無效的DML語(yǔ)句執(zhí)行ROLLBACK語(yǔ)句贫悄。
  • 事務(wù)的四大特點(diǎn)(ACID)
    • atomicity(原子性)
      表示一個(gè)事務(wù)內(nèi)的所有操作是一個(gè)整體,要么全部成功娘摔,要么全部失斦埂;
    • consistency(一致性)
      表示一個(gè)事務(wù)內(nèi)有一個(gè)操作失敗時(shí)凳寺,所有的更改過的數(shù)據(jù)都必須回滾到修改前的狀態(tài)鸭津。
    • isolation(隔離性)
      多個(gè)進(jìn)程互不干擾。
    • durability(持久性)
      持久性事務(wù)完成之后肠缨,它對(duì)于系統(tǒng)的影響是永久性的逆趋。
  • 事務(wù)隔離級(jí)別從低到高:
    • 讀取未提交(Read Uncommitted)
    • 讀取已提交(Read Committed)
    • 可重復(fù)度(Repeatable Read)
    • 序列化(serializble)

批量處理Batch

  • 靈活指定SQL中的變量(PreparedStatement)
  • 對(duì)存儲(chǔ)過程進(jìn)行調(diào)用(CallableStatement)
  • 運(yùn)用事務(wù)處理(Transaction)
  • 批處理(Batch)
    對(duì)于大量的批處理,建議使用Statement晒奕,因?yàn)镻reparedStatement的預(yù)編譯空間有限闻书,當(dāng)數(shù)據(jù)量特別大時(shí),會(huì)發(fā)生異常脑慧。
  1. 插入2萬條數(shù)據(jù)的測(cè)試
 1 package com.test.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.SQLException;
 6 import java.sql.Statement;
 7 
 8 /**
 9  * 測(cè)試ResultSet結(jié)果集的基本用法
10  */
11 public class Demo05 {
12     public static void main(String[] args) {
13         Connection conn = null;
14         Statement stmt = null;
15 
16         try {
17             Class.forName("com.mysql.jdbc.Driver");
18             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","mysql");
19 
20             conn.setAutoCommit(false); //設(shè)為手動(dòng)提交
21 
22             long start = System.currentTimeMillis();
23 
24             stmt = conn.createStatement();
25             for (int i = 0; i < 20000; i++) {
26                 stmt.addBatch("insert into t_user (userName,pwd,regTime) values ('hao" + i + "',666666,now())");
27             }
28             stmt.executeBatch();
29             conn.commit();  //提交事務(wù)
30 
31             long end = System.currentTimeMillis();
32             System.out.println("插入200000條數(shù)據(jù)魄眉,耗時(shí)(ms):" + (end - start));
33 
34         } catch (ClassNotFoundException e) {
35             e.printStackTrace();
36         } catch (SQLException e) {
37             e.printStackTrace();
38         } finally{
39 
40             try {
41                 if (stmt!=null) {
42                     stmt.close();
43                 }
44             } catch (SQLException e) {
45                 e.printStackTrace();
46             }
47             try {
48                 if (conn!=null) {
49                     conn.close();
50                 }
51             } catch (SQLException e) {
52                 e.printStackTrace();
53             }
54         }
55     }
56 }

  1. 測(cè)試事務(wù)的基本概念和用法
 1 package com.test.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.PreparedStatement;
 6 import java.sql.SQLException;
 7 
 8 /**
 9  * 測(cè)試事務(wù)的基本概念和用法
10  */
11 public class Demo06 {
12     public static void main(String[] args) {
13         Connection conn = null;
14         PreparedStatement ps1 = null;
15         PreparedStatement ps2 = null;
16 
17         try {
18             Class.forName("com.mysql.jdbc.Driver");
19             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","mysql");
20 
21             conn.setAutoCommit(false); //JDBC中默認(rèn)是true,自動(dòng)提交事務(wù)
22 
23             ps1 = conn.prepareStatement("insert into t_user(userName,pwd)values(?,?)"); //事務(wù)開始
24             ps1.setObject(1, "小高");
25             ps1.setObject(2, "123");
26             ps1.execute();
27             System.out.println("第一次插入");
28 
29             try {
30                 Thread.sleep(5000);
31             } catch (InterruptedException e) {
32                 e.printStackTrace();
33             }
34 
35             ps2 = conn.prepareStatement("insert into t_user(userName,pwd)values(?,?,?)");   //模擬執(zhí)行失敗(values的參數(shù)寫成三個(gè)了)
36             //insert時(shí)出現(xiàn)異常,執(zhí)行conn.rollback
37             ps2.setObject(1, "小張");
38             ps2.setObject(2, "678");
39             ps2.execute();
40             System.out.println("第二次插入");    
41 
42             conn.commit();
43 
44         } catch (ClassNotFoundException e) {
45             e.printStackTrace();
46             try {
47                 conn.rollback();
48             } catch (SQLException e1) {
49                 e1.printStackTrace();
50             }
51         } catch (SQLException e) {
52             e.printStackTrace();
53         } finally{
54 
55             try {
56                 if (ps1!=null) {
57                     ps1.close();
58                 }
59             } catch (SQLException e) {
60                 e.printStackTrace();
61             }
62             try {
63                 if (ps2!=null) {
64                     ps2.close();
65                 }
66             } catch (SQLException e) {
67                 e.printStackTrace();
68             }
69             try {
70                 if (conn!=null) {
71                     conn.close();
72                 }
73             } catch (SQLException e) {
74                 e.printStackTrace();
75             }
76         }
77     }
78 }

輸出:

 1 第一次插入
 2 java.sql.SQLException: No value specified for parameter 3
 3     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
 4     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
 5     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
 6     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
 7     at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2611)
 8     at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2586)
 9     at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2510)
10     at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1316)
11     at com.test.jdbc.Demo06.main(Demo06.java:39)

五闷袒、時(shí)間處理(Date和Time以及Timestamp區(qū)別坑律、隨機(jī)日期生成)

java.util.Date

  • 子類:java.sql.Date
  • 子類:java.sql.Time
  • 子類:java.sql.Timestamp

測(cè)試時(shí)間處理(java.sql.Date,Time,Timestamp)

 1 package com.test.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.PreparedStatement;
 6 import java.sql.SQLException;
 7 import java.sql.Timestamp;
 8 import java.util.Random;
 9 
10 /**
11  * 測(cè)試時(shí)間處理(java.sql.Date,Time,Timestamp)
12  */
13 public class Demo07 {
14     public static void main(String[] args) {
15         Connection conn = null;
16         PreparedStatement ps = null;
17 
18         try {
19             Class.forName("com.mysql.jdbc.Driver");
20             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","mysql");
21 
22             for (int i = 0; i < 1000; i++) {
23 
24                 ps = conn.prepareStatement("insert into t_user(userName,pwd,regTime,lastLoginTime)values(?,?,?,?)");
25                 ps.setObject(1, "小高" + i);
26                 ps.setObject(2, "123");
27 
28                 //
29                 int random = 1000000000 + new Random().nextInt(1000000000); //隨機(jī)時(shí)間
30 
31                 java.sql.Date date = new java.sql.Date(System.currentTimeMillis() - random);    //插入隨機(jī)時(shí)間
32                 java.sql.Timestamp stamp = new Timestamp(System.currentTimeMillis());   //如果需要插入指定時(shí)間,可以使用Calendar囊骤、DateFormat
33                 ps.setDate(3, date);
34                 ps.setTimestamp(4, stamp);
35                 //
36                 ps.execute();
37             }
38 
39             System.out.println("插入");
40 
41         } catch (ClassNotFoundException e) {
42             e.printStackTrace();
43         } catch (SQLException e) {
44             e.printStackTrace();
45         } finally{
46 
47             try {
48                 if (ps!=null) {
49                     ps.close();
50                 }
51             } catch (SQLException e) {
52                 e.printStackTrace();
53             }
54             try {
55                 if (conn!=null) {
56                     conn.close();
57                 }
58             } catch (SQLException e) {
59                 e.printStackTrace();
60             }
61         }
62     }
63 }

測(cè)試時(shí)間處理(java.sql.Date,Time,Timestamp)晃择,取出指定時(shí)間段的數(shù)據(jù)

 1 package com.test.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.Date;
 5 import java.sql.DriverManager;
 6 import java.sql.PreparedStatement;
 7 import java.sql.ResultSet;
 8 import java.sql.SQLException;
 9 import java.text.DateFormat;
10 import java.text.ParseException;
11 import java.text.SimpleDateFormat;
12 
13 /**
14  * 測(cè)試時(shí)間處理(java.sql.Date,Time,Timestamp)冀值,取出指定時(shí)間段的數(shù)據(jù)
15  */
16 public class Demo08 {
17 
18     /**
19      * 將字符串代表的時(shí)間轉(zhuǎn)為long數(shù)字(格式:yyyy-MM-dd hh:mm:ss)
20      * @param dateStr
21      * @return
22      */
23     public static long str2DateTime(String dateStr){
24         DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
25 
26         try {
27             return format.parse(dateStr).getTime();
28         } catch (ParseException e) {
29             e.printStackTrace();
30             return 0;
31         }
32     }
33 
34     public static void main(String[] args) {
35         Connection conn = null;
36         PreparedStatement ps = null;
37         ResultSet rs = null;
38 
39         try {
40             Class.forName("com.mysql.jdbc.Driver");
41             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc","root","mysql");
42 
43             //
44             ps = conn.prepareStatement("select * from t_user where regTime > ? and regTime < ?");
45             java.sql.Date start = new java.sql.Date(str2DateTime("2016-06-20 00:00:00"));
46             java.sql.Date end = new java.sql.Date(str2DateTime("2016-06-24 00:00:00"));
47 
48             ps.setObject(1, start);
49             ps.setObject(2, end);
50 
51             rs = ps.executeQuery();
52             while(rs.next()){
53                 System.out.println(rs.getInt("id") + "--" + rs.getString("userName")+"--"+rs.getDate("regTime"));
54             }
55             //
56 
57         } catch (ClassNotFoundException e) {
58             e.printStackTrace();
59         } catch (SQLException e) {
60             e.printStackTrace();
61         } finally{
62 
63             try {
64                 if (ps!=null) {
65                     ps.close();
66                 }
67             } catch (SQLException e) {
68                 e.printStackTrace();
69             }
70             try {
71                 if (conn!=null) {
72                     conn.close();
73                 }
74             } catch (SQLException e) {
75                 e.printStackTrace();
76             }
77         }
78     }
79 }

六、總結(jié)(簡(jiǎn)單封裝宫屠、資源文件properties處理連接信息)

db.properties

 1 #右擊該properties文件--properties--Resource--Text file encoding列疗,選中other,選擇其它編碼方式。
 2 #如UTF-8或GBK,這樣就能在properties里面輸入中文激况,而不會(huì)自動(dòng)轉(zhuǎn)成Unicode了作彤。
 3 
 4 #java中的properties文件是一種配置文件,主要用于表達(dá)配置信息乌逐。
 5 #文件類型為*.properties竭讳,格式為文本文件,文件內(nèi)容是"鍵=值"的格式浙踢。
 6 #在properties文件中绢慢,可以用"#"來作注釋
 7 
 8 #MySQL連接配置
 9 mysqlDriver=com.mysql.jdbc.Driver
10 mysqlURL=jdbc:mysql://localhost:3306/testjdbc
11 mysqlUser=root
12 mysqlPwd=mysql
13 
14 #Oracle連接配置
15 #...

JDBCUtil工具類

 1 package com.test.jdbc;
 2 
 3 import java.io.IOException;
 4 import java.sql.Connection;
 5 import java.sql.DriverManager;
 6 import java.sql.ResultSet;
 7 import java.sql.SQLException;
 8 import java.sql.Statement;
 9 import java.util.Properties;
10 
11 public class JDBCUtil {
12 
13     static Properties pros = null;  //可以幫助讀取和處理資源文件中的信息
14 
15     static {    //加載JDBCUtil類的時(shí)候調(diào)用
16         pros = new Properties();
17         try {
18             pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
19         } catch (IOException e) {
20             e.printStackTrace();
21         }
22     }
23 
24     public static Connection getMysqlConn(){
25         try {
26             Class.forName(pros.getProperty("mysqlDriver"));
27             return DriverManager.getConnection(pros.getProperty("mysqlURL"),
28                     pros.getProperty("mysqlUser"),pros.getProperty("mysqlPwd"));
29         } catch (Exception e) {
30             e.printStackTrace();
31             return null;
32         }
33     }
34     //可以重載多個(gè),這里就懶得寫了
35     public static void close(ResultSet rs,Statement st,Connection conn){
36 
37         try {
38             if (rs!=null) {
39                 rs.close();
40             }
41         } catch (SQLException e) {
42             e.printStackTrace();
43         }
44         try {
45             if (st!=null) {
46                 st.close();
47             }
48         } catch (SQLException e) {
49             e.printStackTrace();
50         }
51         try {
52             if (conn!=null) {
53                 conn.close();
54             }
55         } catch (SQLException e) {
56             e.printStackTrace();
57         }
58     }
59 }

測(cè)試使用JDBCUtil工具類來簡(jiǎn)化JDBC開發(fā)

 1 package com.test.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 
 7 /**
 8  * 測(cè)試使用JDBCUtil工具類來簡(jiǎn)化JDBC開發(fā)
 9  */
10 public class Demo11 {
11     public static void main(String[] args) {
12         Connection conn = null;
13         PreparedStatement ps = null;
14         ResultSet rs = null;
15 
16         try {
17             conn = JDBCUtil.getMysqlConn();
18 
19             ps = conn.prepareStatement("insert into t_user (userName) values (?)");
20             ps.setString(1, "小高高");
21             ps.execute();
22 
23         } catch (Exception e) {
24             e.printStackTrace();
25         } finally{
26             JDBCUtil.close(rs, ps, conn);
27         }
28     }
29 }

參考資料:
https://www.cnblogs.com/erbing/p/5805727.html
https://blog.csdn.net/weixin_46649583/article/details/109611889

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末洛波,一起剝皮案震驚了整個(gè)濱河市胰舆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蹬挤,老刑警劉巖缚窿,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異焰扳,居然都是意外死亡倦零,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門吨悍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扫茅,“玉大人,你說我怎么就攤上這事育瓜『叮” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵躏仇,是天一觀的道長(zhǎng)恋脚。 經(jīng)常有香客問我,道長(zhǎng)钙态,這世上最難降的妖魔是什么慧起? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮册倒,結(jié)果婚禮上蚓挤,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好灿意,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布估灿。 她就那樣靜靜地躺著,像睡著了一般缤剧。 火紅的嫁衣襯著肌膚如雪馅袁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天荒辕,我揣著相機(jī)與錄音汗销,去河邊找鬼。 笑死抵窒,一個(gè)胖子當(dāng)著我的面吹牛弛针,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播李皇,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼削茁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了掉房?” 一聲冷哼從身側(cè)響起茧跋,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卓囚,沒想到半個(gè)月后瘾杭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哪亿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年富寿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锣夹。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖苏潜,靈堂內(nèi)的尸體忽然破棺而出银萍,到底是詐尸還是另有隱情,我是刑警寧澤恤左,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布贴唇,位于F島的核電站,受9級(jí)特大地震影響飞袋,放射性物質(zhì)發(fā)生泄漏戳气。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一巧鸭、第九天 我趴在偏房一處隱蔽的房頂上張望瓶您。 院中可真熱鬧,春花似錦、人聲如沸呀袱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夜赵。三九已至明棍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寇僧,已是汗流浹背摊腋。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘁傀,地道東北人兴蒸。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像心包,于是被迫代替她去往敵國(guó)和親类咧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 一蟹腾、JDBC簡(jiǎn)介 1痕惋、JDBC基礎(chǔ) JDBC(Java Database Connectivity)是一個(gè)獨(dú)立于特...
    慕凌峰閱讀 1,215評(píng)論 2 32
  • ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ JDB...
    _Levi__閱讀 427評(píng)論 1 0
  • 轉(zhuǎn)自:http://www.cnblogs.com/erbing/p/5805727.html一、相關(guān)概念 1.什...
    小沙鷹168閱讀 1,719評(píng)論 0 0
  • 一娃殖、相關(guān)概念 1.什么是JDBC JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫(kù)...
    ZZS_簡(jiǎn)閱讀 353評(píng)論 0 0
  • 轉(zhuǎn)自:https://www.cnblogs.com/erbing/p/5805727.html 一值戳、相關(guān)概念 1...
    mayiwoaini閱讀 154評(píng)論 0 1