程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL數據庫學習筆記(十)----JDBC事務處理、封裝JDBC工具類,----jdbcjdbc

MySQL數據庫學習筆記(十)----JDBC事務處理、封裝JDBC工具類,----jdbcjdbc

編輯:MySQL綜合教程

MySQL數據庫學習筆記(十)----JDBC事務處理、封裝JDBC工具類,----jdbcjdbc


 

首先需要回顧一下上一篇文章中的內容:MySQL數據庫學習筆記(九)----JDBC的PreparedStatement接口重構增刪改查

一、JDBC事務處理:

我們已經知道,事務的概念即:所有的操作要麼同時成功,要麼同時失敗。在MySQL中提供了Commit、Rollback命令進行事務的提交與回滾。實際上在JDBC中也存在事務處理,如果要想進行事務處理的話,則必須按照以下的步驟完成。

JDBC中事務處理的步驟:

1、要取消掉JDBC的自動提交:void setAutoCommit(boolean autoCommit)

2、執行各個SQL語句,加入到批處理之中

3、如果所有語句執行成功,則提交事務 commit();如果出現了錯誤,則回滾:rollback()

核心代碼:

conn.setAutoCommit(false); // 取消自動提交
把SQL語句加入批處理
stmt.addBatch(…) ()
stmt.addBatch(…)
//執行批處理操作
stmt.executeBatch();
conn.commit(); // 提交事務

//如果發生錯誤
conn.rollback();

代碼舉例:

首先在sql中創建一個空的數據庫,現在在java中,使用PreparedStatement插入數據並修改數據。正常情況下,代碼應該這樣寫:

 1 package com.vae.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.PreparedStatement;
 6 import java.sql.ResultSet;
 7 import java.sql.SQLException;
 8 
 9 public class JDBCtest {
10 
11 
12     //數據庫連接地址
13     public final static String URL = "jdbc:mysql://localhost:3306/JDBCdb";
14     //用戶名
15     public final static String USERNAME = "root";
16     //密碼
17     public final static String PASSWORD = "smyh";
18     //驅動類
19     public final static String DRIVER = "com.mysql.jdbc.Driver";
20     
21     
22     public static void main(String[] args) {
23         // TODO Auto-generated method stub
24         //insert(p);
25         //update(p);
26         //delete(3);
27         insertAndQuery();
28     }
29     
30     
31     //方法:使用PreparedStatement插入數據、更新數據
32     public static void insertAndQuery(){
33         Connection conn = null;
34         try {
35             Class.forName(DRIVER);
36             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
37             String sql1 = "insert into user(name,pwd)values(?,?)";
38             String sql2 = "update user set pwd=? where name=?";
39             PreparedStatement ps = conn.prepareStatement(sql1);
40             ps.setString(1, "smyhvae");
41             ps.setString(2, "007");            
42             ps.executeUpdate();
43             
44             ps = conn.prepareStatement(sql2);
45             ps.setString(1, "008");
46             ps.setString(2, "smyh");            
47             ps.executeUpdate();            
48             
49             ps.close();
50             conn.close();            
51             
52         } catch (ClassNotFoundException e) {
53             e.printStackTrace();
54         } catch (SQLException e) {
55             e.printStackTrace();
56         }
57     }
58     
59 }

事務處理:

現在我們把上面的插入操作和修改操作變成一個事務,就要增加一部分代碼了。修改上方的insertAndQuery()方法裡面的代碼:

 1 //方法:使用PreparedStatement插入數據、更新數據
 2     public static void insertAndQuery(){
 3         Connection conn = null;
 4         try {
 5             Class.forName(DRIVER);
 6             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
 7             conn.setAutoCommit(false);//設置為手動提交事務
 8             String sql1 = "insert into user(name,pwd)values(?,?)";
 9             String sql2 = "update user set pwd=? where name=?";
10             PreparedStatement ps = conn.prepareStatement(sql1);
11             ps.setString(1, "smyhvae");
12             ps.setString(2, "007");            
13             ps.executeUpdate();
14             
15             ps = conn.prepareStatement(sql2);
16             ps.setString(1, "008");
17             ps.setString(2, "smyh");            
18             ps.executeUpdate();            
19             conn.commit(); //如果所有sql語句成功,則提交事務
20             ps.close();
21             conn.close();
22             
23         } catch (ClassNotFoundException e) {
24             e.printStackTrace();
25         } catch (SQLException e) {
26             e.printStackTrace();
27             try {
28                 conn.rollback();//只要有一個sql語句出現錯誤,則將事務回滾 
29             } catch (SQLException e1) {
30                 e1.printStackTrace();
31             }
32         }
33         
34     }

