彭老师帮看下我自己封装了个JDBC的通用查询,更新函数有没有什么问题。

06-09-16 wgmao

函数功能实现通用的增删改查,这个是第一版,还需要加的功能很多,希望把问题在萌芽阶段就找出来。

public class DBJdbcRunners {
	private static Log log = LogFactory.getLog(DBJdbcRunners.class);
	private boolean autoCommit;
    Connection connection = null;
	
    public DBJdbcRunners()throws SQLException{
    	autoCommit = true;
    	try {
    		 connection = DBUtils.getConnection();
		} catch (SQLException e) {
			 throw new SQLException();
		}
    }
    public void begintx()throws SQLException{
    	autoCommit = false;
    	if (connection != null){
    		try {
    		connection.setAutoCommit(false);
    		} catch (SQLException e) {
   			 throw new SQLException();
   		}
      }
    }
    public void committx()throws SQLException{
    	autoCommit = false;
    	if (connection != null){
    		try {
    		connection.commit();
    		connection.setAutoCommit(true);
    		autoCommit = true;
    		} catch (SQLException e) {
    		 log.equals("committx exception is ->["+e+"]");
   			 throw new SQLException();
   		}finally{
    			DBUtils.closeConnection(connection);
    	}
      }
    }

	  public int executeUpdate (String sql) throws SQLException,
		 InputIllegalException
	  {
	       Statement statement = null;	       
	      try
	      {
	
	          statement = connection.createStatement();
	         int i = statement.executeUpdate(sql);
				return i;
	   }catch( SQLException e){
		   log.error("error sql is-->["+sql+"]");
		   log.error(e);
		   if(!autoCommit){
		   try{
		   connection.rollback();
		   }catch(SQLException ex){
			   log.error(ex);
		   }
		}
          throw new SQLException();
	   }
	   finally{
		      DBUtils.closeStatement(statement);
		   if(autoCommit){
	      DBUtils.closeConnection(connection);
	      }
	   }
	  }
	   

  public  void executeQuery (
		  String sql,boolean isgetTotalNum)
          throws SQLException,InputIllegalException{
	   
       Statement statement = null;
       PreparedStatement p_statement = null;
       ResultSet rs = null;
       if(sql == null){
    	   throw new InputIllegalException("in executeQuery function" +
    	   		"sql is null");
       }
       try{
    	   if(isgetTotalNum){
    		   statement = connection.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,  
	                   ResultSet.CONCUR_READ_ONLY);
    	   }else{
    	   statement = connection.createStatement();
    	   }
    	   rs = statement.executeQuery(sql);
    	   if(isgetTotalNum){
    		   rs.last();
    		   log.debug("total row num is-->["+rs.getRow()+"]");
    		   rs.first();
    	   }
    	   ResultSetMetaData rsmd = rs.getMetaData();
    	   int numCols = rsmd.getColumnCount();
    	   log.debug("column num is-->["+rsmd.getColumnCount()+"]");
    	  
    	   while(rs.next()){
    		   for(int i=1;i<=numCols;i++){
    			   System.out.print("column "+i+" is-->["+rs.getString(i)+"]");
    		   }
    		   System.out.print("\n");
    	   }
	   }catch( SQLException e){
		   log.error("error sql is-->["+sql+"]");
		   log.error("[ex in executeQuery function]-->["+e+"]");
		   if(!autoCommit){
		     try{
			   if(log.isDebugEnabled()){
		    	   log.debug("[in executeQuery function rollback]");
		       }
		       connection.rollback();
		     }catch(SQLException ex){
			   log.error(ex);
		     }
		   }
          throw new SQLException();
	   }
	   finally{
			  DBUtils.closeResultSet(rs);
		      DBUtils.closeStatement(statement);
		      if(autoCommit){
	           DBUtils.closeConnection(connection);
	          }
	   }
	   
  }
  
}
<p>

wgmao
2006-09-16 18:59

public class testDBQuery {
	private static Log log = LogFactory.getLog(testDBQuery.class);
public static void main(String[] args) {
	DBJdbcRunners query = null;
	try {	query.begintx();
		query.executeUpdate("insert into user (id,name) values(9001,'wgm')");
		  query.executeQuery("select id, name from user order by id",true);
	query.committx();
} catch (Exception e) {
		//System.out.print(rowSet.print());
		e.printStackTrace();
	}
}

}
<p>

以上在MYSQL数据库,INFORMIX数据库上都已经测试过,支持事物。

查询结果正确。

说明在DBJdbcRunners中DBUtils.getConnection();

DBUtils.closeResultSet(rs); DBUtils.closeStatement(statement); DBUtils.closeConnection(connection);

是写的一个通用方法DBUtils,管理连接,结果集和statement。

但我不知道这种调用方式会不会有其他的问题,所以请大家帮我参考下。

===========================

另外我在Jdon发帖子的时候,老是要重新登陆,我不得不复制写下东西。可能一个原因是SESSION设置的失效时间太短,希望管理员解决下。

wgmao
2006-09-16 18:59

public class testDBQuery {
	private static Log log = LogFactory.getLog(testDBQuery.class);
public static void main(String[] args) {
	DBJdbcRunners query = null;
	try {	query.begintx();
		query.executeUpdate("insert into user (id,name) values(9001,'wgm')");
		  query.executeQuery("select id, name from user order by id",true);
	query.committx();
} catch (Exception e) {
		//System.out.print(rowSet.print());
		e.printStackTrace();
	}
}

}
<p>

以上在MYSQL数据库,INFORMIX数据库上都已经测试过,支持事物。

查询结果正确。

说明在DBJdbcRunners中DBUtils.getConnection();

DBUtils.closeResultSet(rs); DBUtils.closeStatement(statement); DBUtils.closeConnection(connection);

是写的一个通用方法DBUtils,管理连接,结果集和statement。

但我不知道这种调用方式会不会有其他的问题,所以请大家帮我参考下。

===========================

另外我在Jdon发帖子的时候,老是要重新登陆,我不得不复制写下东西。可能一个原因是SESSION设置的失效时间太短,希望管理员解决下。

wgmao
2006-09-16 19:33

0。我最关心的这个代码会不会出现连接无限增长,无法关闭的问题。

rs.last()在数据量很大的时候会不会出现性能问题。

这样的事务调用方式,累似hibernate的调用方式,虽然生效,但不知道会不会有其他问题和弊病。

1.为什么不用现成的开源产品如hibernate,ibats?

回答:并不是每个项目都适合用hibernate,不是说hibernate的能力适用不适用,而是开发人员的学习能力。毕竟hibernate中还是有很多东西需要学习,如果有些问题注意不好会出现性能问题,比如我前段时间碰见过延迟加载没有设置,导致列表页面超级慢。比如关联删除没有设置好,也会出问题。还有出了问题,人的第一个放应是框架的问题,不是自己问题。

而我写的JDBC只是简单的封装,学习门槛低,对付一些小的项目是很合适的。hibernate虽然开源,但真正能大体看懂源码得人很少。

2。这个代码不适合预处理查询和大字段(BLOB)的查询

是,这个需要在之后加入。

预处理查询 可以参考 Jdon彭老师 的jdbcUtil.setQueryParams(queryParams, ps);

blob 我只想写一个插入函数,和查询findbykey()的方法,不会在一般列表查询中也把blob,查询出来。

3.rs.getString都用这个函数似乎有偷工减料的嫌疑。

rs.getString 对一般的类型都可以取出,可能效率不是最好,但是问题应该不大。取出后在进行类型的转换。

Jdon的彭老师用的 rs.getObject

这个也是我有疑问的地方。

4。这个代码不支持分页查询

是,这个也需要在之后加入。

5。查询的结果没有返回,只是打印。

是,我回将结果放入的一个rowSet 种,rowSet中放入row.

6.不够优化,没有对各种数据库进行优化。

是,我看了hibernate的Dialect,可以搬过来。

最后我觉得这个东西还是有用的,适合比较简单,业务不复杂但要求进度的项目。

superbible
2006-09-18 10:22

你的这些方法的确会碰到一些麻烦。

1)使用者对其概念不完整的模糊认识导致的问题。

你的例子中,只需要开启事务和提交事务。一般来说都会对是否关闭了连接有疑问。且在你的提交事务之前,开启事务之候,如果发生异常,你的连接就没有关闭,你无法使用try{}catch{}finally{}.

2)executeQuery()有性能问题。

你在log.debug()中访问了ResultSet的元数据,一般来说元数据总是比较慢的。如果你想通过设置log的级别来消除影响,你需要将这些log写为

if(log.isDebugEnabled()){log.debug(...)}

你的isgetTotalNum参数看来也是用作debug用的,用法应改为上述方式。

2Go 1 2 下一页