Java基礎-面向接口編程-JDBC詳解
html
做者:尹正傑java
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。python
一.JDBC概念和數據庫驅動程序mysql
JDBC(Java Data Base Connectivity,java數據庫鏈接)是一種用於執行SQL語句的Java API,能夠爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。是Java訪問數據庫的標準規範。本篇博客使用的介紹的是Java連接MySQL數據庫,若是對MySQL數據不是很瞭解的小夥伴請參考:http://www.cnblogs.com/yinzhengjie/p/9011342.html程序員
JDBC提供了一種基準,據此能夠構建更高級的工具和接口,使數據庫開發人員可以編寫數據庫應用程序。JDBC須要鏈接驅動,驅動是兩個設備要進行通訊,知足必定通訊數據格式,數據格式由設備提供商規定,設備提供商爲設備提供驅動軟件,經過軟件能夠與該設備進行通訊。sql
本篇博客使用的是mysql的驅動mysql-connector-java-5.1.39-bin.jar,若沒有安裝包請自行下載,若在網上沒有找到相應的解決方案,別擔憂,我已經幫你把坑踩好了,請參考:http://www.cnblogs.com/yinzhengjie/p/9017416.html數據庫
二.JDBC原理編程
Java提供訪問數據庫規範稱爲JDBC,而生產廠商提供規範的實現類稱爲驅動。JDBC是接口,驅動是接口的實現,沒有驅動將沒法完成數據庫鏈接,從而不能操做數據庫!每一個數據庫廠商都須要提供本身的驅動,用來鏈接本身公司的數據庫,也就是說驅動通常都由數據庫生成廠商提供。服務器
三.JDBC的開發步驟網絡
1>.JDBC操做數據庫的步驟
a>.註冊驅動
告知JVM使用的是哪個數據庫的驅動。
b>.得到連接
使用JDBC中的類,完成對MySQL數據庫的連接。
c>.得到語句執行平臺
經過連接對象獲取對SQL語句的執行者對象。
d>.執行SQL語句
使用執行者對象,向數據庫執行SQL語句,獲取到數據庫執行後的結果。
e>.處理結果
就是咱們當咱們拿到數據庫執行後的結果想要完成的業務邏輯。
f>.釋放資源
關閉網絡連接,跟IO流相似,調用其close方法便可。
2>.導入MySQL數據庫驅動程序jar包
a>.在當前項目下,建立lib目錄,在lib目錄下建立MySQL目錄(用於標識該目錄只存放MySQL相關驅動),並將下載的好的按照保導入該文件夾中。
b>.將下載後的Java包添加到項目中的環境變量中
c>.導入MySQL驅動成功標誌
3>.準備數據庫數據(我開發環境在虛擬機上安裝的,真正的MySQL服務安裝在宿主機上,模擬的是生產環境中連接服務器)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 8 #建立表結構 9 create table Classmate( 10 ID int(11) NOT NULL primary key AUTO_INCREMENT, 11 Name varchar(30) COLLATE gbk_bin DEFAULT NULL, 12 Age int DEFAULT NULL, 13 Job varchar(50), 14 Chinese int, 15 English int, 16 Math int, 17 Physics int, 18 Chemistry int, 19 Biology int 20 ); 21 22 #往表裏添加數據 23 insert into Classmate values(null,'王建軍',30,'Java講師',100,98,99,96,97,100); 24 insert into Classmate values(null,'常慶林',28,'Linux講師',100,100,98,93,99,96); 25 insert into Classmate values(null,'徐培成',35,'BigData講師',100,100,100,98,96,100); 26 insert into Classmate values(null,'李永強',30,'javaEE開發工程師',100,93,91,74,89,100); 27 insert into Classmate values(null,'趙子昂',24,'python開發工程師',98,93,91,74,89,100); 28 insert into Classmate values(null,'桂陽',25,'C++開發工程師',100,98,93,91,99,82); 29 insert into Classmate values(null,'肖雲龍',24,'Golang開發工程師',93,97,85,100,93,69); 30 insert into Classmate values(null,'李洋',23,'C#開發工程師',100,98,99,96,97,100); 31 insert into Classmate values(null,'卜孟龍',30,'BigData開發',98,93,100,100,73,92); 32 insert into Classmate values(null,'羅大鵬',22,'Java開發工程師',100,84,91,87,100,93); 33 insert into Classmate values(null,'尹正傑',26,'高級運維工程師',100,100,100,100,100,100);
四.JDBC執行insert語句( Statement接口的實現類對象)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note; 7 8 import java.sql.Connection; 9 import java.sql.DriverManager; 10 import java.sql.ResultSet; 11 import java.sql.Statement; 12 13 public class JDBCDemo { 14 15 public static void main(String[] args) throws Exception { 16 17 //1.註冊驅動,利用java反射技術,將驅動類加入到內容 18 /*使用java.sql.DriverManager類靜態方法 registerDriver(Driver driver) 19 Diver是一個接口,參數傳遞,MySQL驅動程序中的實現類 20 DriverManager.registerDriver(new Driver()); 21 驅動類源代碼,註冊2次驅動程序 */ 22 Class.forName("com.mysql.jdbc.Driver"); 23 //2.得到數據庫鏈接 DriverManager類中靜態方法 24 /*static Connection getConnection(String url, String user, String password) 25 返回值是Connection接口的實現類,在mysql驅動程序 26 url: 數據庫地址 jdbc:mysql://鏈接主機IP:端口號//數據庫名字 */ 27 String url = "jdbc:mysql://192.168.0.254:5200/yinzhengjie"; 28 String username="root"; 29 String password="yinzhengjie"; 30 Connection conn = DriverManager.getConnection(url, username, password); 31 //3.得到語句執行平臺, 經過數據庫鏈接對象,獲取到SQL語句的執行者對象 32 /* conn對象調用方法 Statement createStatement() 獲取Statement對象,將SQL語句發送到數據庫返回值是 Statement接口的實現類對象.*/ 33 Statement stat = conn.createStatement(); 34 // 4.執行sql語句 35 /* 經過執行者對象調用方法執行SQL語句,獲取結果 int executeUpdate(String sql) 執行數據庫中的SQL語句, insert,delete,update操做,返回值int,操做成功數據表多少行 */ 36 String sql = "insert into Classmate values(null,'鄧西',27,'DBA開發工程師',98,100,81,70,100,90);"; 37 int row = stat.executeUpdate(sql); 38 System.out.printf("表中有【%d】行發生了改變!",row); 39 //6.釋放資源 一堆close() 40 stat.close(); 41 conn.close(); 42 } 43 } 44 45 46 /* 47 以上代碼執行結果以下: 48 表中有【1】行發生了改變! 49 */
五.JDBC執行select語句(ResultSet接口的實現類)
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note; 7 8 import java.sql.Connection; 9 import java.sql.DriverManager; 10 import java.sql.ResultSet; 11 import java.sql.Statement; 12 /* 13 * JDBC技術,查詢數據表,獲取結果集 14 */ 15 public class JDBCDemo1 { 16 public static void main(String[] args) throws Exception{ 17 //1. 註冊驅動 18 Class.forName("com.mysql.jdbc.Driver"); 19 //2. 獲取鏈接對象 20 String url = "jdbc:mysql://192.168.0.254:5200/yinzhengjie"; 21 String username="root"; 22 String password="yinzhengjie"; 23 Connection conn = DriverManager.getConnection(url, username, password); 24 //3 .獲取執行SQL 語句對象 25 Statement stat = conn.createStatement(); 26 // 拼寫查詢的SQL 27 String sql = "select * from classmate"; 28 //4. 調用執行者對象方法,執行SQL語句獲取結果集 29 /* ResultSet executeQuery(String sql) 執行SQL語句中的select查詢,返回值ResultSet接口的實現類對象,實現類在mysql驅動中*/ 30 ResultSet rs = stat.executeQuery(sql); 31 //5 .處理結果集 32 // ResultSet接口方法 boolean next() 返回true,有結果集,返回false沒有結果集 33 //獲取結果集中的數據,一種是逐行獲取每列的內容,若是知道是字符串就用getString方法接住,類型爲String,若是知道是數字則用getInt方式接着,類型爲int,若是你不知道此列的類型能夠用getObject接住,類型爲Object。 34 /*根據每列的長度進行取值,不推薦使用 35 while(rs.next()){ 36 int id = rs.getInt(1); 37 String name = rs.getString(2); 38 int age = rs.getInt(3); 39 String job = rs.getString(4); 40 int Chinese = rs.getInt(5); 41 int English = rs.getInt(6); 42 int Math = rs.getInt(7); 43 int Physics = rs.getInt(8); 44 int Chemistry = rs.getInt(9); 45 int Biology = rs.getInt(10); 46 System.out.println(id +","+ name +","+ age +","+ job +","+ Chinese+","+ English+","+ Math+","+ Physics+","+ Chemistry+","+ Biology); 47 }*/ 48 //除了上面的取值方式,固然還能夠用列明的方式取值啦。這樣你能夠清楚的知道本身取出來的是什麼數據,推薦使用該方法。 49 while(rs.next()){ 50 int id = rs.getInt("id"); 51 String name = rs.getString("name"); 52 int age = rs.getInt("age"); 53 String job = rs.getString("job"); 54 int Chinese = rs.getInt("Chinese"); 55 int English = rs.getInt("English"); 56 int Math = rs.getInt("Math"); 57 int Physics = rs.getInt("Physics"); 58 int Chemistry = rs.getInt("Chemistry"); 59 int Biology = rs.getInt("Biology"); 60 System.out.println(id +","+ name +","+ age +","+ job +","+ Chinese+","+ English+","+ Math+","+ Physics+","+ Chemistry+","+ Biology); 61 } 62 //6.釋放資源 一堆close() 63 rs.close(); 64 stat.close(); 65 conn.close(); 66 } 67 } 68 69 70 71 /* 72 以上代碼執行結果以下: 73 1,王建軍,30,Java講師,100,98,99,96,97,100 74 2,常慶林,28,Linux講師,100,100,98,93,99,96 75 3,徐培成,35,BigData講師,100,100,100,98,96,100 76 4,李永強,30,javaEE開發工程師,100,93,91,74,89,100 77 5,趙子昂,24,python開發工程師,98,93,91,74,89,100 78 6,桂陽,25,C++開發工程師,100,98,93,91,99,82 79 7,肖雲龍,24,Golang開發工程師,93,97,85,100,93,69 80 8,李洋,23,C#開發工程師,100,98,99,96,97,100 81 9,卜孟龍,30,BigData開發,98,93,100,100,73,92 82 10,羅大鵬,22,Java開發工程師,100,84,91,87,100,93 83 11,尹正傑,26,高級運維工程師,100,100,100,100,100,100 84 12,鄧西,27,DBA開發工程師,98,100,81,70,100,90 85 */
六.Java防SQL注入的解決方案
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note; 7 8 import java.sql.Connection; 9 import java.sql.DriverManager; 10 import java.sql.PreparedStatement; 11 import java.sql.Statement; 12 13 /* 14 * 15 * 1.statement使用的不方便 16 * 2.sql注入的問題 17 * 在SQL語句中使用了系統自帶的關鍵字 or and ,讓where條件判斷失效 18 * 19 * prepareStatement: 20 * 1.sql語句不用在拼字符串 21 * 2.防止sql注入問題 22 * 23 */ 24 public class CURDDemo { 25 26 public static void main(String[] args) throws Exception { 27 // insertTest(); 28 insertTest2(); //優化後的代碼 29 // deleteTest(); 30 // deleteTest2(); //優化後的代碼 31 } 32 33 // 刪除方法,存在SQL注入風險! 34 private static void deleteTest() throws Exception { 35 Class.forName("com.mysql.jdbc.Driver"); 36 37 Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.254:5200/yinzhengjie", "root", "yinzhengjie"); 38 39 Statement st = conn.createStatement(); 40 41 int id = 4; 42 //定義咱們想要執行的語句 43 // String sql = "delete from emp where eid = " + id "; 44 //一些對SQL語句小朋友喜歡搞點事情,把上面的代碼添頭加醋,就生成了如下代碼(" or 1 = 1"),最終會致使where匹配條件失效,致使清空掉了整個數據庫內容!是否是有點小驚訝呢? 45 String sql = "delete from classmate where id = " + id + " or 1 = 1"; 46 //除了上面說的SQL注入狀況外,按照上面的拼接字符串真的讓人慾哭無淚啊,慶幸的是我上面測試環境參數相對較少,要是在實際生產環境中就有50個參數要傳遞那隻要你的小手一哆嗦就很容易出錯呢! 47 int i = st.executeUpdate(sql); 48 49 if (i != 0) { 50 System.out.println("刪除成功"); 51 } 52 53 st.close(); 54 conn.close(); 55 } 56 57 // 刪除優化,解決掉SQL注入風險以及拼接字符串的煩惱! 58 private static void deleteTest2() throws Exception { 59 Class.forName("com.mysql.jdbc.Driver"); 60 Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.254:5200/yinzhengjie", "root", "yinzhengjie"); 61 /*調用Connection接口的方法prepareStatement,獲取PrepareStatement接口的實現類,方法中參數,SQL語句中的參數所有采用問號佔位符*/ 62 String sql = "delete from classmate where id = ?"; 63 PreparedStatement pst = conn.prepareStatement(sql); 64 //咱們在傳參數的時候 65 // pst.setInt(1, 12); 66 //這個時候咱們再去模仿SQL注入,發現數據庫真實刪除的只有第二條。關於後面的「or 1 = 1」壓根就沒有執行!!,是否是很高大上? 67 pst.setString(1," 2 or 1 = 1" ); 68 int i = pst.executeUpdate(); 69 70 if (i != 0) { 71 System.out.println("刪除成功"); 72 } 73 74 pst.close(); 75 conn.close(); 76 } 77 78 // 增,也能存在SQL注入的風險,不推薦使用! 79 private static void insertTest() throws Exception { 80 // 註冊驅動 81 Class.forName("com.mysql.jdbc.Driver"); 82 // 獲取鏈接 83 Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.254:5200/yinzhengjie", "root", "yinzhengjie"); 84 // 建立statement對象 85 Statement st = conn.createStatement(); 86 // 執行sql語句 87 // 真實場景中,sql中的數據都是從外界獲取的. 88 89 String name = "方合意"; 90 int age = 21; 91 String job = "Python開發工程師"; 92 int chinese = 100; 93 int english = 89; 94 int math = 98; 95 int physics = 91; 96 int chemistry = 73; 97 int biology = 89; 98 99 String sql = "insert into classmate values(null,'" + name + "', " + age + ", '" + job+ "', " + chinese+ ", " + english+ ", " + math + ", " + physics + ", " + chemistry +", " + biology+ ")"; 100 101 int i = st.executeUpdate(sql); 102 // 判斷插入語句是否執行成功 103 if (i != 0) { 104 System.out.println("插入數據成功"); 105 } 106 st.close(); 107 conn.close(); 108 } 109 110 //增,防止SQL注入版本! 111 private static void insertTest2() throws Exception { 112 // 註冊驅動 113 Class.forName("com.mysql.jdbc.Driver"); 114 115 // 獲取鏈接 116 Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.254:5200/yinzhengjie", "root", "yinzhengjie"); 117 /*調用Connection接口的方法prepareStatement,獲取PrepareStatement接口的實現類,方法中參數,SQL語句中的參數所有采用問號佔位符*/ 118 String sql = "insert into classmate values (null,?,?,?,?,?,?,?,?,?)"; 119 120 PreparedStatement pst = conn.prepareStatement(sql); 121 //調用pst對象set方法,設置問號佔位符上的參數 122 pst.setString(1, "鄧聰"); 123 pst.setInt(2, 28); 124 pst.setString(3, "網絡工程師"); 125 pst.setInt(4, 100); 126 pst.setInt(5, 98); 127 pst.setInt(6, 89); 128 pst.setInt(7, 86); 129 pst.setInt(8, 97); 130 pst.setInt(9, 94); 131 132 int i = pst.executeUpdate(); 133 // 判斷插入語句是否執行成功 134 if (i != 0) { 135 System.out.println("插入數據成功"); 136 } 137 138 pst.close(); 139 conn.close(); 140 141 } 142 } 143 144 145 /* 146 以上代碼執行結果以下: 147 插入數據成功 148 */
八.JDBC的工具類和測試
1 DriverName=com.mysql.jdbc.Driver 2 #zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi ! 3 url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true 4 user=root 5 password=yinzhengjie
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note1; 7 8 import java.io.FileInputStream; 9 import java.io.IOException; 10 import java.sql.Connection; 11 import java.sql.DriverManager; 12 import java.util.Properties; 13 14 /* 15 * 獲取數據庫鏈接的工具類 16 * 在獲取鏈接對象的方法中,首先是註冊驅動,實際上沒有必要 17 * 註冊驅動只須要執行一次就OK 18 * 19 */ 20 public class Utils { 21 22 private Utils(){} 23 24 private static Properties p = new Properties(); 25 private static String driver; 26 private static String url; 27 private static String user; 28 private static String password; 29 30 //加載配置文件 31 static{ 32 try { 33 // p.load(Utils.class.getClassLoader().getResourceAsStream("config.properties")); 34 p.load(new FileInputStream("config.properties")); 35 driver = p.getProperty("DriverName"); 36 url = p.getProperty("url"); 37 user = p.getProperty("user"); 38 password = p.getProperty("password"); 39 } catch (IOException e) { 40 e.printStackTrace(); 41 } 42 } 43 44 //註冊驅動 45 static{ 46 //註冊驅動 47 try { 48 Class.forName(driver); 49 } catch (ClassNotFoundException e) { 50 e.printStackTrace(); 51 } 52 } 53 54 public static Connection getConnect() throws Exception{ 55 //獲取鏈接 56 Connection conn = DriverManager.getConnection(url, user, password); 57 return conn; 58 } 59 60 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note1; 7 8 import java.sql.Connection; 9 import java.sql.ResultSet; 10 import java.sql.Statement; 11 import org.junit.Test; 12 13 14 public class Demo { 15 @Test //注意,這個Test是單元測試,程序員不須要寫main方法就能夠測試!選中方法名運行便可。 16 public void insertTest() throws Exception{ 17 //使用工具類獲取鏈接 18 Connection conn = Utils.getConnect(); 19 20 // 建立statement對象 21 Statement st = conn.createStatement(); 22 23 // 執行sql語句 24 String sql = "insert into Classmate values(null,'陶濤',22,'網絡工程師',100,100,72,93,79,81)"; 25 int i = st.executeUpdate(sql); 26 // 判斷插入語句是否執行成功 27 if (i != 0) { 28 System.out.println("插入數據成功"); 29 } 30 31 st.close(); 32 conn.close(); 33 } 34 35 @Test //注意,這個Test是單元測試,程序員不須要寫main方法就能夠測試!選中方法名運行便可。 36 public void deleteTest() throws Exception{ 37 Connection conn = Utils.getConnect(); 38 39 Statement st = conn.createStatement(); 40 String name = "陶濤"; 41 //注意,字段須要用單引號引發來,這是數據庫的語法規則!所以咱們須要在字符串兩側加上相應的單引號! 42 String sql = "delete from classmate where name = '" + name + "'"; 43 44 int i = st.executeUpdate(sql); 45 46 if (i != 0) { 47 System.out.println("刪除成功"); 48 } 49 50 st.close(); 51 conn.close(); 52 } 53 54 @Test //注意,這個Test是單元測試,程序員不須要寫main方法就能夠測試!選中方法名運行便可。 55 public void updateTest() throws Exception{ 56 57 Connection conn = Utils.getConnect(); 58 59 Statement st = conn.createStatement(); 60 61 String sql = "update classmate set English = English + 120"; 62 int i = st.executeUpdate(sql); 63 64 if (i != 0) { 65 System.out.println("修改爲功"); 66 } 67 68 st.close(); 69 conn.close(); 70 } 71 72 @Test //注意,這個Test是單元測試,程序員不須要寫main方法就能夠測試!選中方法名運行便可。 73 public void selectTest() throws Exception{ 74 Connection conn = Utils.getConnect(); 75 Statement st = conn.createStatement(); 76 77 String sql = "select * from classmate where id = 11"; 78 79 //執行查詢語句! 80 ResultSet rs = st.executeQuery(sql); 81 82 while(rs.next()){ 83 //若是你不知道返回值是什麼類型的話,能夠用getObject來接住喲!!! 84 Object id = rs.getObject("id"); 85 Object name = rs.getObject("name"); 86 Object age = rs.getObject("age"); 87 Object job = rs.getObject("job"); 88 Object chinese = rs.getObject("chinese"); 89 Object english = rs.getObject("english"); 90 Object math = rs.getObject("math"); 91 Object physics = rs.getObject("physics"); 92 Object chemistry = rs.getObject("chemistry"); 93 Object biology = rs.getObject("biology"); 94 System.out.println(id +","+ name +","+ age +","+ job+","+ chinese +","+ english +","+ math +","+ physics +","+ chemistry +","+biology); 95 } 96 97 rs.close(); 98 st.close(); 99 conn.close(); 100 } 101 102 }
九.JDBC的異常處理
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.sql.PreparedStatement; 12 import java.sql.SQLException; 13 import java.sql.Statement; 14 15 public class ExceptionDemo { 16 17 public static void main(String[] args) { 18 //提高做用域 19 Connection conn = null; 20 Statement st = null; 21 22 try { 23 Class.forName("com.mysql.jdbc.Driver"); 24 25 conn = DriverManager.getConnection("jdbc:mysql://192.168.0.254:5200/yinzhengjie", "root", "yinzhengjie"); 26 27 String sql = "insert into classmate values (null,?,?,?,?,?,?,?,?,?)"; 28 29 PreparedStatement pst = conn.prepareStatement(sql); 30 31 pst.setString(1, "楊明明"); 32 pst.setInt(2, 32); 33 pst.setString(3, "網絡工程師"); 34 pst.setInt(4, 100); 35 pst.setInt(5, 98); 36 pst.setInt(6, 89); 37 pst.setInt(7, 86); 38 pst.setInt(8, 97); 39 pst.setInt(9, 94); 40 41 int i = pst.executeUpdate(); 42 // 判斷插入語句是否執行成功 43 if (i != 0) { 44 System.out.println("插入數據成功"); 45 } 46 47 } catch (ClassNotFoundException e) { 48 e.printStackTrace(); 49 } catch (SQLException e) { 50 e.printStackTrace(); 51 } finally { 52 //對被關閉的對象進行非空判斷 53 try { 54 if (st != null) { 55 st.close(); 56 } 57 } catch (SQLException e) { 58 e.printStackTrace(); 59 } 60 try { 61 if (conn != null) { 62 conn.close(); 63 } 64 } catch (SQLException e) { 65 e.printStackTrace(); 66 } 67 } 68 69 } 70 } 71 72 /* 73 以上代碼執行結果以下: 74 插入數據成功 75 */
十. JDBC操做較大數據對象
若是存儲的對象較大,咱們能夠採用以二進流的方式存儲,即BLOB,若是你較大的文本文件的話也能夠採用TEXT進行存儲。值得一說的是,在測試建表的時候要注意字段的數據類型, 若是類型指定的太小的話可能致使數據存儲會失敗喲!
1>.準備實驗環境
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 CREATE TABLE myblob( 8 id INT PRIMARY KEY AUTO_INCREMENT, 9 img LONGBLOB 10 ); 11 12 CREATE TABLE mytext( 13 id INT PRIMARY KEY AUTO_INCREMENT, 14 txt LONGBLOB 15 );
2>.JDBC操做BLOB對象
1 DriverName=com.mysql.jdbc.Driver 2 #zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi ! 3 url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true 4 user=root 5 password=yinzhengjie
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.util.ResourceBundle; 12 13 /* 14 * 獲取數據庫鏈接的工具類 15 * 在獲取鏈接對象的方法中,首先是註冊驅動,實際上沒有必要 16 * 註冊驅動只須要執行一次就OK 17 * 18 */ 19 public class Utils { 20 21 private Utils(){} 22 23 private static final String DRIVERCLASS; 24 private static final String URL; 25 private static final String USERNAME; 26 private static final String PASSWORD; 27 //使用配置文件 28 static { 29 //注意,這裏寫文件名的時候不要寫全稱,咱們此處這須要寫前綴就好,在Windows操做系統中若是你多此一舉寫上了文件名後綴可能會報錯喲! 30 DRIVERCLASS = ResourceBundle.getBundle("config").getString("DriverName"); 31 URL = ResourceBundle.getBundle("config").getString("url"); 32 USERNAME = ResourceBundle.getBundle("config").getString("user"); 33 PASSWORD = ResourceBundle.getBundle("config").getString("password"); 34 } 35 36 //註冊驅動 37 static{ 38 //註冊驅動 39 try { 40 Class.forName(DRIVERCLASS); 41 } catch (ClassNotFoundException e) { 42 e.printStackTrace(); 43 } 44 } 45 46 public static Connection getConnect() throws Exception{ 47 48 //獲取鏈接 49 Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); 50 return conn; 51 } 52 53 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.io.File; 10 import java.io.FileInputStream; 11 import java.io.FileNotFoundException; 12 import java.io.FileOutputStream; 13 import java.io.InputStream; 14 import java.sql.Connection; 15 import java.sql.PreparedStatement; 16 import java.sql.ResultSet; 17 import java.sql.SQLException; 18 19 public class BlobDemo { 20 21 public static void main(String[] args) throws Exception { 22 // sava(); 23 get(); 24 } 25 26 //獲取二進制大對象 27 private static void get() throws Exception { 28 Connection conn = Utils.getConnect(); 29 String sql = "select img from myblob where id = 1"; 30 PreparedStatement ps = conn.prepareStatement(sql); 31 ResultSet rs = ps.executeQuery(); 32 if(rs.next()){ 33 InputStream in = rs.getBinaryStream(1); 34 FileOutputStream fos = new FileOutputStream("1.jpg"); 35 byte[] buf = new byte[4096]; 36 int len; 37 while((len = in.read(buf))!=-1){ 38 fos.write(buf,0,len); 39 } 40 fos.close(); 41 in.close(); 42 } 43 rs.close(); 44 ps.close(); 45 conn.close(); 46 } 47 48 49 50 //保存二進制流文件到數據庫 51 private static void sava() throws Exception, SQLException, FileNotFoundException { 52 Connection conn = Utils.getConnect(); 53 String sql = "insert into myblob values(null,?)"; 54 55 PreparedStatement ps = conn.prepareStatement(sql); 56 // ps.setBinaryStream(1, new FileInputStream("c:/dog.jpg")); //MySQL對這種方式傳參不感冒!可是提供了其餘方法進行傳值! 57 File file = new File("C:/Users/yinzhengjie/Desktop/電子相冊/1.jpg"); 58 FileInputStream fis = new FileInputStream(file); 59 //將圖片保存到數據庫服務器中! 60 ps.setBinaryStream(1, fis, (int)file.length()); 61 62 int i = ps.executeUpdate(); 63 System.out.println(i); 64 65 ps.close(); 66 conn.close(); 67 } 68 } 69 70 71 72 /* 73 注意,若是出現如下報錯的話,說明你上傳的數據大於數據庫定義的數據類型了喲!解決方法要麼就是上傳數據庫規定的大小範圍,要麼修改數據庫字段類型的限制範圍。 74 com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'img' at row 1 75 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2983)*/
3>.JDBC操做TEXT對象
1 DriverName=com.mysql.jdbc.Driver 2 #zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi ! 3 url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true 4 user=root 5 password=yinzhengjie
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.util.ResourceBundle; 12 13 /* 14 * 獲取數據庫鏈接的工具類 15 * 在獲取鏈接對象的方法中,首先是註冊驅動,實際上沒有必要 16 * 註冊驅動只須要執行一次就OK 17 * 18 */ 19 public class Utils { 20 21 private Utils(){} 22 23 private static final String DRIVERCLASS; 24 private static final String URL; 25 private static final String USERNAME; 26 private static final String PASSWORD; 27 //使用配置文件 28 static { 29 //注意,這裏寫文件名的時候不要寫全稱,咱們此處這須要寫前綴就好,在Windows操做系統中若是你多此一舉寫上了文件名後綴可能會報錯喲! 30 DRIVERCLASS = ResourceBundle.getBundle("config").getString("DriverName"); 31 URL = ResourceBundle.getBundle("config").getString("url"); 32 USERNAME = ResourceBundle.getBundle("config").getString("user"); 33 PASSWORD = ResourceBundle.getBundle("config").getString("password"); 34 } 35 36 //註冊驅動 37 static{ 38 //註冊驅動 39 try { 40 Class.forName(DRIVERCLASS); 41 } catch (ClassNotFoundException e) { 42 e.printStackTrace(); 43 } 44 } 45 46 public static Connection getConnect() throws Exception{ 47 48 //獲取鏈接 49 Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); 50 return conn; 51 } 52 53 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note; 7 8 import java.io.File; 9 import java.io.FileInputStream; 10 import java.io.FileOutputStream; 11 import java.io.InputStream; 12 import java.sql.Connection; 13 import java.sql.PreparedStatement; 14 import java.sql.ResultSet; 15 16 public class TextDemo { 17 18 public static void main(String[] args) throws Exception { 19 // textSava(); 20 textGet(); 21 } 22 23 private static void textGet() throws Exception { 24 Connection conn = Utils.getConnect(); 25 String sql = "select txt from mytext where id = 1"; 26 PreparedStatement ps = conn.prepareStatement(sql); 27 ResultSet rs = ps.executeQuery(); 28 if(rs.next()){ 29 InputStream in = rs.getBinaryStream(1); 30 FileOutputStream fos = new FileOutputStream("1.txt"); 31 byte[] buf = new byte[4096]; 32 int len; 33 while((len = in.read(buf))!=-1){ 34 fos.write(buf,0,len); 35 } 36 fos.close(); 37 in.close(); 38 } 39 rs.close(); 40 ps.close(); 41 conn.close(); 42 } 43 44 private static void textSava() throws Exception { 45 Connection conn = Utils.getConnect(); 46 String sql = "insert into mytext values(null,?)"; 47 48 PreparedStatement ps = conn.prepareStatement(sql); 49 File file = new File("C:/Users/yinzhengjie/Desktop/Java常見的關鍵字.txt"); 50 FileInputStream fis = new FileInputStream(file); 51 //將圖片保存到數據庫服務器中! 52 ps.setBinaryStream(1, fis, (int)file.length()); 53 54 int i = ps.executeUpdate(); 55 System.out.println(i); 56 57 ps.close(); 58 conn.close(); 59 60 61 } 62 63 } 64
十一.JDBC批處理案例
1>.準備實驗環境
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 CREATE TABLE test1( 8 id INT PRIMARY KEY AUTO_INCREMENT, 9 num int 10 );
2>.批處理操做
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 CREATE TABLE test1( 8 id INT PRIMARY KEY AUTO_INCREMENT, 9 num int 10 );
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note; 8 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.util.ResourceBundle; 12 13 /* 14 * 獲取數據庫鏈接的工具類 15 * 在獲取鏈接對象的方法中,首先是註冊驅動,實際上沒有必要 16 * 註冊驅動只須要執行一次就OK 17 * 18 */ 19 public class Utils { 20 21 private Utils(){} 22 23 private static final String DRIVERCLASS; 24 private static final String URL; 25 private static final String USERNAME; 26 private static final String PASSWORD; 27 //使用配置文件 28 static { 29 //注意,這裏寫文件名的時候不要寫全稱,咱們此處這須要寫前綴就好,在Windows操做系統中若是你多此一舉寫上了文件名後綴可能會報錯喲! 30 DRIVERCLASS = ResourceBundle.getBundle("config").getString("DriverName"); 31 URL = ResourceBundle.getBundle("config").getString("url"); 32 USERNAME = ResourceBundle.getBundle("config").getString("user"); 33 PASSWORD = ResourceBundle.getBundle("config").getString("password"); 34 } 35 36 //註冊驅動 37 static{ 38 //註冊驅動 39 try { 40 Class.forName(DRIVERCLASS); 41 } catch (ClassNotFoundException e) { 42 e.printStackTrace(); 43 } 44 } 45 46 public static Connection getConnect() throws Exception{ 47 48 //獲取鏈接 49 Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); 50 return conn; 51 } 52 53 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note; 7 8 import java.sql.Connection; 9 import java.sql.PreparedStatement; 10 import java.sql.SQLException; 11 import java.sql.Statement; 12 13 /* 14 * 1.驅動版本5.1.13以上 15 * 2.在url中開啓批處理功能 16 */ 17 public class BatchTest { 18 19 public static void main(String[] args) throws Exception { 20 test1(); //3526毫秒 21 // test2(); //用時1523毫秒 22 } 23 24 25 //5.1.13以後批處理功能,SQL語句的總體框架變更起來很方便! 26 private static void test1() throws Exception, SQLException { 27 Connection conn = Utils.getConnect(); 28 Statement st = conn.createStatement(); 29 long start = System.currentTimeMillis(); 30 for(int i = 0;i<100000;i++){ 31 String sql = "insert into test1 values(null," + i + ")"; 32 st.addBatch(sql); 33 } 34 35 st.executeBatch(); 36 st.clearBatch(); 37 st.close(); 38 conn.close(); 39 System.out.println(System.currentTimeMillis() - start); 40 } 41 42 //SQL語句的總體框架變更起來麻煩,須要逐個進行預編譯 43 private static void test2() throws Exception, SQLException { 44 Connection conn = Utils.getConnect(); 45 String sql = "insert into test1 values(null,?)"; 46 PreparedStatement ps = conn.prepareStatement(sql); 47 long start = System.currentTimeMillis(); 48 49 for(int i = 1;i<=100000;i++){ 50 ps.setInt(1, i); 51 if(i % 1000 == 0){ 52 ps.executeBatch(); 53 ps.clearBatch(); 54 } 55 ps.addBatch(); 56 } 57 58 ps.executeBatch(); 59 ps.clearBatch(); 60 ps.close(); 61 conn.close(); 62 System.out.println(System.currentTimeMillis() - start); 63 } 64 65 }