核心代碼是第07行、19行、28行。這三行代碼就完成了事務處理的操作。兩個sql語句中,只要有一個語句出現錯誤,程序將無法運行,說明事務提交失敗,且報錯如下:

 

二、封裝JDBC工具類

之前的JDBC代碼分析:

我們可以先回顧一下上一篇博文中的第五段:使用PreparedStatement重構增刪改查。

通過分析可以發現有以下不足:有許多重復的代碼、每次都要加載驅動、獲取連接等。增刪改查無非只是slq語句不一樣而已。

封裝工具類就是一個抽象的過程,我們可以把現在代碼中非常公用的代碼抽取出來,形成一個工具類。

  • 第一步:抽象公共的代碼到工具類。
  • 第二步:為提高可以連接不同數據庫的能力,將連接數據庫的URL、用戶名,密碼等信息編寫在一個屬性文件(jdbc.properties)中,方便以後進行修改。 

我們先把之前的文章中,使用PreparedStatement查詢數據庫的代碼貼出來,方便和後面的內容進行對比,省的翻來翻去麻煩。

使用PreparedStatement查詢數據庫:(重構前)

在這之前,請建好一個Person類,參考上一篇博文就行了。然後,JDBCtest.java的代碼如下:

 1 package com.vae.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.PreparedStatement;
 6 import java.sql.ResultSet;
 7 import java.sql.SQLException;
 8 
 9 public class JDBCtest {
10 
11 
12     //數據庫連接地址
13     public final static String URL = "jdbc:mysql://localhost:3306/JDBCdb";
14     //用戶名
15     public final static String USERNAME = "root";
16     //密碼
17     public final static String PASSWORD = "smyh";
18     //驅動類
19     public final static String DRIVER = "com.mysql.jdbc.Driver";
20     
21     
22     public static void main(String[] args) {
23         // TODO Auto-generated method stub
24         Person p = new Person();
25 
26         p = findById(2);
27         System.out.println(p);
28     }   
29     
30  
31     
32     // 使用PreparedStatement查詢數據
33     public static Person findById(int id){
34         Person p = null;
35         try {
36             Class.forName(DRIVER);
37             Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
38             String sql = "select name,age,description from person where id=?";
39             PreparedStatement ps = conn.prepareStatement(sql);
40             //設置占位符對應的值
41             ps.setInt(1, id);
42             
43             ResultSet rs = ps.executeQuery();
44             if(rs.next()){
45                 p = new Person();
46                 p.setId(id);
47                 p.setName(rs.getString(1));
48                 p.setAge(rs.getInt(2));
49                 p.setDescription(rs.getString(3));
50                 
51             }
52             rs.close();
53             ps.close();
54             conn.close();
55             
56             
57         } catch (ClassNotFoundException e) {
58             e.printStackTrace();
59         } catch (SQLException e) {
60             e.printStackTrace();
61         }
62         return p;
63     }
64     
65 
66 }

接下來開始真正的工作了,從零開始。

封裝工具類:

新建工程文件,結構如下:

