基礎知識回顧第三篇數據庫訪問,基礎知識回顧第三篇
前言:本篇主要針對數據庫的操作,在這裡不適用hibernate或者mybatis,用最原始的JDBC進行講解,通過了解這些原理以後更容易理解和學習hibernate或mybatis。
1:jdbc的簡單操作
首先需要下載jdbc驅動的jar包 如果不想下載在C:\Program Files (x86)\MySQL\Connector J 5.1.26位置也可以找到 如果是maven項目的話需要在pom上引入下面的依賴包

![]()
1 <dependency>
2 <groupId>mysql</groupId>
3 <artifactId>mysql-connector-java</artifactId>
4 <version>5.1.26</version>
5 </dependency>
View Code
1.1:配置連接數據庫

![]()
1 Class.forName("com.mysql.jdbc.Driver");//加載數據庫驅動
2 String url="jdbc:mysql://localhost:3306/blog";//數據連接地址
3 String username="root";//登錄名
4 String password="123456";//密碼
5 connection=DriverManager.getConnection(url, username, password);//獲取數據庫的連接
View Code
1.2:向數據庫發起請求(增刪改查)
1.2.1:statement
statement用於已經建立好數據庫連接的基礎上發送sql語句的對象,不帶參數簡單的sql語句
1.2.2:PreparedStatement
由於在程序中傳遞sql語句必須要經過預編譯,包括分析,優化等,如果重復執行一條只是參數不同的sql是比較低效的,那麼久可以使用preparedStatement對象對sql語句進行預編譯。(推薦使用)
1.2.3:CallableStatement
這個表示處理存儲過程的對象。
1.3:ResultSet的作用
這個主要是sql執行以後返回的結果集,然後通過next屬性來轉換相關的結果
1.4:executeUpdate()、executeQuery()、execute()三者區別
executeUpdate()主要處理增刪改語句,返回受影響的行數,也可以處理創建或更新數據庫、以及創建或更新表結構
executeQuery()主要是用來查詢的,主要針對select開頭的語句
execute()表示一個特殊的執行,主要針對返回多個結果集、多個更新計數,相對來說用的少些
粘貼一下代碼

![]()
1 public class JDBCHelper {
2 private Connection connection;
3 private PreparedStatement preparedStatement;
4 public JDBCHelper(){
5 try {
6 Class.forName("com.mysql.jdbc.Driver");
7 String url="jdbc:mysql://localhost:3306/blog";
8 String username="root";
9 String password="123456";
10 connection=DriverManager.getConnection(url, username, password);
11 }
12 catch (ClassNotFoundException e) {
13 e.printStackTrace();
14 } catch (SQLException e) {
15 e.printStackTrace();
16 }
17 }
18 /**
19 * 創建數據庫
20 * sql語句
21 */
22 public void createDatabase(String sql)
23 {
24 Statement statement=null;
25 try {
26 statement=connection.createStatement();//主要用戶不帶參數的簡單sql語句()執行靜態SQL語句返回它生成結果
27 statement.executeUpdate(sql);
28 System.out.println("數據庫創建成功");
29 } catch (SQLException e) {
30 e.printStackTrace();
31 }
32 finally {
33 if (statement!=null) {
34 try {
35 statement.close();
36 } catch (SQLException e) {
37 }
38 statement=null;
39 }
40 }
41 }
42 /**
43 * 增刪改
44 * @param sql
45 * @param paramters
46 * @return
47 * @throws SQLException
48 */
49 public int update(String sql,Object... paramters) throws SQLException
50 {
51 try{
52 preparedStatement =connection.prepareStatement(sql);
53 for (int i = 0; i < paramters.length; i++) {
54 preparedStatement.setObject(i+1, paramters[i]);
55 }
56 return preparedStatement.executeUpdate();
57 }
58 catch(SQLException e)
59 {
60 e.printStackTrace();
61 }
62 finally {
63 if(preparedStatement!=null)
64 {
65 preparedStatement.close();
66 }
67 preparedStatement=null;
68 }
69 return 0;
70 }
71 /**
72 * 用與查詢
73 * @param sql
74 * @param paramters
75 * @return
76 * @throws SQLException
77 */
78 public ResultSet query(String sql,Object... paramters) throws SQLException
79 {
80 try{
81 preparedStatement =connection.prepareStatement(sql);
82 for (int i = 0; i < paramters.length; i++) {
83 preparedStatement.setObject(i+1, paramters[i]);
84 }
85 return preparedStatement.executeQuery();
86 }
87 catch(SQLException e)
88 {
89 e.printStackTrace();
90 }
91 finally {
92 if(preparedStatement!=null)
93 {
94 preparedStatement.close();
95 }
96 preparedStatement=null;
97 }
98 return null;
99 }
100 }
JDBCHelper
1.4:數據庫事務
事務的定義:訪問並可能更新數據庫中各種數據項的一個程序執行單元(籠統的將就是一段程序執行所有的sql要麼同時成功,要麼就全部失敗回滾)
我們了解事務之前先看三個定義
髒讀:一個事務正在修改某行數據但是並未提交,而另一個事務正好讀取了這行數據,這就是髒讀
不可重復讀:一個事務讀取了一行數據,在這個事務結束前另一個事務對這條數據進行修改,但是這種修改並沒有提交數據庫中,此時第一個事務再次讀取這條數據時,出現了2次數據不一致這就是不可重復讀
幻讀:當一個事務讀取滿足條件的數據後,另一個事務卻插入一條數據,當第一個事務再次讀取時,發現多了一條數據。這就是幻讀。
因為上面三種情況存在所以就出現了隔離級別,當然隔離級別越高效率會越低,下面是4中隔離級別
connection.TRANSACTION_READ_UNCOMMITTED:這種隔離級別最低三種情況都可能發生
connection.TRANSACTION_READ_COMMITTED:這種隔離級別避免髒讀
connection.TRANSACTION_REPEATABLE_READ:這種隔離級別避免髒讀和不可重讀讀
connection.TRANSACTION_SERIALIZABLE:這種隔離級別最高三種都可避免
當了解完這種情況以後我們就可開始進行事務處理,在默認的情況下是不執行事務的。
第一步是要開啟事務:connection.setAutoCommit(false);//關閉自動提交功能(默認是true)
然後在設置隔離級別:connection.setTransactionIsolation(connection.TRANSACTION_REPEATABLE_READ);
ok有了上面的我們就可以進行事務了下面把代碼貼出來,僅供參考

