jdbc 編程(二)

 

JDBC處理大文本,JDBC處理圖片,JDBC進行批處理    數據庫連接池

參考文獻:https://www.cnblogs.com/shanheyongmu/p/5909539.html

參考文獻:https://www.cnblogs.com/shanheyongmu/p/5909922.html

 

1. 事務(Transaction,簡寫爲tx):

  所謂事務是用戶定義的一組操作,使數據從一種狀態變換到另一種狀態,要麼同時成功,要麼同時失敗。

2. 事務的操作:

  先定義開始一個事務,然後對數據作修改操作,這時如果提交(commit),這些修改就永久地保存下來,如果回退(rollback),數據庫管理系統將放棄您所作的所有修改而回到開始事務時的狀態。

3. 事務的ACID屬性:

  Atomic原子性、Consistency一致性、Isolation   [ˌaɪsəˈleɪʃn] 隔離性和 Durability 持久性。

  1、原子性(Atomicity)原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。 
  2、一致性(Consistency):事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。 
  3、隔離性(Isolation):事務的隔離性是指一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。 
  4、持久性(Durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來的其他操作和數據庫故障不應該對其有任何影響。)

4. 如何在代碼中去處理事務:

  1.在JDBC中,事務是默認提交的.  必須先設置事務爲手動提交.

    connection對象.setAutoCommit(false);//設置事務爲手動提交.

  2.手動的提交事務.

    connection對象.commit();

  3.若出現異常必須回滾事務:

     不回滾事務,總餘額依然是正確的. 若不回滾事務,不會釋放數據庫資源.

     connection對象.rollback();

 

 

6. 事務示例:

 

銀行轉帳功能: bank / money

 

過兒和姑姑:

過兒 : 10000塊錢

姑姑 : 0塊錢

 

轉賬:過兒要給姑姑轉1000塊錢

 

分析:轉錢需要提供兩條sql,但是程序員也會出錯,比較代碼寫錯了.

 

  ①update bank set money = money +1000 where name = '姑姑'

 

  ②代碼出錯,     會導致過兒賬戶錢少了,而姑姑賬戶沒有收到錢,錢去哪了?

 

  ③update bank set money =  money -1000 where name= '過兒'

解決辦法 代碼:

數據庫:

CREATE TABLE `bank` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

 

com.domain包下的  實體類 Bank 

package com.domain;

public class Bank {
	private String name;
	private double money;
	public Bank(String name, double money) {
		super();
		this.name = name;
		this.money = money;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	public Bank() {
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "Bank [name=" + name + ", money=" + money + "]";
	}
}

  

com.dao 包下的 IBankDao 接口

package com.dao;
import com.domain.Bank;

public interface IBankDao {
	void transMoney(Bank b1,Bank b2, double money);
}

  

com.dao .impl 包 的  BankDaoImpl 實現類

package com.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.Util.JDBCUtil;
import com.dao.IBankDao;
import com.domain.Bank;

public class BankDaoImpl implements IBankDao {
// 單利模式獲取 BankDaoImpl 類對象
	private  BankDaoImpl (){}
	private static BankDaoImpl instance = null;
	public static  BankDaoImpl getInstance(){
		if(instance == null){
			return instance = new BankDaoImpl();
		}
		return null;
	}
	@Override
	public void transMoney(Bank b1, Bank b2, double money) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = JDBCUtil.getInstance().getConnection();
			
		//在JDBC中,事務是默認提交的true.  必須先設置事務爲手動提交false
			conn.setAutoCommit(false);
			ps = conn.prepareStatement("update bank set money = money - ? where name = ? ");
			ps.setDouble(1, money);
			ps.setString(2, b1.getName() );
			ps.executeUpdate();
			
//			int a = 1/0;  //錯誤代碼
			
			ps = conn.prepareStatement("update bank set money = money + ? where name = ?");
			ps.setDouble(1, money);
			ps.setString(2, b2.getName());
			ps.executeUpdate();
			conn.commit();        //手動進行提交
			
		} catch (Exception e) {
			try {
				conn.rollback();  //數據回滾
			} catch (SQLException e1) {
				e1.printStackTrace();
			}   
		}
		JDBCUtil.getInstance().closeAll(null,ps,conn);
	}
}

 

測試類

public class TestBank {
	@Test
	public void trans(){
		Bank b1 = new Bank("過兒",10000);
		Bank b2 = new Bank("姑姑",0);
		BankDaoImpl.getInstance().transMoney(b1, b2, 1000);
	}
}

  

 7. 如何在JDBC中保存數據的時候獲取自動生成的主鍵呢?

Statement方式:

int executeUpdate(String sql,  int autoGeneratedKeys):執行SQL:

         參數:autoGeneratedKeys,是否需要返回自動生成的主鍵.常量值:Statement.RETURN_GENERATED_KEYS.

ResultSet getGeneratedKeys():獲取自動生成的主鍵

示列代碼如下:

@Test
    public void statementTest() throws Exception {
        String sql = "insert into student (name, age) values ('zhangsan', 30)";
        Connection connection = JdbcUtil.getConn();
        Statement statement = connection.createStatement();
        // statement.executeUpdate(sql);
        statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
        ResultSet resultSet = statement.getGeneratedKeys();
        if (resultSet.next()) {
            Long id = resultSet.getLong(1);
            System.out.println(id);
        }
        JdbcUtil.close(connection, statement, null);
    }

 

  

PreparedStatement方式:

PreparedStatement prepareStatement(String sql,int autoGeneratedKeys)  :

創建PreparedStatement對象,病指定是否需要返回生成的主鍵. 常量值:Statement.RETURN_GENERATED_KEYS

示列代碼:

public class PreparedStatementTest {
    @Test
    public void preparedStatement() throws Exception {
        String sql = "insert into student (name,age) values (?,?)";
        Connection connection = JdbcUtil.getConn();
        PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        preparedStatement.setString(1, "張三");
        preparedStatement.setInt(2, 24);
        preparedStatement.executeUpdate();
        ResultSet resultSet = preparedStatement.getGeneratedKeys();
        if (resultSet.next()) {
            Long id = resultSet.getLong(1);
            System.out.println(id);
        }
        JdbcUtil.close(connection, preparedStatement, null);
    }
}

 

  

部分類容參考:https://www.cnblogs.com/741162830qq/p/6733982.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章