jdbc封装类(连接参数配置与web.xml)
上次的博客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拿掉,放入调用的方法中,关闭也是调用的方法自己进行关闭
有兴趣的朋友可以自行修改下
希望多多交流,多多关注,共同成就梦想