JDBC编程中遇到的一点小问题
2011-05-03 20:45
120 查看
众所周知,java语言中采用了JDBC技术,为大量的java程序员提供了方便的数据库访问机制,客户程序员无需关心项目或者产品采用那种数据库,也不必在意各种数据库之间的差异,JDBC提供了统一的API供客户程序员使用,这种技术大大简化了程序员的工作量,从而使得程序员能花更多的时间去关注处理业务,但是在实际的实用中,虽然JDBC的各方 面封装都已经很好,而且性能也不错(至少在比hibernate的性能要好很多),但是在一些小细节上,一不小心还是会犯错,笔者就曾经遇到过这样的问题,改了很久都没有发现问题所在,后来仔细一行一行的读代码后终于发现这个隐藏的很深的问题,详情如下:
/*******
*javaBean
*/
class Student{
String name;
int id;
public void setName(String name){
this.name=name;
}
public void setId(int id){
this.id=id;
}
public String getName(){
return name;
}
publlic int getId(){
return id;
}
public String toString(){
return "name:"+this.name+",id="+this.id;
}
}
/****
*query bean
*/
class Dao{
ResultSet rs=null;
/**
*...略...
*/
List<Student> list = new ArrayList<Student>();
Student st = new Studendt();
while(rs.hasNext()){
st.setId(rs.getInt("id"));
st.setName(rs.getString("name"));
list.add(st);
}
/***不知道读者有没有发现上述代码的问题**/
int size = list.size();
for(int i=0;i<size;i++){
Student st=list.get(i);
System.out.println(st);
}
/**数据库中有10条学生信息记录,但打印出来的十条语句却只是同一个学生的信息,
*直接打印list时发现list里添加的10个内存地址一样的student的对象,
*笔者在这上面花了很多时间最后把代码改为如下才正*确的取到了10条学生信息
*/
whie(rs.hasNext()){
Student st=new Student();
st.setId(rs.getInt("id"));
st.setName(rs.getString("name"));
list.add(st);
}
/**这样在遍历list之后就正确的取出了10个学生的信息
*究其原因是因为list是允许添加相同的对象的,它是对象
*添加的顺序来区别添加进去的对象,而此前的代码中由于
*只在while循环外声明了一个student对象,而在while里
*只是不断的改变了该对象的属性,实际上相当于把相同的
*student对象添加了10次,所以打印list时取到的是10个
*内存地址相同的student对象,把student的声明放在while
*里去就对了,但是这会出现一个性能问题那就是假如数据库
*里有10万条记录,那么我们的这次查询将导致new 10万
*个student对象,这或多或少会对我们的
*应用的性能会造成影响,因此更好的做法是:
*/
whie(rs.hasNext()){
Student st=new Student();
st.setId(rs.getInt("id"));
st.setName(rs.getString("name"));
list.add(st);
st=null;
}
/***因为我while里的student对象只是一个临时的作用,
*因此在每次把它添加到list后就显示的把它声明为null
*这样可以明确的告诉jvm该个对象已经作废,你在适当
*的时机里可以把它销毁了,而不必等到jvm的内存不够用时
*才去销毁这些无用的对象
*/
*/
}
/*******
*javaBean
*/
class Student{
String name;
int id;
public void setName(String name){
this.name=name;
}
public void setId(int id){
this.id=id;
}
public String getName(){
return name;
}
publlic int getId(){
return id;
}
public String toString(){
return "name:"+this.name+",id="+this.id;
}
}
/****
*query bean
*/
class Dao{
ResultSet rs=null;
/**
*...略...
*/
List<Student> list = new ArrayList<Student>();
Student st = new Studendt();
while(rs.hasNext()){
st.setId(rs.getInt("id"));
st.setName(rs.getString("name"));
list.add(st);
}
/***不知道读者有没有发现上述代码的问题**/
int size = list.size();
for(int i=0;i<size;i++){
Student st=list.get(i);
System.out.println(st);
}
/**数据库中有10条学生信息记录,但打印出来的十条语句却只是同一个学生的信息,
*直接打印list时发现list里添加的10个内存地址一样的student的对象,
*笔者在这上面花了很多时间最后把代码改为如下才正*确的取到了10条学生信息
*/
whie(rs.hasNext()){
Student st=new Student();
st.setId(rs.getInt("id"));
st.setName(rs.getString("name"));
list.add(st);
}
/**这样在遍历list之后就正确的取出了10个学生的信息
*究其原因是因为list是允许添加相同的对象的,它是对象
*添加的顺序来区别添加进去的对象,而此前的代码中由于
*只在while循环外声明了一个student对象,而在while里
*只是不断的改变了该对象的属性,实际上相当于把相同的
*student对象添加了10次,所以打印list时取到的是10个
*内存地址相同的student对象,把student的声明放在while
*里去就对了,但是这会出现一个性能问题那就是假如数据库
*里有10万条记录,那么我们的这次查询将导致new 10万
*个student对象,这或多或少会对我们的
*应用的性能会造成影响,因此更好的做法是:
*/
whie(rs.hasNext()){
Student st=new Student();
st.setId(rs.getInt("id"));
st.setName(rs.getString("name"));
list.add(st);
st=null;
}
/***因为我while里的student对象只是一个临时的作用,
*因此在每次把它添加到list后就显示的把它声明为null
*这样可以明确的告诉jvm该个对象已经作废,你在适当
*的时机里可以把它销毁了,而不必等到jvm的内存不够用时
*才去销毁这些无用的对象
*/
*/
}
相关文章推荐
- intelliJ IDEA for mac 的Mysql数据库编程的JDBC配置问题及初级程序遇到的问题
- 9*9乘法表中for循环中遇到的一点问题
- Linux 串口编程中遇到的问题
- StringBuffer和StringBuilder编程遇到的问题
- flex开发中遇到的一点小问题
- VC编程过程中遇到的问题
- 用MFC编程,在软件登录时与服务器同步数据时遇到的相关问题
- 看到一个伙计遇到的服务端编程遇到的问题 赶紧复制过来
- 初次linux下安装apache2.4.27遇到的一点问题和解决方法
- 学习《java多线程编程核心技术》遇到的一些问题
- 编程过程遇到的问题——与解决方法 2011年4月8日
- hadoop编程遇到的jvm问题为内存不够的解决办法
- Android 编程遇到的一点记录
- 企业上架发布-工作中遇到的一点问题
- 菜单绘制遇到的一点问题
- windows sdk编程遇到奇怪的问题
- 最近遇到的单片机编程小问题总结
- JDBC访问Oracle数据库时遇到Connection Reset问题的分析
- android编程中容易遇到的若干问题
- sqlite3 jdbc、c接口、python接口处理中文时遇到的问题及其解决方法