1. 程式人生 > >Jdbc的總結

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();	
		}
		
	}
}