![]()
1 public void addUserAndRole(UserBean userbean,UserRoleBean userRoleBean) throws SQLException
2 {
3 connection.setAutoCommit(false);//關閉自動提交功能
4 connection.setTransactionIsolation(connection.TRANSACTION_REPEATABLE_READ);
5
6
7 String userSql="insert into b_user(name,password,level,des,tel)values"+
8 "(?,?,?,?,?)";
9 String roleSql="insert into b_user_role(userId,roleId)values(?,?)";
10 try {
11
12 preparedStatement =connection.prepareStatement(userSql);
13 preparedStatement.setString(1, userbean.getName());
14 preparedStatement.setString(2, userbean.getPassword());
15 preparedStatement.setInt(3, userbean.getLevel());
16 preparedStatement.setString(4, userbean.getDes());
17 preparedStatement.setString(5, userbean.getTel());
18 preparedStatement.executeUpdate();
19 if (userRoleBean.getRoleId()==0) {
20 throw new Exception();
21 }
22 preparedStatement=connection.prepareStatement(roleSql);
23 preparedStatement.setInt(1, userRoleBean.getUserId());
24 preparedStatement.setInt(2, userRoleBean.getRoleId());
25 preparedStatement.execute();
26 connection.commit();
27 System.out.println("執行成功");
28 } catch (Exception e) {
29 System.out.println("執行失敗");
30 connection.rollback();
31 }
32 }
Transaction

![]()
1 public static void main(String[] args)
2 {
3 JDBCHelper jdbcHelper=new JDBCHelper();
4 UserBean userBean=new UserBean();
5 userBean.setName("張三");
6 userBean.setPassword("123456");
7 userBean.setLevel(1);
8 userBean.setDes("...");
9 userBean.setTel("123456");
10
11 UserRoleBean userRoleBean=new UserRoleBean();
12 userRoleBean.setRoleId(0);
13 userRoleBean.setUserId(2);
14
15 try {
16 jdbcHelper.addUserAndRole(userBean, userRoleBean);
17 } catch (SQLException e) {
18 // TODO Auto-generated catch block
19 e.printStackTrace();
20 }
21 }
main
經過測試發現
數據庫中也不存在相應的數據。
1.5:數據庫連接池
本人推薦看寫的很詳細http://www.cnblogs.com/xdp-gacl/p/4002804.html