Jdbc的總結
一. JDBC的總結
1.jdbc---->訪問資料庫的一組介面,用來操作關係型資料庫
簡單來說就是一組規範,將所有關係型資料庫都抽像出來的一組規 範。
2.作用:就是訪問不同的資料庫jdbc的語句是一樣的,
3.訪問資料庫的4個步驟:
載入驅動:
Class.forName(“com.mysql.jdbc.Driver”)
注意:對於不同的版本驅動是不一樣的
獲得連線:
Connection conn=DriverManager.getConnetion(url,user,password)
這裡的user和password對應的資料庫的使用者名稱和密碼
建立宣告:Statement st=conn.CreateStatement()
執行sql: st.execute(sql) 使用範圍:任何語句
st.executeQuery(sql) 返回的是一個集合(ResultSet),對於Update不適用,對於遍歷集合時用到next() 遊標,注意遊標第一次指向的是各屬性的那一行
st.executeUptate(sql) 返回的是執行sql語句後所更新的條數(int)
4.JDBC中重要的兩個類和介面:
DriverManager類:主要用來管理驅動和獲得資料庫的連線
Statement類:用來發送sql,包括三個方法: execute(),executeQuery(),executeUpdate()
Connection 介面:不能用來發送SQL,只是一個連線通道,用完要進行關閉
常用方法:
CreateStatement():建立宣告
PreparedStatement():建立預編譯的宣告
setAutocommit(Boolean ):管理事務是否為自動提交,預設為True
Commit();提交
rollback():回退
ResultSet介面:
常用方法:next():移動游標
get(type):獲得返回結果集中任何型別的資料
close():關閉資源,在1.7版本之後放在try(…sql)當執行完成自動關閉,無需在呼叫close()函式進行關閉
Jdbc的封裝:
在這裡插入程式碼片 package jdbcTest; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JdbcUtil { static String url="jdbc:mysql://localhost:3306/java1116"; static String userName="root"; static String password="tiger"; //封裝jdbc,首先載入驅動,因為驅動只加載一次,所以放在靜態塊中 static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Connection getConnection() { try { return DriverManager.getConnection(url, userName, password); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
5.sql注入的含義:通過傳遞一個sql片段來破壞原有的sql語句,達到sql攻擊的目的
6.為了實現動態引數引入和解決sql的注入PreparedStatement介面:
作用:
1.解決sql注問題
2.為不同的資料型別賦值更加方便
3.同一個sql執行時效能更好
如果sql語句中帶有引數時用PreparedStatement
具體例項:
/** * 購買圖書 * @param userid * @param bookid * @return */ public static boolean buy(int userid,int bookid) { //更新兩表;庫存表-1, 使用者表: 餘額-價格‘ String updata1="update bookstore set count=count-1 where bookid=?"; String updata2="update sys_user set remain=remain-(select price from book where bookid=?)where userid=?"; //查所剩於的數量和餘額是否大於零 String query1="select count from bookstore where bookid=?"; String query2="select remain from sys_user where userid=?"; Connection conn=JdbcUtil.getConnection(); try(PreparedStatement ps_u1=conn.prepareStatement(updata1); PreparedStatement ps_u2=conn.prepareStatement(updata2); PreparedStatement ps_q1=conn.prepareStatement(query1); PreparedStatement ps_q2=conn.prepareStatement(query2); ){ conn.setAutoCommit(false); //完成了兩個表的更新操作 ps_u1.setInt(1, bookid); ps_u1.execute(); ps_u2.setInt(1, bookid); ps_u2.setInt(2, userid); ps_u2.execute(); //查詢 ps_q1.setInt(1, bookid); ResultSet rs1= ps_q1.executeQuery(); rs1.next(); int store=rs1.getInt(1); ps_q2.setInt(1, userid); ResultSet rs2=ps_q2.executeQuery(); rs2.next(); int remain=rs2.getInt(1); if(store<0) { throw new Exception("庫存不足"); }else if(remain<0) { throw new Exception("餘額不足"); }else { conn.commit(); } System.out.println("購買成功 庫存為"+store+"餘額為"+remain); return true; }catch(Exception e) { e.printStackTrace(); }finally { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return false; }
7.JDBC中的Connection來解決事務的問題:
所謂的事務:就是使用者自定義的最小單元,事務中的操作是一個整體,要麼全做,要麼全不做。
在事務中用到的方法:
1.setAutoCommit(boolean )
2.Commit()
3.rollback()
執行事務的框架:
Connection conn=JdbcUtil.getConnection();
try(){
//sql語句
conn.commit();
}catch (Exception e) {
rollback();
}finally {
//關閉資源
}
8.Jdbc對打大物件的讀和取:
通過流的方式進行讀和取
讀方法:
setBinaryStream(1): 獲得BLOb的輸出流
CreateBlob() 建立一個大物件
取方法:
getBinaryStream(); 得到BLOb輸入流
CreateBlob() 建立一個大物件
package jdbcTest;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class BigObject {
public static void main(String[] args) throws Exception {
//write();
read();
}
public static void write() throws Exception {
//將一張圖片存到資料庫中
//通過流的方式寫入資料庫中
String sql="insert into emp(empno,ename,picName,pic) values(null,?,?,?)";
//只有表的主鍵為自動增長時才能在插入資料的時候寫null
try(Connection conn=JdbcUtil.getConnection();
PreparedStatement ps=conn.prepareStatement(sql);){
//建立一個Blob物件
Blob blob=conn.createBlob();
//獲得輸出流,利用os將從磁碟中得到的圖片寫入到資料庫中
OutputStream os=blob.setBinaryStream(1);
FileInputStream fis=new FileInputStream("d:/111.jpg");
byte[] by=new byte[100];//快取陣列
int size=-1;
while((size=fis.read(by))!=-1) {
os.write(by, 0, size);
}
ps.setString(1,"莫清");
ps.setString(2, "宿舍");
ps.setBlob(3, blob);
ps.execute();
System.out.println("執行完畢");
fis.close();
os.close();
}
}
public static void read() throws Exception {
String sql="select * from emp where empno=1";
try(Connection conn=JdbcUtil.getConnection();
//如果沒有?號的時候沒有必要用PreparedStatement
Statement st=conn.createStatement();
//看是否返回結果集
ResultSet rs=st.executeQuery(sql)){
rs.next();
Blob blob=rs.getBlob(4);
InputStream is=blob.getBinaryStream();
FileOutputStream fos=new FileOutputStream("d:/picture/hh.jpg");
byte[] by=new byte[100];
int size=-1;
while((size=is.read(by))!=-1) {
fos.write(by, 0, size);
}
is.close();
fos.close();
}
}
}