1 package com.vae.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.ResourceBundle; 9 10 /** 11 * 數據庫操作工具類 12 * @author lamp 13 * 14 */ 15 public class DBUtils { 16 17 //數據庫連接地址 18 public static String URL; 19 //用戶名 20 public static String USERNAME; 21 //密碼 22 public static String PASSWORD; 23 //mysql的驅動類 24 public static String DRIVER; 25 26 private static ResourceBundle rb = ResourceBundle.getBundle("com.vae.jdbc.db-config"); 27 28 private DBUtils(){} 29 30 //使用靜態塊加載驅動程序 31 static{ 32 URL = rb.getString("jdbc.url"); 33 USERNAME = rb.getString("jdbc.username"); 34 PASSWORD = rb.getString("jdbc.password"); 35 DRIVER = rb.getString("jdbc.driver"); 36 try { 37 Class.forName(DRIVER); 38 } catch (ClassNotFoundException e) { 39 e.printStackTrace(); 40 } 41 } 42 //定義一個獲取數據庫連接的方法 43 public static Connection getConnection(){ 44 Connection conn = null; 45 try { 46 conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); 47 } catch (SQLException e) { 48 e.printStackTrace(); 49 System.out.println("獲取連接失敗"); 50 } 51 return conn; 52 } 53 54 /** 55 * 關閉數據庫連接 56 * @param rs 57 * @param stat 58 * @param conn 59 */ 60 public static void close(ResultSet rs,Statement stat,Connection conn){ 61 try { 62 if(rs!=null)rs.close(); 63 if(stat!=null)stat.close(); 64 if(conn!=null)conn.close(); 65 } catch (SQLException e) { 66 e.printStackTrace(); 67 } 68 } 69 70 }

28行:既然是工具類,一般不要實例化,此時可以采用單例設計模式,或者將構造方法私有化。

26行:很明顯可以看到,我們是將連接數據庫的URL、用戶名,密碼等信息編寫在一個屬性文件(jdbc.properties)中,稍後再來定義這個屬性文件。

31行:為避免重復代碼,使用靜態代碼塊:只會在類加載的時候執行一次。

42行:定義一個獲取數據庫連接的方法

60行:關閉數據庫連接

(2)接下來新建一個屬性文件,new-->file,命名為:db-config.properties,代碼如下:

jdbc.url=jdbc:mysql://localhost:3306/jdbcdb
jdbc.username=root
jdbc.password=smyh
jdbc.driver=com.mysql.jdbc.Driver

以後如果需要修改配置信息,只需要在這裡改就行了。注意在上面的DBUtils類中是怎麼來調用這個配置信息的。

(3)緊接著新建文件,定義好Person類:

1 package com.vae.jdbc; 2 3 public class Person { 4 private int id; 5 private String name; 6 private int age; 7 private String description; 8 public int getId() { 9 return id; 10 } 11 public void setId(int id) { 12 this.id = id; 13 } 14 public String getName() { 15 return name; 16 } 17 public void setName(String name) { 18 this.name = name; 19 } 20 public int getAge() { 21 return age; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 } 26 public String getDescription() { 27 return description; 28 } 29 public void setDescription(String description) { 30 this.description = description; 31 } 32 public Person(int id, String name, int age, String description) { 33 super(); 34 this.id = id; 35 this.name = name; 36 this.age = age; 37 this.description = description; 38 } 39 public Person(String name, int age, String description) { 40 super(); 41 this.name = name; 42 this.age = age; 43 this.description = description; 44 } 45 public Person() { 46 super(); 47 // TODO Auto-generated constructor stub 48 } 49 @Override 50 public String toString() { 51 return "Person [id=" + id + ", name=" + name + ", age=" + age 52 + ", description=" + description + "]"; 53 } 54 55 56 } Person.java

(4)然後開始編寫主程序來測試一下:

 1 package com.vae.jdbc;
 2 
 3 import java.sql.Connection;
 4 import java.sql.PreparedStatement;
 5 import java.sql.ResultSet;
 6 import java.sql.SQLException;
 7 
 8 
 9 public class Test {
10     
11     public static void main(String[] args) {
12         Person p = new Person();
13         p = findById(1);
14         System.out.println(p);
15     }
16     
17     
18 
19 
20     /**
21      * 查詢的方法
22      */
23     public static Person findById(int id){
24         Person p =null;
25         //通過工具類獲取數據庫連接
26         Connection conn = DBUtils.getConnection();
27         PreparedStatement ps = null;
28         ResultSet rs = null;
29         String sql = "select name,age,description from person where id=?";
30         try {
31             ps = conn.prepareStatement(sql);
32             //設置占位符對應的值
33             ps.setInt(1, id);
34             rs = ps.executeQuery();
35             if(rs.next()){
36                 p = new Person();
37                 p.setName(rs.getString(1));
38                 p.setAge(rs.getInt(2));
39                 p.setDescription(rs.getString(3));
40             }
41         } catch (SQLException e) {
42             e.printStackTrace();
43         }finally{
44             //通過工具類關閉數據庫連接
45             DBUtils.close(rs, ps, conn);
46         }
47         return p;
48         
49     }
50 
51 }

測試程序是可以運行的。這樣,我們的工具類就建好了。


封裝JDBC工具類?解析XML獲取配置中的數據庫信息?

package tool;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;public class JdbcXmlParse { /** 數據庫配置信息 */ private static HashMap<String, JdbcBean> beanMap; public static JdbcBean getJdbcBean(String dbName) { if (beanMap == null) { // 配置文件路徑 String path = System.getProperty("user.dir") + File.separator + "src/tool/dbConfig.xml"; try { new JdbcXmlParse().initDbconfig(path); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return beanMap.get(dbName); } private void initDbconfig(String dbCfgPath) throws ParserConfigurationException, SAXException, IOException { // 初始化map beanMap = new HashMap<String, JdbcBean>(); DocumentBuilder dombuilder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); InputStream is = new FileInputStream(dbCfgPath); Element root = dombuilder.parse(is).getDocumentElement(); NodeList childs = root.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { Node child = childs.item(i); if ("db".equals(child.getNodeName())) { // 數據庫種類 String dbType......余下全文>>
 

jdbc連接mysql 完整代碼 其中數據庫只需要建立username password 就可以了

你找對了Jar包沒有呢?
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved