代码的二次重构(开篇:JDBC连接数据库)
Java中使用JDBC连接数据库时,若是使用初级的代码,代码复用率非常低,连接过程简单来说分为以下几个步骤:
加载驱动包 准备好URL链接获取数据库连接(driver和url根据不同的数据库的不同而不同) 准备sql语句,对数据库进行增删改查四个基础操作,获取数据并处理 关闭与数据库的连接
(与此同时整个过程还要注意进行异常处理)
以上详细步骤可参考博客:http://www.cnblogs.com/erbing/p/5805727.html
加载JDBC驱动程序 → 建立数据库连接Connection → 创建执行SQL的语句Statement → 处理执行结果ResultSet → 释放资源
那么针对以上步骤,在大型项目开发中是无法采纳的,原因有:(1)代码的重用程度低,这种编码方式将造成大量的代码冗余,增加程序员负担(2)整个过程采用硬编码,当需要修改系统配置如:更换数据库时,需要重新编码及发布等等;那么为了避免这些缺点,让我们在开发的过程中将主要的精力都放在针对处理SQL语句及其关键参数上,我们需要对以上代码进行二次重构,做出我们自己的接口;
简单分析,使用JDBC的目的是为了在java代码中使用sql语句对数据库进行增删改查(也就是:查询及修改两个操作,我们将增删改三个操作都视为修改操作),那么我们在开发的过程中,若是只要使用查询和修改的两个接口对数据库进行操作,将大大减轻我们的工作量,我们将这两个接口分别命名为:findBySQL和exeuteUpdate,详细实现代码请见下:
package com.neu.dao; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import com.neu.util.DBManager; public class BaseDao {
private Connection conn;
private PreparedStatement stmt;
private ResultSet rst; public int exeuteUpdate(String sql,Object...args){
//Object...args是java中的可变长参数列表的语法,可以按照规则向其传输sql语句需要的所有参数
int count=0;
try {
conn=DBManager.getConnection();
stmt=conn.prepareStatement(sql);
if(args!=null){
for(int i=0;i<args.length;i++){
stmt.setObject(i+1, args[i]);
}
}
count=stmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("执行sql语句有误",e);
}finally{
DBManager.close(conn, stmt, rst);
}
return count;
} //不需要提供列名,只需要sql语句和参数即可
public List<HashMap<String, String>> findBySQL(String sql,
Object...params){
// <>表示 泛型
// 保存所有行中的数据
List<HashMap<String, String>> list=
new ArrayList<HashMap<String,String>>();
// 保存每一行中的每一列数据
HashMap<String, String> item=null;
try {
conn=DBManager.getConnection();
stmt=conn.prepareStatement(sql);
if(params!=null){
for(int i=0;i<params.length;i++){
stmt.setObject(i+1, params[i]);
}
}
rst=stmt.executeQuery();
//可以获取查询的列数目
ResultSetMetaData meta=rst.getMetaData();
int count=meta.getColumnCount();
String[] colNames=new String[count];
for(int i=0;i<count;i++){
colNames[i]=meta.getColumnName(i+1);
}
//System.out.println(Arrays.toString(colNames));
while(rst.next()){
item=new HashMap<String, String>();
for(int i=0;i<count;i++){
String value=rst.getString(colNames[i]);
item.put(colNames[i].toLowerCase(), value);
}
list.add(item);
}
} catch (SQLException e) {
throw new RuntimeException("执行查询异常", e);
} finally{
DBManager.close(conn, stmt, rst);
}
return list;
}
}
BaseDao.java
package com.neu.util; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class DBManager {
private static final String driver;
private static final String url;
private static final String user;
private static final String pwd;
/*
* 静态块,自在类加载的时候执行一次
*/
static{
driver=ReadProperties.getInstance()
.getProperty("driver");
url=ReadProperties.getInstance()
.getProperty("url");
user=ReadProperties.getInstance()
.getProperty("user");
pwd=ReadProperties.getInstance()
.getProperty("pwd");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 负责连接数据库
* @return 连接的对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
Connection conn=DriverManager
.getConnection(url, user, pwd); return conn;
}
/**
* 关闭数据库资源,有小到大,由里到外
* @param conn
* @param stmt
* @param rst
*/
public static void close(
Connection conn,
Statement stmt,
ResultSet rst){
if(rst!=null){
try {
rst.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rst= null;
}
}
if(stmt !=null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
stmt=null;
}
}
if(conn !=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn=null;
}
}
}
}
DBManager.java
package com.neu.util; import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//用户读取db.properties文件中的内容
//单例模式,懒汉模式
public class ReadProperties extends Properties {
private static ReadProperties read;
// 加载文件
private ReadProperties(){
// 把文件转换为输入流
InputStream is=ReadProperties
.class.getResourceAsStream("/db.properties");
// 加载到内存
try {
load(is);
} catch (IOException e) { }
} public static ReadProperties getInstance(){
if(read==null){
read=new ReadProperties();
}
return read;
} }
ReadProperties.java
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@10.10.2.1:1521:neu
user=scott
pwd=tiger
db.properties
其中在eclipse中的目录结构如下图所示:

