原文鏈接:http://blog.csdn.net/jiangwei0910410003/article/details/26164629
目錄1.摘要2.JDBC的使用步驟 1.注冊驅動 只做一次 2.建立連接Connection 3.創建執行SQL的語句Statement 4.處理執行結果ResultSet 5.釋放資源3.使用JDBC來實現CRUD的操作4.Statement中的sql依賴注入的問題5.JDBC中特殊數據類型的操作問題 1.第一個是日期問題 2.第二個問題就是大文本數據的問題6.JDBC中事務的概念7.JDBC中調用存儲過程8.JDBC來實現批處理功能9.JDBC中的滾動結果集和分頁技術10.JDBC中的可更新以及對更新敏感的結果集操作11.元數據的相關知識 1.數據庫的元數據信息 2.查詢參數的元數據信息 3.結果集中元數據信息12.JDBC中的數據源13.JDBC中CRUD的模板模式14.SPRing框架中的JdbcTemplate 1.加強版的JdbcTemplate 1.NamedParameterJdbcTemplate 2.SimpleJdbcTemplate
今天我們來說一下關于JDBC的相關知識,關于JDBC我想大家都不陌生了,而且我記得早就開始使用它了,記得那是大二的時候做課程設計,但是那時候是為了完成任務,所以遇到問題就google,那時候也沒有時間去整理,所以這次就來詳細說一下關于JDBC的知識
摘要:JDBC(Java Data Base Connectivity,java數據庫連接),由一些接口和類構成的API。 J2SE的一部分,由java.sql,javax.sql包組成。
應用程序、JDBC API、數據庫驅動及數據庫之間的關系
方式一:Class.forName(“com.MySQL.jdbc.Driver”); 推薦這種方式,不會對具體的驅動類產生依賴。 方式二:DriverManager.registerDriver(com.mysql.jdbc.Driver); 會造成DriverManager中產生兩個一樣的驅動,并會對具體的驅動類產生依賴。 方式三:System.setProperty(“jdbc.drivers”, “driver1:driver2”); 雖然不會對具體的驅動類產生依賴;但注冊不太方便,所以很少使用。 驅動類型(四種類型)
2.建立連接(Connection)[java] view plaincopyprint?Connection%20conn%20=%20DriverManager.getConnection(url,%20user,%20password);
url格式:%20JDBC:子協議:子名稱//主機名:端口/數據庫名?屬性名=屬性值&&hell
StatementStatement%20st%20=%20conn.createStatement();st.executeQuery(sql);PreparedStatementString%20sql%20=%20“select%20*%20from%20table_name%20where%20col_name=?”;PreparedStatement%20ps%20=%20conn.preparedStatement(sql);ps.setString(1,%20“col_value”);ps.executeQuery();4.處理執行結果(ResultSet)[java]%20view%20plaincopyprint?
ResultSet%20rs%20=%20statement.executeQuery(sql);While(rs.next()){rs.getString(“col_name”);rs.getInt(“col_name”);//…}5.釋放資源釋放ResultSet,%20Statement,Connection.%20數據庫連接(Connection)是非常稀有的資源,用完后必須馬上釋放,如果Connection不能及時正確的關閉將導致系統宕機。Connection的使用原則是盡量晚創建,盡量早的釋放。
下面來看一下完整的Demo:
工具類:JdbcUtils
[java]%20view%20plaincopyprint?package%20com.weijia.firstdemo;import%20java.sql.Connection;import%20java.sql.DriverManager;import%20java.sql.ResultSet;import%20java.sql.SQLException;import%20java.sql.Statement;import%20javax.sql.DataSource;public%20class%20JdbcUtils%20{private%20static%20String%20user%20=%20"root";private%20static%20String%20password%20=%20"123456";private%20static%20String%20dbName%20=%20"test";private%20static%20%20String%20url%20=%20"jdbc:mysql://localhost:3306/"+dbName+"?user="+user+"&password="+password+"&useUnicode=true&characterEncoding=gb2312";private%20static%20DataSource%20dataSource%20=%20null;/**%20*%20加載驅動%20*/static{try{Class.forName("com.mysql.jdbc.Driver");}catch(Exception%20e){System.out.println("Exception:"+e.getMessage()+"");throw%20new%20ExceptionInInitializerError(e);}}private%20JdbcUtils(){}/**%20*%20獲取連接%20*%20@return%20*%20@throws%20SQLException%20*/public%20static%20Connection%20getConnection()%20throws%20SQLException{return%20DriverManager.getConnection(url);}public%20static%20DataSource%20getDataSource(){return%20dataSource;}/**%20*%20釋放資源%20*%20@param%20rs%20*%20@param%20st%20*%20@param%20conn%20*/public%20static%20void%20free(ResultSet%20rs,Statement%20st,Connection%20conn){try{if(rs%20!=%20null){rs.close();}}catch(SQLException%20e){e.printStackTrace();}finally{try{if(st%20!=%20null){st.close();}}catch(SQLException%20e){e.printStackTrace();}finally{try{if(conn%20!=%20null){conn.close();}}catch(SQLException%20e){e.printStackTrace();}}}}}測試類:
[java]%20view%20plaincopyprint?package%20com.weijia.firstdemo;import%20java.sql.Connection;import%20java.sql.DriverManager;import%20java.sql.ResultSet;import%20java.sql.SQLException;import%20java.sql.Statement;public%20class%20Demo%20{public%20static%20void%20main(String[]%20args)%20throws%20Exception{//測試代碼:test();//標準規范代碼:template();}//模板代碼public%20static%20void%20template(){Connection%20conn%20=%20null;Statement%20st%20=%20null;ResultSet%20rs%20=%20null;try%20{conn%20=%20JdbcUtils.getConnection();//創建語句st%20=%20conn.createStatement();//執行語句rs%20=%20st.executeQuery("select%20*%20from%20user");//處理結果while(rs.next()){System.out.println(rs.getObject(1)%20+%20"/t"%20+%20rs.getObject(2)%20+%20"/t"%20+%20rs.getObject(3)%20+%20"/t");}}catch(SQLException%20e){e.printStackTrace();}catch(Exception%20e){e.printStackTrace();}finally{JdbcUtils.free(rs,%20st,%20conn);}}//測試static%20void%20test()%20throws%20Exception{//注冊驅動DriverManager.registerDriver(new%20com.mysql.jdbc.Driver());//通過系統屬性來注冊驅動System.setProperty("jdbc.drivers","");//靜態加載驅動Class.forName("com.mysql.jdbc.Driver");//建立連接String%20url%20=%20"jdbc:mysql://localhost:3306";String%20userName%20=%20"root";String%20password%20=%20"";Connection%20conn%20=%20DriverManager.getConnection(url,userName,password);//創建語句Statement%20st%20=%20conn.createStatement();//執行語句ResultSet%20rs%20=%20st.executeQuery("select%20*%20from%20user");//處理結果while(rs.next()){System.out.println(rs.getObject(1)%20+%20"/t"%20+%20rs.getObject(2)%20+%20"/t"%20+%20rs.getObject(3)%20+%20"/t");}//釋放資源rs.close();st.close();conn.close();}}注意:這里還要記住引入額外的jar.這個網上很多的,這里使用的是MySql,搜一下MySql驅動的jar就行了。這里我們將一些操作都放到一個工具類中,這種方式是很優雅的。
使用JDBC來實現CRUD的操作我們這里就采用分層操作:Dao層,Service層
首先看一下domain域中的User實體
[java]%20view%20plaincopyprint?package%20com.weijia.domain;import%20java.util.Date;public%20class%20User%20{private%20int%20id;private%20String%20name;private%20Date%20birthday;private%20float%20money;public%20User(){}public%20User(int%20id,String%20name,Date%20birthday,float%20money){this.id%20=%20id;this.name%20=%20name;this.birthday%20=%20birthday;this.money%20=%20money;}public%20int%20getId()%20{return%20id;}public%20void%20setId(int%20id)%20{this.id%20=%20id;}public%20String%20getName()%20{return%20name;}public%20void%20setName(String%20name)%20{this.name%20=%20name;}public%20Date%20getBirthday()%20{return%20birthday;}public%20void%20setBirthday(Date%20birthday)%20{this.birthday%20=%20birthday;}public%20float%20getMoney()%20{return%20money;}public%20void%20setMoney(float%20money)%20{this.money%20=%20money;}@Overridepublic%20String%20toString(){return%20"[id="+id+",name="+name+",birthday="+birthday+",money="+money+"]";}}再來看一下Dao層結構:
接口:
[java]%20view%20plaincopyprint?package%20com.weijia.domain;public%20interface%20UserDao%20{//添加用戶public%20void%20addUser(User%20user);//通過userid查詢用戶,id是唯一的,所以返回的是一個userpublic%20User%20getUserById(int%20userId);//更新用戶信息public%20int%20update(User%20user);//刪除用戶信息public%20int%20delete(User%20user);}實現類:
[java]%20view%20plaincopyprint?package%20com.weijia.domain;import%20java.sql.Connection;import%20java.sql.Date;import%20java.sql.PreparedStatement;import%20java.sql.ResultSet;import%20com.weijia.firstdemo.JdbcUtils;public%20class%20UserDaoImpl%20implements%20UserDao{/**%20*%20添加用戶%20*/public%20void%20addUser(User%20user)%20{Connection%20conn%20=%20null;PreparedStatement%20st%20=%20null;try{conn%20=%20JdbcUtils.getConnection();String%20sql%20=%20"insert%20into%20user(id,name,birthday,money)%20values(?,?,?,?)";st%20=%20conn.prepareStatement(sql);st.setInt(1,user.getId());st.setString(2,user.getName());//日期格式的轉換(utils.date轉化成sql.date)st.setDate(3,new%20Date(user.getBirthday().getTime()));st.setFloat(4,%20user.getMoney());int%20count%20=%20st.executeUpdate();System.out.println("添加記錄條數:"+count);}catch(Exception%20e){throw%20new%20DaoException(e.getMessage(),e);}finally{JdbcUtils.free(null,%20st,%20conn);}}/**%20*%20刪除用戶%20*/public%20int%20delete(User%20user)%20{Connection%20conn%20=%20null;PreparedStatement%20st%20=%20null;try{conn%20=%20JdbcUtils.getConnection();String%20sql%20=%20"delete%20from%20user%20where%20id=?";st%20=%20conn.prepareStatement(sql);st.setInt(1,user.getId());int%20count%20=%20-1;count%20=%20st.executeUpdate();System.out.println("刪除記錄條數:"+count);return%20count;}catch(Exception%20e){throw%20new%20DaoException(e.getMessage(),e);}finally{JdbcUtils.free(null,%20st,%20conn);}}/**%20*%20通過userId獲取用戶信息%20*/public%20User%20getUserById(int%20userId)%20{Connection%20conn%20=%20null;PreparedStatement%20st%20=%20null;ResultSet%20rs%20=%20null;try{conn%20=%20JdbcUtils.getConnection();String%20sql%20=%20"select%20*%20from%20user%20where%20id=?";st%20=%20conn.prepareStatement(sql);st.setInt(1,userId);rs%20=%20st.executeQuery();if(rs.next()){User%20user%20=%20new%20User();user.setId(userId);user.setName(rs.getString("name"));user.setBirthday(rs.getDate("birthday"));user.setMoney(rs.getFloat("money"));return%20user;}}catch(Exception%20e){throw%20new%20DaoException(e.getMessage(),e);}finally{JdbcUtils.free(rs,%20st,%20conn);}return%20null;}/**%20*%20更新用戶信息%20*/public%20int%20update(User%20user){Connection%20conn%20=%20null;PreparedStatement%20st%20=%20null;try{conn%20=%20JdbcUtils.getConnection();String%20sql%20=%20"update%20user%20set%20name=?,birthday=?,money=?%20where%20id=?";st%20=%20conn.prepareStatement(sql);st.setString(1,user.getName());st.setDate(2,new%20Date(user.getBirthday().getTime()));st.setFloat(3,user.getMoney());st.setInt(3,user.getId());int%20count%20=%200;count%20=%20st.executeUpdate();System.out.println("更新的記錄數:"+count);return%20count;}catch(Exception%20e){throw%20new%20DaoException(e.getMessage(),e);}finally{JdbcUtils.free(null,%20st,%20conn);}}}然后是Servic層:
[java]%20view%20plaincopyprint?package%20com.weijia.domain;public%20class%20UserService%20{private%20UserDao%20userDao;public%20UserService(){//通過工廠實例化UserDao對象userDao%20=%20DaoFactory.getInstance().createUserDao();System.out.println("userDao:"+userDao);}/**%20*%20注冊用戶%20*%20@param%20user%20*/public%20void%20regist(User%20user){if(user%20==%20null){System.out.println("注冊信息無效!!");}else{userDao.addUser(user);}}/**%20*%20查詢用戶%20*%20@param%20userId%20*%20@return%20*/public%20User%20query(int%20userId){User%20user%20=%20userDao.getUserById(userId);if(user%20==%20null){System.out.println("查詢結果為空!!");}else{System.out.println(user.getId()+"/t"+user.getName()+"/t"+user.getBirthday()+"/t"+user.getMoney());}return%20userDao.getUserById(userId);}/**%20*%20更新用戶%20*%20@param%20user%20*/public%20void%20update(User%20user){if(user.getId()<=0){System.out.println("用戶id無效,無法更新");}else{userDao.update(user);}}/**%20*%20刪除用戶%20*%20@param%20user%20*/public%20void%20delete(User%20user){if(user.getId()<=0){System.out.println("用戶id無效,無法刪除!!");}else{userDao.delete(user);}}}這里我們還需要額外的兩個類:
一個是異常類,因為我們需要自定義我們自己的一個異常,這樣方便進行捕獲:
[java]%20view%20plaincopyprint?package%20com.weijia.domain;public%20class%20DaoException%20extends%20RuntimeException{private%20static%20final%20long%20serialVersionUID%20=%201L;public%20DaoException(){}public%20DaoException(Exception%20e){super(e);}public%20DaoException(String%20msg){super(msg);}public%20DaoException(String%20msg,Exception%20e){super(msg,e);}}同時,我們這里面采用工廠模式進行實例化UserDao對象:
[java]%20view%20plaincopyprint?package%20com.weijia.domain;import%20java.io.FileInputStream;import%20java.util.Properties;public%20class%20DaoFactory%20{/**%20*%20單例模式%20*/private%20static%20UserDao%20userDao%20=%20null;private%20static%20DaoFactory%20instance%20=%20new%20DaoFactory();private%20DaoFactory(){/**%20*%20通過讀取屬性文件來動態的加載Dao層類%20*/Properties%20prop%20=%20new%20Properties();try{FileInputStream%20fis%20=%20new%20FileInputStream("src/com/weijia/domain/daoconfig.properties");prop.load(fis);String%20className%20=%20prop.getProperty("userDaoClass");Class<?>%20clazz%20=%20Class.forName(className);userDao%20=%20(UserDao)clazz.newInstance();fis.close();}catch(Throwable%20e){throw%20new%20ExceptionInInitializerError(e);}}public%20static%20DaoFactory%20getInstance(){return%20instance;}public%20UserDao%20createUserDao(){return%20userDao;}}這里面是讀取properties文件,然后去讀取類名進行加載,這種方式是很靈活的
測試:
[java]%20view%20plaincopyprint?package%20com.weijia.domain;import%20java.util.Date;public%20class%20TestDemo%20{public%20static%20void%20main(String[]%20args)%20throws%20Exception{UserService%20userService%20=%20new%20UserService();System.out.println("添加用戶:");userService.regist(new%20User(1,"jiangwei",new%20Date(System.currentTimeMillis()),300));}}這里我們看到其實這些操作真的很簡單,就是按照那樣的幾個步驟來操作即可,同時我們還需要將結構進行分層,以便管理,我們這里面測試的時候,撇開了創建數據庫的一個環節,至于那個環節,也是不難的,可以從網上搜索一下即可。
Statement中的sql依賴注入的問題接著來看一下關于我們上面的例子中使用了Statement進行操作的,其實這里面是存在一個問題的,就是會有sql注入的問題,我們先來看一下這個問題:
查詢學生信息:
[java]%20view%20plaincopyprint?新聞熱點
疑難解答