JDBC及操作數據庫步驟
概念
JDBC-數據庫連接,是由一些類和接口構成的API,是J2SE的一部分,有java.sql、javax.sql包組成。下面看一下JDBC API與應用程序和數據庫驅動及數據庫之間的關系:
可以看出JDBC是Sun公司為應用程序與數據庫驅動之間提供的一組接口(規范)。
操作數據庫的步驟(以mySql為例)
與ODBC類似,分為以下幾步:
1. 注冊驅動
2. 建立連接
3. 創建執行sql語句的對象
4. 執行語句
5. 處理執行結果
6. 釋放資源
下面進行詳解:
1. 注冊驅動
常用的有3種方式:
1) 直接注冊驅動:
DriverManager.registerDriver(com.mysql.jdbc.Driver);這種方式要求程序首先要引入驅動包,否則無法通過編譯。而且它可能會造成DriverManager中產生兩個一樣的驅動,并對具體的驅動類產生依賴,所以不推薦使用。
2) 鍵值對方式:
System.setProperty(“jdbc.drivers”,”com.mysql.jdbc.Driver”);同時注冊多個驅動則用冒號隔開。這種方式如果事先不引入驅動包的情況下能通過編譯(因為操作的都為字符串,運行時肯定不行啦),所以雖然不會對具體的驅動類產生依賴,但注冊不太方便,所以很少使用。
3) Class.forName方式(類似反射):
Class.forName(“com.mysql.jdbc.Driver”); Class.forName函數的作用是根據類的名字將類裝載到虛擬機中(并未實例化);這種方式也不會對具體的驅動類產生依賴,而且使用很方便,所以推薦使用。
2. 建立連接
Connection conn=DriverManager.getConnection(url,uid,pwd);
url格式:JDBC:子協議:子名稱//主機名:端口/數據庫名?key=value&…
例如:jdbc:mysql://localhost:8086/jdbc;uid和pwd也可以用key=value的方式告訴數據庫。
其它參數:如,userUnicode=true&characterEncoding=gbk
3. 創建執行sql語句的對象
這里有兩個對象可以使用:Statement、PreparedStatement對象
一般來說有參數的sql操作都用PreparedStatement對象,因為它有防止sql注入等優點。兩者的區別這里不多介紹,創建語句:(假設conn為數據庫連接對象)
Statement st=conn.createStatement();
PreparedStatement ps=conn.prepareStatement(strSql);
可以看出在創建PreparedStatement對象時即需要指明要執行的sql語句,因為它會對sql語句進行預處理,例如進行一些防止sql注入的字符過濾等;而Statement則在執行sql動作時才指明sql語句。
4. 執行語句(CURD)
查詢:st.executeQuery(strSql);或者ps. executeQuery();
非查詢(增、刪、改):st.executeUpdate(strSql);或ps.executeUpdate();
5. 處理執行結果
查詢:返回值用ResultSet接收,例:ResultSet rs=st.executeQuery(strsql)
非查詢(增、刪、改):返回值為int
6. 釋放資源
依次釋放ResultSet、Statement(或PreparedStatement)、Connection對象,釋放順序與創建順序相反(類似“棧”結構)。
注意,Connection是非常稀有的資源,用完必須馬上釋放,它的使用原則是盡量晚的創建,盡量早的釋放,以減少占用資源的時間。
下面看一個最普通的操作代碼:
//以mysql為例 public static void test() throws ClassNotFoundException, SQLException{ /*1.注冊驅動(3種方法),依賴于驅動jar包的存在,否則無法通過編譯 DriverManager.registerDriver(new com.mysql.jdbc.Driver());*/ //方法2:System.setProperties("jdbc.drivers","com.mysql.jdbc.Driver"); //方法3:*****推薦使用****** Class.forName("com.mysql.jdbc.Driver"); //2.建立連接 Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:8086/jdbc","zhipeng","123456"); //3.創建語句執行對象 java.sql.Statement st=conn.createStatement();//使用Statement對象 //4.執行語句 ResultSet rs=st.executeQuery("select * from T_User"); //5.處理結果 while(rs.next()){ System.out.print(rs.getObject(1)+"\t"+rs.getObject(2)+"\t"+rs.getObject(3)+"\t"); } //6.釋放資源,資源rs、st、conn的釋放順序與創建順序相反 rs.close(); st.close(); conn.close(); } }
當然真正使用時要對上面的代碼進行優化封裝等,比如需要將注冊驅動、建立連接、釋放資源的操作封裝到一個工具類中,然后用單例模式為該類加鎖(synchronized)以限制多線程沖突問題。