上次的博客JDBC封裝類 http://www.cnblogs.com/shenliang123/archive/2012/04/19/2456665.html 在實際的使用出現了使用上的不方便,不去說其他的,單單說數據庫
連接的參數,因為數據庫連接參數(className,url,uer,psw等)都是在類中進行硬編碼的,在開發時是不會有什么問題,但是項目放到服務器上后就出現問題了,因為服務器上的
數據庫密碼等很有可能是跟你本地的不一樣的,因此我們就需要更改,但服務器下的項目已經是被編譯的,java類是能進行更改的,故還需要到本地IDE中將其更改后重新編譯在放到
服務器上,這樣就很不方便,因此就打算將參數配置與xml或property文件中:
這里為了不新的配置文件就直接在web.xml進行參數的配置,然后相應的servlet進行讀取后傳遞給DbConn:
web.xml:
<servlet> <servlet-name>dbconn</servlet-name> <servlet-class>xidian.sl.equipment.Servlet.DbConnServlet</servlet-class> <init-param> <param-name>className</param-name> <param-value>net.sourceforge.jtds.jdbc.Driver</param-value> </init-param> <init-param> <param-name>connUrl</param-name> <param-value>jdbc:jtds:sqlserver://localhost:9433;DatabaseName=SportsUnion2</param-value> </init-param> <init-param> <param-name>uname</param-name> <param-value>sa</param-value> </init-param> <init-param> <param-name>psw</param-name> <param-value>123@sports</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet>
xidian.sl.equipment.Servlet.DbConnServlet:
package xidian.sl.equipment.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import xidian.sl.equipment.util.DbConn; public class DbConnServlet extends HttpServlet{ /** * 負責數據庫連接數據的獲得,配置於web.xml */ private static final long serialVersionUID = 1L; private String className = null; private String uname = null; private String connUrl = null; private String psw = null; /** * 在ServletConfig和ServletContext都有getInitParameter方法, 這兩個方法的都能從web.xml中獲取參數 * */ public void init() throws ServletException { /** * 利用getInitParameter()方法從web.xml中獲得為該servlet配置的初始化參數 * */ this.className = this.getInitParameter("className"); this.connUrl = this.getInitParameter("connUrl"); this.uname = this.getInitParameter("uname"); this.psw = this.getInitParameter("psw"); System.out.println("獲取的所有參數 = "+ className+ connUrl+ uname + psw); DbConn.getconn(className, connUrl, uname, psw);//Web容器啟動后調用 } }
DbConn:
package xidian.sl.equipment.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.Vector; public class DbConn { @SuppressWarnings("unchecked") private static Vector dsVector; static int rowCount = 0; static int colCount = 0; public static String[] type = null; static boolean flag = true; /** * 由於參數的值是靠外部servlet進行傳遞的,而變量卻需要多次使用,因此設為全局變量 * 並且由於servlet傳入值只會在容器啟動的時候,因此設為static * */ static String classNames = null; static String url = null; static String user = null; static String psw = null; /** * 進行查詢的sql的實現 * */ @SuppressWarnings("unchecked") public static String[][] query(String sql){ getData(sql); String dsString[][] = new String[rowCount][colCount]; if(flag == true){ dsString = null; }else{ for (int i = 0; i< rowCount; i++){ Vector row = new Vector(); row = (Vector)dsVector.get(i); for(int j = 0; j<colCount; j++){ dsString[i][j] = (String)row.get(j); } } } dsVector.clear(); return dsString; } /** * 執行除查詢外的所有sql語句 * */ public static int exceptQuery(String sql){ Connection conn=DbConn.getconn(classNames, url, user, psw); Statement stmt=null; int count=0; try { conn.setAutoCommit(false); stmt=conn.createStatement(); count=stmt.executeUpdate(sql); conn.commit(); } catch (SQLException e) { try{ conn.rollback(); }catch(SQLException e1){ e1.printStackTrace(); } e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); }finally{ DbConn.closeConn(conn); } return count; } /** * 執行查詢的sql語句 * */ @SuppressWarnings("unchecked") private static int getData(String sql){ Connection conn = DbConn.getconn(classNames, url, user, psw); dsVector = new Vector(); Statement stmt = null; ResultSet rs = null; rowCount = 0; colCount = 0; try { stmt = conn.createStatement(); rs = stmt.executeQuery(sql); flag = true; while(rs.next()){ flag = false; rowCount++; ResultSetMetaData rsmd = rs.getMetaData(); Vector row = new Vector(); colCount = rsmd.getColumnCount(); for( int i = 0; i< colCount; i++){ row.add(rs.getString(i+1)); } dsVector.add(row); } } catch (SQLException e) { System.out.print(e.getErrorCode()); e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); }finally{ DbConn.closeConn(conn); } return rowCount; } /** * 進行數據庫的基本連接 * */ public static Connection getconn(String className, String connUrl, String uname, String upsw){ classNames = className; url = connUrl; user = uname; psw = upsw; try { Class.forName(classNames).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection conn = null; try { conn = DriverManager.getConnection(url, user, psw); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 進行數據庫連接的關閉 * */ public static void closeConn(Connection conn){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
大家也可以直接使用.property配置文件進行參數的配置,也是很方便的;
??????????????????????????????
很久沒用jdbc了,前段時間看了下這個封裝類,感覺封裝的有點問題,太死了,導致事務沒法開啟,並且這樣的封裝執行效率很低
問題:可以看到這個的方法都是自己新起一個連接,然后再自行關閉,看起來好像不錯,但當一個方法需要多次調用封裝類中的更新方法進行很多數據的更新,連接就需要不斷的開啟和關閉,而且將連接連接con寫到這么原子的方法中,導致調用該方法的方法中無法實現事務
改進:將連接con拿掉,放入調用的方法中,關閉也是調用的方法自己進行關閉
有興趣的朋友可以自行修改下
