一、大資料集的分頁
1、記憶體分頁:將資料全部取出來放到List中,然後再進行分頁。(不可取的)
2、資料庫層分頁:按照頁碼從資料查詢。
MySQL:Select * from table limit M,N
M:開始記錄的索引
N:取出的條數
假設每頁顯示10條記錄
第一頁資料:select * from customer limit 0,10;
第二頁資料:select * from customer limit 10,10;
每頁開始記錄的索引=(頁碼-1)*10
總共有多少頁:總記錄數%10==0?總記錄數/10:總記錄數/10+1
總記錄數:select count(*) from customer;
Dao:
int getTotalCount();//擷取總記錄數
List<Customer> findCustomer(int startIndex,int pageSize);
3、其他需要分頁的業務該怎麼編寫
a、Dao:需要兩個分頁的方法
int getTotalCount();//擷取總記錄數
List<Customer> findCustomer(int startIndex,int pageSize);//startIndex開始記錄的索引
//pageSize每頁顯示的記錄數
b、Service:將分頁相關的資料封裝到Page對象中
public Page findCustomers(int pagenum);//pagenum使用者要查看的頁面
用以下代碼進行實現該方法
public Page findCustomers(int pagenum) {
int totalrecord = dao.getTotalCount();
Page page = new Page(totalrecord, pagenum);
List<Customer> cs = dao.findCustomer(page.getStartIndex(), page.getPagesize());
page.setList(cs);//一定要把分頁的結果放到page對象中
return page;
}
c、Servlet:擷取使用者要查看的頁面,調用service層獲得page對象,封裝資料,轉向顯示頁面。
註:不要忘記設定page對象的url屬性。該屬性指向處理分頁的Serlvet的url地址,比如/servlet/SomeServlet
d、jsp:用於顯示分頁資料
分頁資料用靜態包含的形式把page.jsp包含進來。page.jsp不需要做任何的修改
二、2.1大資料的讀寫
BLOB:
//從結果集中得到BLOB對象的二進位輸入資料流
InputStream in = resultSet.getBinaryStream(i);
InputStream in = resultSet.getBlob(i).getBinaryStream();
//設定BLOB先行編譯,根據絕對路徑得到輸入資料流, //注意length長度須設定,並且設定為int型,利用File擷取
PreparedStatement. setBinaryStream(i, inputStream, length);
CLOB:
擷取:
reader = resultSet. getCharacterStream(i);
reader = resultSet.getClob(i).getCharacterStream();
string s = resultSet.getString(i);
設定:
String path = classLoader();
File f = new File(path);
PreparedStatement.setCharacterStream(index, reader, length);
//注意length長度須設定,並且設定為int型,利用File擷取
2.2 批處理
實現批處理有兩種方式,第一種方式:
Statement.addBatch(sql) list
執行批處理SQL語句
executeBatch()方法:執行批處理命令
clearBatch()方法:清除批處理命令
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConnection();
String sql1 = "insert into user(name,password,email,birthday)
values('kkk','123','abc@sina.com','1978-08-08')";
String sql2 = "update user set password='123456' where id=3";
st = conn.createStatement();
st.addBatch(sql1); //把SQL語句加入到批命令中
st.addBatch(sql2); //把SQL語句加入到批命令中
st.executeBatch();
} finally{
JdbcUtil.free(conn, st, rs);
}
採用Statement.addBatch(sql)方式實現批處理:
優點:可以向資料庫發送多條不同的SQL語句。
缺點:
SQL語句沒有先行編譯。
當向資料庫發送多條語句相同,但僅參數不同的SQL語句時,需重複寫上很多條SQL語句
實現批處理的第二種方式:
PreparedStatement.addBatch()
注意記憶體溢出問題
具體應用時需要進行細化分批處理
conn = JdbcUtil.getConnection();
String sql = "insert into user(name,password,email,birthday) values(?,?,?,?)";
st = conn.prepareStatement(sql);
for(int i=0;i<50000;i++){
st.setString(1, "aaa" + i);
st.setString(2, "123" + i);
st.setString(3, "aaa" + i + "@sina.com");
st.setDate(4,new Date(1980, 10, 10));
st.addBatch();
if(i%1000==0){ //每1000條處理一次,處理完進行清零
st.executeBatch();
st.clearBatch();
}
}
st.executeBatch();//超出的部分也需要按一次批處理執行
採用PreparedStatement.addBatch()實現批處理
優點:發送的是先行編譯後的SQL語句,執行效率高。
缺點:只能應用在SQL語句相同,但參數不同的批處理中。因此此種形式的批處理經常用於在同一個表中批量插入資料,或批次更新表的資料。
2.3 得到資料庫自動產生的主鍵
eg:
Connection conn = JdbcUtil.getConnection();
String sql = "insert into user(name,password,email,birthday)
values('abc','123','abc@sina.com','1978-08-08')";
PreparedStatement st = conn.
prepareStatement(sql,Statement.RETURN_GENERATED_KEYS );
st.executeUpdate();
ResultSet rs = st.getGeneratedKeys(); //得到插入行的主鍵
if(rs.next())
System.out.println(rs.getObject(1));
2.4JDBC調用預存程序
編寫預存程序
delimiter $$
CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam varchar(255))
BEGIN
SELECT CONCAT('zyxw---', inputParam) into inOutParam;
END $$
delimiter ;
得到
CallableStatement stmt = conn.prepareCall("{call demoSp(?,?)}");
設定參數,註冊傳回值並輸出
stmt.setString(1, "abcde");
stmt.registerOutParameter(2, Types.VARCHAR);
stmt.execute();
System.out.println(stmt.getString(2));
result: zyxw---abcde
三、事務的入門
當Jdbc程式向資料庫獲得一個Connection對象時,預設情況下這個Connection對象會自動向資料庫提交在它上面發送的SQL語句。若想關閉這種預設提交方式,讓多條SQL在一個事務中執行,可使用下列語句:
JDBC控制事務語句
//開啟事務
conn.setAutoCommit(false);
//提交事務
conn.commit();
//設定事務儲存點
SavePoint sp = conn.setSavePoint();
//交易回復//復原後必須要提交
conn.rollback(sp);
conn.commit();
四、事務的隔離等級
事務的特性:
原子性(Atomicity) 原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。?
一致性(Consistency) 事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態。
隔離性(Isolation) 事務的隔離性是多個使用者並發訪問資料庫時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作資料所幹擾,多個並發事務之間要相互隔離。
持久性(Durability) 持久性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來即使資料庫發生故障也不應該對其有任何影響
事務的異常情況:
髒讀:
指一個事務讀取了另外一個事務未提交的資料。
不可重複讀取(針對一條記錄的,同一條記錄前後不一樣)
在一個事務內讀取表中的某一行資料,多次讀取結果不同。
虛讀(幻讀,同一張表前後不一樣記錄數)
1、READ UNCOMMITTED:髒讀、不可重複讀取、虛讀都可能發生
2、READ COMMITTED:可以防止髒讀,不可重複讀取、虛讀有可能發生
3、REPEATABLE READ:可以防止髒讀、不可重複讀取,虛讀有可能發生
4、SERIALIZABLE:可以防止髒讀、不可重複讀取、虛讀的發生。(鎖)
注意:設定事務的隔離等級必須在開啟事務之前,否則無法生效
eg:
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
conn.setAutoCommit(false);