这其中箭头所指的即为几个比较关键的文件:
ojdbc14.jar是连接数据库的驱动jar包;db.properties为配置文件,其中包括连接数据库的驱动包名,连接数据库的url链接及对应数据库的数据库用户名和密码,以后如果要更换数据库的时候只需要更换驱动jar包及配置文件中对应的配置即可;
而ReadProperties.java的主要目的是将配置文件中的信息读取到创建的对象中,这样即可获得配置文件中配置的字符串变量,并将其传送给DBManager.java,
DBManager.java进行获得数据库连接对象及关闭数据库等相对简单且较为冗余的操作;
最后是BaseDao.java文件,它是未来我们操作的核心,其中的主要两个部分是findBySQL和exeuteUpdate,分别进行查找和修改两个操作;
在BaseDao.java文件中,简单一句conn=DBManager.getConnection();即可获取到数据库连接对象,public int exeuteUpdate(String sql,Object...args);可以将对应的需要操作的sql语句及其中间的问号?需要替代的参数传入,返回值为int,根据返回值来判断整个修改过程是否成功(修改操作的返回值都是返回0或者大于0的数,代表影响行,异常除外)。而
public List<HashMap<String, String>> findBySQL(String sql,Object...params)则是直接返回一个类似表的键值对结构,将查询得到的整张表作为结果返回,非常方便。以下也展示两个对其进行使用的测试代码:
package test;
import com.neu.dao.BaseDao;
public class TestBaseDao {
public static void main(String[] args) {
// TODO Auto-generated method stub
String id="2";
String name="";
String sql="delete from user_info "
+ "where user_id=? and user_name=?";
BaseDao dao=new BaseDao();
int i=dao.exeuteUpdate(sql,id,name);
System.out.println(i);
}
}
在这里我们根据返回的i的值来判断修改操作是否成功,修改可以进行增删改三个操作;
之后我们将上边提到的三个java文件打包成jar包并发布,以后我们就可以在开发中直接使用自己的两个接口即可:
选中我们的项目文件夹,右键导出,java文件夹下JAR file文件,

选中我们需要的java文件,同时也可以加上自己的源代码,方便以后的学习使用;不附带源代码可以更加安全的发布,自己拥有自己代码的版权;

这是个属于自己的独一无二的jar包,将它导入项目中后可以完全像我们自己在eclipse中写的类一样调用即可;

代码的二次重构(开篇:JDBC连接数据库)的更多相关文章
- 使用配置文件来配置JDBC连接数据库
1.管理数据库连接的Class 代码如下: package jdbcTest;import java.sql.Connection;import java.sql.DriverManager;impo ...
- JDBC连接数据库(PreparedStatement)
PreparedStatement是在数据库端防止SQL注入漏洞的SQL方法这里演示了一些基本使用方法同样使用Oracle数据库,之前已经手动建立了一张t_account表数据库代码参见上一篇< ...
- 转 JDBC连接数据库(二)——连接池
https://www.cnblogs.com/xiaotiaosi/p/6398371.html 数据库保持长连接,不过一直都是idle,除非有用户激活连接,这样后果是无法删除用户,但是不影响数据库 ...
- java开发中JDBC连接数据库代码和步骤
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...
- 【转】Java开发中JDBC连接数据库代码和步骤总结
(转自:http://www.cnblogs.com/hongten/archive/2011/03/29/1998311.html) JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含7个 ...
- Java中JDBC连接数据库代码和步骤详解总结
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Jav ...
- 完整java开发中JDBC连接数据库代码和步骤
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...
- 完整java开发中JDBC连接数据库代码和步骤 JDBC连接数据库
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...
- (转)完整java开发中JDBC连接数据库代码和步骤
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...
随机推荐
- c#控件的动画显示效果
1. 缘由: 项目中任务完成有个提示,需要以动画效果展示,其效果当如下图: 此为老项目为Delphi所写,改用c#实现,此效果做些设计.本也不难,小技而已,但为易于扩展,写了个静态类实现. 2. A ...
- win7安装sqlserver2008
双击启动程序,点击安装
- 细说SVN集中式版本控制器
svn全称Subversion,实现多人开发同一个项目时,对源代码进行管理的工具.在公司里边,一个项目是由多人同时在开发,大家在本地自己电脑开发php代码,完毕后就commit上传给服务器运行. 如 ...
- 线特征---Edge Drawing(七)
http://ceng.anadolu.edu.tr/cv/edgedrawing/ References C. Topal, C. Akinlar, Edge Drawing: A Combined ...
- VIO回顾:从滤波和优化的视角
https://mp.weixin.qq.com/s/zpZERtWPKljWNAiASBLJxA 根据以上网页自己做的总结: 在机器人社区中,定位与构图问题属于状态估计问题.主流使用的工具可以对给定 ...
- vue.js路由vue-router
学习网址:https://segmentfault.com/blog/vueroad 转载至:https://segmentfault.com/a/1190000009350679#articleHe ...
- python 3.6.5 hashlib 和 hmac 模块
import hashlib m=hashlib.md5()# m=hashlib.sha256() m.update('hello'.encode('utf8'))print(m.hexdigest ...
- python3.6.5 路径处理与规范化
在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠. >>> os.path.normcase('c: ...
- Android——Activity练习
manifests里的AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> < ...
- python爬虫_简单使用百度OCR解析验证码
百度技术文档 首先要注册百度云账号: 在首页,找到图像识别,创建应用,选择相应的功能,创建 安装接口模块: pip install baidu-aip 简单识别一: 简单图形验证码: 图片: from ...