JDBC是一組能夠執行SQL語句的API
由於傳統的數據庫操作方式需要程序員掌握各個不同的數據庫的API,極其不便
因此java定義了JDBC這一標准的接口和類,為程序員操作數據庫提供了統一的方式
JDBC的操作方式比較單一,由五個流程組成:
1.通過數據庫廠商提供的JDBC類庫向DriverManager注冊數據庫驅動
2.使用DriverManager提供的getConnection()方法連接到數據庫
3.通過數據庫的連接對象的createStatement方法建立SQL語句對象
4.執行SQL語句,並將結果集合返回到ResultSet中
5.使用while循環讀取結果
6.關閉數據庫資源
下面來看看具體操作Mysql數據庫的方法
准備工作
首先我們需要建立一個數據庫和一張簡單的表
復制代碼 代碼如下:
mysql> create database person;
Query OK, 1 row affected (0.00 sec)
mysql> use person;
Database changed
mysql> create table student(
-> id int,
-> name varchar(20),
-> birth year
-> ) default charset=utf8;
Query OK, 0 rows affected (0.10 sec)
然後往裡面插入幾條數據
復制代碼 代碼如下:
mysql> insert into student values
-> (1,'張三',1990),
-> (2,'李四',1991),
-> (3,'王五',1992);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
這樣一張簡單的表就建好了
復制代碼 代碼如下:
mysql> select * from student;
+------+--------+-------+
| id | name | birth |
+------+--------+-------+
| 1 | 張三 | 1990 |
| 2 | 李四 | 1991 |
| 3 | 王五 | 1992 |
+------+--------+-------+
rows in set (0.00 sec)
接下來,去mysql官網下載數據庫連接器這個包
其中這個包裡面含有一份文檔,裡面列舉了基本的使用方法,可以參考
我們的操作也是按照這份文檔中的內容進行,然後最主要的地方就是導入這個jar包
為了操作方便,這裡使用eclipse來導入
右鍵項目-->構件路徑-->添加外部歸檔,添加好了之後如下所示
現在我們正式開始使用java來操作mysql數據庫
JDBC操作實例1:最簡單的查詢操作
復制代碼 代碼如下:
import java.sql.*;
public class Demo {
//為了代碼緊湊性,暫時拋出所有異常
public static void main(String[] args) throws Exception {
//注冊數據庫驅動
Class.forName("com.mysql.jdbc.Driver");
//建立數據庫連接
//參數一:jdbc:mysql//地址:端口/數據庫,參數二:用戶名,參數三:密碼
Connection conn = DriverManager.getConnection
("jdbc:mysql://localhost:3306/person","root","admin");
//創建SQL語句
Statement st = conn.createStatement();
//執行語句,返回結果
ResultSet rt = st.executeQuery("show tables");
//循環取出結果
while(rt.next()) {
//獲取字段
System.out.println(rt.getString("Tables_in_person"));
}
//關閉資源,最先打開的最後關
rt.close();
st.close();
conn.close();
}
}
運行結果:student
如此便可執行show tables語句查詢出當前數據庫含有多少張表
其中rt.getString()方法是獲取字段,這點需要注意
關閉資源的方式也與以往相反
不過,上面的操作方式靈活性不大,並且不嚴謹
實例2:優化的查詢操作
復制代碼 代碼如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/person";
String user = "root";
String pwd = "admin";
String sql = "select * from student";
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pwd);
st = conn.createStatement();
//執行查詢語句,另外也可以用execute(),代表執行任何SQL語句
rs = st.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getObject(1) + " " +
rs.getObject(2) + " " + rs.getInt("birth"));
}
//分別捕獲異常
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
//判斷資源是否存在
if(rs != null) {
rs.close();
//顯示的設置為空,提示gc回收
rs = null;
}
if(st != null) {
st.close();
st = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
運行結果:
這裡把異常給分別捕獲了,並且相關的字符串全部用變量定義
需要注意下循環取出數據裡面的getInt()方法,此處必須知道類型和字段才能取出
如果不知道可以使用getObject(1)取出第一列,getObject(2)取出第二列,以此類推
實例3:自定義變量插入到數據庫
復制代碼 代碼如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) {
//參數檢查
if (args.length != 3) {
System.out.println("參數形式不對");
System.exit(0);
}
String id = args[0];
String name = args[1];
String birth = args[2];
String sql = "insert into student values(" + id + ",'" + name +
"'," + "'" + birth + "')";
System.out.println(sql);
String url = "jdbc:mysql://localhost:3306/person";
String user = "root";
String pwd = "admin";
Connection conn = null;
Statement st = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pwd);
st = conn.createStatement();
//注意,此處是excuteUpdate()方法執行
st.executeUpdate(sql);
//分別捕獲異常
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(st != null) {
st.close();
st = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
運行結果:
這裡運行需要設置自變量,窗口中右鍵-->運行方式-->運行配置
然後在自變量裡面寫4 susan 1993,我沒有寫中文,因為產生亂碼,目前還不清楚原因
需要注意的是,執行插入的SQL語句比較難寫,最好是打印出SQL語句用以檢查
實例4:PreparedStatement應用
從上面的Demo可以看到,插入數據的時候,SQL操作相當不便
這裡可以使用PreparedStatement對象來簡化SQL語句的建立
復制代碼 代碼如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) {
if (args.length != 3) {
System.out.println("參數形式不對");
System.exit(0);
}
String id = args[0];
String name = args[1];
String birth = args[2];
String url = "jdbc:mysql://localhost:3306/person";
String user = "root";
String pwd = "admin";
Connection conn = null;
//聲明PreparedStatement對象的引用
PreparedStatement pst = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pwd);
//使用?代替變量
pst = conn.prepareStatement("insert into student values (?,?,?)");
//給指定參數的位置設定變量
pst.setString(1, id);
pst.setString(2, name);
pst.setString(3, birth);
pst.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(pst != null) {
pst.close();
pst = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
運行結果:
實例5:Batch批處理
復制代碼 代碼如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/person";
String user = "root";
String pwd = "admin";
Connection conn = null;
Statement st = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pwd);
st = conn.createStatement();
//添加批處理
st.addBatch("insert into student values(6,'Jerry','1995')");
st.addBatch("insert into student values(7,'Greg','1996')");
st.addBatch("insert into student values(8,'Ryan','1997')");
//執行批處理
st.executeBatch();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(st != null) {
st.close();
st = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
運行結果:
批處理比較簡單,只需先建立Statement對象,然後逐個添加批處理即可
最後使用executeBatch()方法執行批處理
此外,PreparedStatement對象也可以使用批處理
復制代碼 代碼如下:
PreparedStatement ps = conn.prepareStatement("insert into student values(?,?,?)");
ps.setInt(1,8);
ps.setString(2,"GG");
ps.setString(3,"1996");
ps.addBatch();
ps.executeBatch();
實例6:Transaction事務處理
事務處理是要求sql以單元的形式更新數據庫,要求其確保一致性
如銀行的轉賬業務,一方轉出後,另一方則增加
如果出現異常,那麼所有的操作則會回滾
復制代碼 代碼如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/person";
String user = "root";
String pwd = "admin";
Connection conn = null;
Statement st = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pwd);
//取消自動提交
conn.setAutoCommit(false);
st = conn.createStatement();
st.addBatch("insert into student values(6,'Jerry','1995')");
st.addBatch("insert into student values(7,'Greg','1996')");
st.addBatch("insert into student values(8,'Ryan','1997')");
st.executeBatch();
//提交後設置自動提交
conn.commit();
conn.setAutoCommit(true);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
if(conn != null) {
try {
//出現異常則回滾操作,然後設置自動提交
conn.rollback();
conn.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
}
} finally {
try {
if(st != null) {
st.close();
st = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
運行結果: