`
hgq0011
  • 浏览: 555375 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

请点评jdbc通用访问方法,这样可行吗?

    博客分类:
  • Jdbc
阅读更多
    最近在检查其他同事写的代码,看到一同学写的了一个通用JDBC模板(静态工厂模式),似乎没有什么问题,但看起来很是不美观,有点怪异的感觉。我想了很久是不是要在论坛中发布,我觉得这样的代码还是不够OO,为什么自己对应的域对象操作不直接用用对象封装来处理呢?而转用ResultSetMetaData来解析对应的字段的属性,而且每次要把相关的参数保存到MAP、list中,然后又要取出来解析。所以我觉得回影响性能。当然在测试过程中没有发现性能的问题。由于项目中其他同学也在用他这个模板,他们觉得很方便。但对应新人(刚毕业的同学)来说,经常在调试的时候发生了错误,都不知错误发生在那?导致又要其他同学帮忙,乱费太多时间,而且他们还是不知其所以然。请大家帮忙评点一下。谢谢!
//通过SQL反回对应的数据集
//比如:sql select nameSc,age from users
public List getResultDataList(String sql, Connection con) {
		List<Map> dataList = new ArrayList<Map>();
		Map<String, String> map = new HashMap<String, String>();//存放对应字段数据
		PreparedStatement ps = null;
		ResultSet ds = null;
		ResultSetMetaData rsd;
		try {
			ps = con.prepareStatement(sql);
			ds = ps.executeQuery();
			while (ds.next()) {
				map = new HashMap<String, String>();//通过键值对存放一条记录的数据
				rsd = ds.getMetaData();
				for (int i = 1; i <= rsd.getColumnCount(); i++) {
					switch (rsd.getColumnType(i)) {//通过判断数据类型转换数据
					case 12:// varchar(12)
						map.put(rsd.getColumnName(i), ds.getString(i));
						break;
					case 1:// char(1)
						map.put(rsd.getColumnName(i), ds.getString(i));
						break;
					case -7:// bit(-7)
						map.put(rsd.getColumnName(i), Boolean.toString(ds
								.getBoolean(i)));
						break;
					case 4:// int(4)
						map.put(rsd.getColumnName(i), Integer.toString(ds
								.getInt(i)));
						break;
					case 5:// smallint(5)
						map.put(rsd.getColumnName(i), Integer.toString(ds
								.getInt(i)));
						break;	
					case 93:// datetime(93)
						if (ds.getString(i) == null)
							map.put(rsd.getColumnName(i), "");
						else {
							if (ds.getString(i).length() >= 19) {
								map.put(rsd.getColumnName(i), ds.getString(i)
										.substring(0, 19));
							} else {
								map.put(rsd.getColumnName(i), ds.getString(i)
										.substring(0, 10));
							}
						}
						break;
					case 3:// decimal(3)
						map.put(rsd.getColumnName(i), Double.toString(ds
								.getDouble(i)));
						break;
					default:
						map.put(rsd.getColumnName(i), ds.getString(i));
						break;
					}
				}
				dataList.add( map);//存放所有行数据
			}
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
                        [color=red]connection是通过HibernateDaoSupport获取得到的,似乎能够自动回收(反回到连接池),是否真的不用关闭连接呢?[/color]
			/*
			 * try{ if(ds!=null){ds.close();ds=null;}
			 * if(ps!=null){ps.close();ps=null;}
			 * if(con!=null){con.close();con=null;} }catch(SQLException e){}
			 */
		}
		return dataList;
	}



//通过传递SQL,Sql的参数更新数据
//比如 sql insert into users(nameCs,age)valuse(?,?)
//params就是存放?代表的值
public int execUpdateByParams(String sql, Connection con, List params) {
		PreparedStatement ps = null;
		int message = 0;
		try {
			String paramsStr="";
			ps = con.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.size(); i++) {
					String p = params.get(i)==null?null:"" + params.get(i);//设置对应的参数
					ps.setString(i + 1, p);
				}
			}
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
			message = -1;
			throw new RuntimeException(e);
		} finally {
			try {
				if (ps != null) {
					[color=red]ps.close();[/color]//怎么在这他有把这个关闭了呢?这会有问题吧?
					ps = null;
				}
				// if(con!=null){con.close();con=null;}
			} catch (SQLException e) {
			}
		}

		return message;
	}
分享到:
评论
15 楼 taelons 2008-08-24  
把connenction作为public方法的参数,不是一种好风格,既然用hibernate/ibatis,就不需要暴露connection
用ResultSetMetaData来处理字段属性的思路是对的,但是map里应该放Field/StringField/IntField/MoneyField....等等
hibernate/ibatis之类的ORM东东,兜了好大一圈,才达到目的,性能是没什么问题,
灵活性也很好,但总有脱裤子放屁的感觉
14 楼 hellodesigner 2008-08-24  
建议看一下这个开源工具:
http://coolsql.dev.java.net
,里面的代码写得比较通用,可以研究一下。
13 楼 hgq0011 2008-08-24  
linhong_1001 写道

没看出来哪里用了hibernate,难道你是用hibernate管理connection,不会吧,My God!,你要连接池就专门找个连接池用啊,不用这样糟蹋hibernate吧


当然不是了。不熟悉hibernate的同学就用JDBC了,熟悉的就直接用HIBERNATE了,当然很复杂的SQL我们还是用JDBC来的爽。
12 楼 xzj127 2008-08-24  
这个视乎和 Ibatis 的那个方法差不多啊。。
11 楼 movingboy 2008-08-24  
......
10 楼 linhong_1001 2008-08-24  
hgq0011 写道
to codeutil
非常感谢你的建议。
其实我们用了HIBERNATE,但项目比较大,时间比较赶,而且其他同学学习的不够好(我也差不多),我才决定不会用hibernate的就用jdbc,任其他们天马行空,可谓写的奇特。性能问题很快就冒出来了。

“finally里的一个try进行三个关闭,存在严重的隐患。”我们用HibernateDaoSupport管理连接的,我们都不用手动关闭了吧?,那些都注释了。



没看出来哪里用了hibernate,难道你是用hibernate管理connection,不会吧,My God!,你要连接池就专门找个连接池用啊,不用这样糟蹋hibernate吧
9 楼 hgq0011 2008-08-23  
to codeutil
非常感谢你的建议。
其实我们用了HIBERNATE,但项目比较大,时间比较赶,而且其他同学学习的不够好(我也差不多),我才决定不会用hibernate的就用jdbc,任其他们天马行空,可谓写的奇特。性能问题很快就冒出来了。

“finally里的一个try进行三个关闭,存在严重的隐患。”我们用HibernateDaoSupport管理连接的,我们都不用手动关闭了吧?,那些都注释了。
8 楼 codeutil 2008-08-23  
getResultDataList 这个方法封装思路还是可取的,足够解决很大一部分的应用场景(不要期望有一个牛x的方法就可以搞定所有应用场景)。但是代码实现却比较糟糕。

首先如果返回是String类型的字段值,是根本不需要判断字段的类型,所以代码里那些case是没必要,
其次,既然用到了case,所有了、的类型值,在SqlType里已经定义为常量,这里不应该再写成 case 1,2,3,4这样的方式。
还有最后的finally里的一个try进行三个关闭,存在严重的隐患。

总之,建议如楼上所说,这些代码封装其实都有现成的。Apache common DBUtils已经封装得很好了。

7 楼 hgq0011 2008-08-23  
javaXX 写道
你传入的SQL语句 我建议不如用 Ognl,参数再加个POJO类代表一张表,和他的类型,直接将查到的数据放进去,这样是不是比较像ORM了!!

其实,同事的思想是用MAP来封装数据。
6 楼 hgq0011 2008-08-23  
HRoger 写道
没有什么可不可行,能解决问题就行,当然看起来的确不那么自然美观

要多次的转换,应该对性能会有影响的
5 楼 hgq0011 2008-08-23  
stworthy 写道
使用这个
Map<String, String> map = new HashMap<String, String>();//存放对应字段数据
当然是不通用
换成
Map<String, Object> map = new HashMap<String, Object>()
还好一些


恩,确实会好点。那个SQL一般都处理了。查询出来的数据最终只是显示在页面上,问题不大。
4 楼 hgq0011 2008-08-23  
kunanfo 写道
以前我在公司培训的时候,也做过类似的程序,初看起来,很似好用。但是其实有一个很典型的问题,如果数据库有一个BLOB数据类型的怎么办?如果使用了不同的数据库,存在了另外的数据类型怎么办?

当时想了想,姑且不管什么OO,单就扩展性方面,就比较差。
这个问题提出来了,正好也关注下

数据类型和移值性和扩展性确实不好。
移值性就不说了,因为我们很长一段时间都会定位在SQL SERVER上。
BLOB这个也不会了,因为有对立的文件服务器。
3 楼 HRoger 2008-08-22  
没有什么可不可行,能解决问题就行,当然看起来的确不那么自然美观
2 楼 stworthy 2008-08-22  
使用这个
Map<String, String> map = new HashMap<String, String>();//存放对应字段数据
当然是不通用
换成
Map<String, Object> map = new HashMap<String, Object>()
还好一些

1 楼 kunanfo 2008-08-22  
以前我在公司培训的时候,也做过类似的程序,初看起来,很似好用。但是其实有一个很典型的问题,如果数据库有一个BLOB数据类型的怎么办?如果使用了不同的数据库,存在了另外的数据类型怎么办?

当时想了想,姑且不管什么OO,单就扩展性方面,就比较差。
这个问题提出来了,正好也关注下

相关推荐

    JDBC通用增删改查方法

    本资源主要围绕"JDBC通用增删改查方法"展开,旨在提供一套简单、易用且具有广泛适用性的数据库操作方案。 首先,我们来了解一下JDBC的基本工作流程: 1. 加载驱动:使用`Class.forName()`方法加载数据库驱动,这...

    jdbc通用类

    本篇文章将详细探讨`jdbc通用类`的相关知识点,包括两种连接数据库的方法——基于连接池和属性文件,以及通用方法的设计思路。 首先,我们来看连接数据库的方法: 1. **基于连接池的数据库连接**:连接池是一种...

    jdbc通用数据库连接

    总结来说,"jdbc通用数据库连接"是指通过Java的JDBC API,封装了数据库操作的类或方法,使得在不同项目中可以方便快捷地进行数据库交互。这种封装涵盖了数据库连接的全过程,包括连接建立、SQL执行、结果处理以及...

    JDBC通用封装类

    本资源是对JDBC的封装,方便在项目中使用,其中BaseDao.java是对JDBC操作的封装,使用时让自己的Dao类继承即可,然后调用其中的executeQuery和executeOthe分别执行DQL和DML操作。dbinfo.properties属性文件存储基本...

    自定义jdbc通用类

    在Java编程领域,自定义JDBC(Java Database Connectivity)通用类是提高数据库操作效率和代码复用性的重要手段。通过创建这样一个类,开发者可以封装常见的数据库连接、查询、执行SQL语句等操作,使得数据库访问...

    JDBC通用DAO CRUD(不是Hibernate)

    自己写的一个JDBC通用DAO 有几点需要注意: 1.数据库命明目前只支持没下血杠命名(_) 2.表ID字段名取名有2种方式 (1)ID (2)TableName + ID 例如:user表 则取名为 id 或者 userid 因为没有用xml来映射表结构确定哪一个...

    神州通用数据库JDBC驱动和手册

    本文将深入探讨神通通用数据库的JDBC驱动及其使用方法,同时也会对提供的手册进行解读。 首先,让我们了解JDBC驱动的基本概念。JDBC驱动是Java应用程序连接到数据库的桥梁,它实现了Java API与数据库特定的通信协议...

    JDBC数据库访问技术

    JDBC数据库访问技术

    jdbc访问数据库\jdbc方式直接访问数据库环境的配置

    本文档旨在详细介绍如何通过JDBC方式直接访问数据库环境的配置方法。 #### 二、准备工作 为了确保能够顺利地使用JDBC访问数据库,需要进行以下准备工作: 1. **安装SQL Server 2000并打上sp3补丁**:确保SQL ...

    JDBC访问数据库步骤

    JDBC 访问数据库步骤 JDBC(Java Database Connectivity)是 Java 语言中用来访问数据库的 API,提供了一种标准的方式来连接和操作数据库。下面是 JDBC 访问数据库的步骤: 步骤 1:加载对应数据库驱动 在使用 ...

    JDBC数据访问接口

    JDBC(Java Database Connectivity)是Java编程语言中用于访问数据库的API,它是Java平台的标准,允许Java应用程序与各种数据库进行交互。JDBC提供了一组接口和类,使得开发者能够编写与数据库交互的代码,而无需...

    利用JSP实现基于JDBC_ODBC桥的Web数据库的访问

    本文详细介绍了JSP(Java Server Pages)技术以及JDBC-ODBC桥接技术,并结合Java Bean和JDBC(Java Database Connectivity)技术,展示了如何通过Web浏览器实现对SQL Server 2000数据库的访问。文章首先介绍了JSP的...

    达梦6jdbc通用驱动

    这是十分十分好用的达梦6jdbc通用驱动,欢迎大家下载啊

    通用的jdbc增删改查

    通用的jdbc增删改查,仅仅只是两个通用的方法,利用反射和泛型

    JDBC公共操作方法代码

    这篇名为“JDBC公共操作方法代码”的博客文章可能详细介绍了如何使用JDBC进行常见的数据库操作。下面我们将深入探讨JDBC的关键知识点。 首先,JDBC连接数据库的步骤通常包括以下几个部分: 1. 导入JDBC驱动:在...

    数据库概论实验范文实验八:通过JDBC方式访问数据库

    实验八的主题是“通过JDBC方式访问数据库”,这是数据库概论课程中的一项重要实践内容。JDBC(Java Database Connectivity)是Java语言中用于与各种数据库交互的一种标准接口,由Sun Microsystems开发并定义,现已...

    jdbc通用连接操作类

    在Java编程领域,JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。"jdbc通用连接操作类"是开发者为了简化数据库操作,...

    android通过JDBC直接访问Mysql数据库

    ### Android通过JDBC直接访问MySQL数据库 #### 一、引言 随着移动应用开发的不断发展,Android应用程序常常需要与后端数据库进行交互以提供丰富的功能和服务。传统的Android应用与数据库的交互方式通常采用RESTful ...

    优化JDBC方法功略

    标题“优化JDBC方法攻略”和描述中提到的是关于JDBC(Java Database Connectivity)数据库操作的性能优化,适合初学者和教学使用。本文将详细介绍三个主要的JDBC性能优化技巧,并提供了一些通用的准则,以帮助开发者...

Global site tag (gtag.js) - Google Analytics