`
lettoo
  • 浏览: 35087 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
博客专栏
58ccff5b-5ca6-387a-9c99-a277f31a9e51
我和Java数据库操作的那...
浏览量:9466
社区版块
存档分类
最新评论

我和JAVA数据库操作的那些事儿(1)

阅读更多
摘要
我开始接触jdbc的时候,常常 碰到的问题:
1. Connection基本上每次都是创建新的,导致速度很慢
2. Connection, Statement, ResultSet用完都没有释放,导致资源泄露,内存溢出
3. 重复的代码很多,创建Statement,创建ResultSet,遍历ResultSet,把ResultSet查询出来的数据set到对象,等等等等
4. sql语句在代码里,修改了表结构就要更新sql语句,就要修改源代码,里面双引号、单引号看多了都晕了。
 

    不管你的程序员生涯是不是从做数据库应用开始的,反正我是的。

 

    刚刚使用java那时,除了会写个hello world以外,参加的面试都会问你,会不会java数据库操作?答曰:会!再问:请详细描述。答曰:JDBC。

 

    后来的工作中写代码,写的最多的就是JDBC的应用,创建connection,创建Statement,创建ResultSet,遍历......周而复始,好像深山中樵夫砍柴,一刀一个印,单调乏味,却乐此不彼。

 

 

    言归正传,本文就从自己使用JDBC讲起,对自己在java数据库操作方面做一个小结,温故知新,回忆往昔。

 

    接下来,考虑到例子的简易性,数据库就使用sqlite 。例子中所有的操作基于以下几个表:

写道
对于sqlite的操作,我推荐使用sqlite browser 。这个绿色的小工具很方便使用。
 
  • 部门表
  • 员工表
  • 技能表
  • 员工技能关系表

图1: 表结构定义

 

建表SQL如下

 

CREATE TABLE Department (id NUMERIC, name TEXT, description TEXT);

CREATE TABLE Employee (id NUMERIC, name TEXT, departmentid NUMERIC, description TEXT);

CREATE TABLE Skill (id NUMERIC, name TEXT);

CREATE TABLE EmpSkill (empid NUMERIC, skillid NUMERIC);

 

    其中,Department和employee是一对多的关系,employee和skill表是多对多关系。

 

    项目需要:

  • 部门表、员工表、技能表可以CRUD
  • 删除部门,员工表的对应的部门ID设置为空
  • 删除员工,员工技能关系表要对应删除
  • 删除技能,要检查这项技能有没有被员工使用,如果有,则不允许删除,要先把员工和技能对应关系删除后,再进行删除

 

    好吧,我承认,一开始我就是直接写代码开始做了,大概是这样子的:

package cn.lettoo.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class DepartmentDB {

	public void addDepartment(Connection conn, Department dept)
			throws SQLException {
		Statement stmt = conn.createStatement();
		String sql = "INSERT INTO DEPARTMENT(ID, NAME, DESCRIPTION) VALUES ("
				+ dept.getId() + ", \"" + dept.getName() + "\", \""
				+ dept.getDescription() + "\")";
		stmt.execute(sql);
	}
	
	public void deleteDepartment(Connection conn, Department dept)
			throws SQLException {
		Statement stmt = conn.createStatement();
		String sql = "DELETE FROM DEPARTMENT WHERE ID = " + dept.getId();
		stmt.execute(sql);
	}
	
	public void updateDepartment(Connection conn, Department dept) throws SQLException {
		Statement stmt = conn.createStatement();
		String sql = "UPDATE DEPARTMENT SET NAME = \"" + dept.getName() + "\", DESCRIPTION =\""
				+ dept.getDescription() + "\" WHERE ID = "+ dept.getId();
		stmt.execute(sql);
	}
	
	public List<Department> selectDepartment(Connection conn, String condition) throws SQLException {
		Statement stmt = conn.createStatement();
		String sql = "SELECT ID, NAME, DESCRIPTION FROM DEPARTMENT WHERE " + condition;
		ResultSet rs = stmt.executeQuery(sql);
		List<Department> deptList = new ArrayList<Department>();
		
		while(rs.next()) {			
			Department dept = new Department();
			dept.setId(rs.getInt("ID"));
			dept.setName(rs.getString("NAME"));
			dept.setDescription(rs.getString("DESCRIPTION"));
			deptList.add(dept);			
		}
		
		return deptList;
	}
}
 

测试类大概是这样:

package cn.lettoo.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

public class JdbcTest {

    /**
     * @param args
     * @throws ClassNotFoundException 
     * @throws SQLException 
     */
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String url = "jdbc:sqlite:test.db";
        Class.forName("org.sqlite.JDBC");
        Connection conn=DriverManager.getConnection(url);
        
        DepartmentDB deptDB = new DepartmentDB();
        Department dept1 = new Department();
        dept1.setId(1);
        dept1.setName("研发部");
        dept1.setDescription("研发部很不错!");
        deptDB.addDepartment(conn, dept1);
        
        Department dept2 = new Department();
        dept2.setId(2);
        dept2.setName("商务部");
        dept2.setDescription("商务部也很不错!");
        deptDB.addDepartment(conn, dept2);
        
        deptDB.deleteDepartment(conn, dept1);
        
        dept2.setName("新商务部");
        dept2.setDescription("新商务更好!");
        deptDB.updateDepartment(conn, dept2);
        
        String condition = "id=2";
        List<Department> deptList = deptDB.selectDepartment(conn, condition);
        for (Department dept : deptList) {
        	System.out.println(dept.getId() + dept.getName() + dept.getDescription());
        }
        
    }

}
 

    测试OK,功能正常,一切都好,回家睡觉了。过了没有几天,就发现很多很多的问题,主要有:

1. Connection基本上每次都是创建新的,导致速度很慢

2. Connection, Statement, ResultSet用完都没有释放,导致资源泄露,内存溢出

3. 重复的代码很多,创建Statement,创建ResultSet,遍历ResultSet,把ResultSet查询出来的数据set到对象,等等等等

4. sql语句在代码里,修改了表结构就要更新sql语句,就要修改源代码,里面双引号、单引号看多了都晕了。

5. 此处可以继续写上更多的问题......

 

    对于第一个问题,记得当时对连接池没有了解,就使用一个对象里持有一个连接,这个连接在用之前先检查是不是关闭的,如果不是,直接使用,如果是,创建再使用。写了N多检查维护这个连接的代码,包括什么创建这个连接不成功重试的功能等,汗一下~

 

    第二个问题,解决方案就是在一个util类写上close方法,如:

    public static void close(Statement stmt) {
    	if (stmt != null) {
    		try {
				stmt.close();
			} catch (SQLException e) {
				// Do nothing
			}
    	}
    }

    然后在使用的地方,通过try{}finally{}在finally里调用关闭之类。这一类的代码,目前在某些项目里仍然可见。

 

    第三个问题,当时解决无非就是用函数包装下重复的代码。此处略。

 

    第四个问题,解决方法是把所有的sql语句放到一个文本文件里,然后有一个configuration模块预先把文本文件读到内存,在代码里通过参数从configuration提供的接口里获取sql语句。sql语句采用传参的形式,比如这样:

SELECT * FROM DEPARTMENT WHERE ID = ?

    然后使用PreparedStatement.setString(1, xx)这样的方式。当然,这样的代码目前仍然大量使用ing...

 

    还有很多问题,当时,就是这样忙的不亦乐乎吧。

 

    今天就写到这里,后面的内容将会包括以下:

  1. 连接池的引用
  2. 批处理
  3. 事务的加入
  4. 使用apache dbutils来减少代码工作量
  • 大小: 38.5 KB
分享到:
评论

相关推荐

    我和JAVA数据库操作的那些事儿(2)

    在“我和JAVA数据库操作的那些事儿(2)”这篇博文中,作者分享了实际操作的经验和技巧,涵盖了数据库连接、SQL语句执行、结果集处理以及对象模型的构建。 首先,JDBC是Java平台的标准接口,它允许Java应用程序与...

    java程序员的那些事儿

    Java程序员在IT行业中占据着重要的地位,他们负责...总的来说,"java程序员的那些事儿"涉及了广泛的知识领域,从编程语言本身到与之相关的框架、工具和最佳实践。不断学习和适应新技术,是Java程序员保持竞争力的关键。

    Java编程那些事儿

    "Java编程那些事儿"无疑是对这个强大语言的深入探讨,旨在帮助开发人员提升技能,拓宽视野。这份资料可能是由一系列章节或主题组成的文档,比如基础语法、面向对象编程、异常处理、集合框架、多线程、IO流、网络编程...

    java那些事儿chm

    在这个压缩包中,包含的文件名为“java那些事儿.chm”。 Java,作为世界上最流行的编程语言之一,拥有广泛的应用领域,从企业级应用到移动开发,无处不在。这个CHM文档很可能是对Java基础知识、进阶概念、实战技巧...

    java那些事儿

    在这个压缩包中,我们有两份重要的文件:《Java编程那些事儿》的PDF文档以及两个与软件下载相关的文本和URL。 首先,让我们聚焦于核心的《Java编程那些事儿》PDF文档。这份资料可能包含了Java语言的基础概念,如...

    数据库连接池的实现java

    本篇文章将深入探讨如何使用Java实现一个数据库连接池,并分析其中的关键技术和步骤。 首先,我们需要理解数据库连接池的基本工作原理。数据库连接池在初始化时会创建一定数量的数据库连接,这些连接在空闲时会被池...

    java程序员上班那些事儿.pdf

    ### Java程序员上班那些事儿 #### 一、求职者与企业之间的认知差异 ##### 1.1 应聘者的自我定位问题 - **高大全式的技能列表**:许多求职者在简历上罗列了大量的技能,从传统编程语言如C++、VB,到现代技术如Java...

    关于Java和Python爬虫那些事儿.zip

    本压缩包文件“关于Java和Python爬虫那些事儿.zip”可能包含与使用Java和Python这两种语言进行网络爬虫相关的教程、代码示例或资源。尽管描述中只提到了“python”,但标题暗示了内容可能涵盖两种语言。 首先,让...

    Java程序员上班那点事儿txt版本

    - **掌握数据库操作**:需了解如何使用ADO对Access或SQL Server进行操作,并能编写SQL语句。 - **图形界面开发能力**:对于OpenGL或DirectX有一定的了解。 - **Java及Java平台知识**:熟悉J2EE和J2ME等技术框架。 - ...

    Java程序员上班那点事儿.txt

    - **操作系统管理**:具备Linux系统操作能力,同时对Solaris等其他操作系统有一定了解。 - **网络通信**:掌握网络基础知识,能够进行基本的网络调试与维护工作。 - **图形处理与多媒体**:了解OpenGL、DirectX等...

    Java程序员 上班那点事儿.pdf

    - **企业需求特点**:企业的招聘要求相对集中,如Java编程经验、MySQL数据库使用、Linux操作系统熟练等。这反映了企业在招聘时更加注重特定领域的深度而不是广度。 **求职者的自我认知与定位** - **明确职业定位**...

    Java程序员上班那点事儿

    12. **数据库操作**:了解SQL语言,熟悉常用的数据库如MySQL、Oracle,以及JDBC(Java数据库连接)API,能够进行数据的增删改查操作。 13. **网络编程**:理解TCP/IP协议,能够使用Socket进行网络通信,为构建...

    java程序员上班那点事儿

    根据给定的信息,“Java程序员上班那点事儿”这一标题与描述指向了关于Java程序员日常工作的一些常见情况、挑战或趣事等内容。尽管提供的具体内容部分没有直接给出相关知识点,但结合标题和描述,我们可以围绕Java...

    Java gui简单程序

    这是一个很好的起点,适合那些希望深入理解Java Swing库和数据库操作的初学者。 首先,让我们详细了解Java GUI。Java Swing库提供了大量的组件,用于构建用户界面,如按钮(JButton)、文本框(JTextField)、表格...

Global site tag (gtag.js) - Google Analytics