笔者本人真正意义上接触编程开发是在2004年,最早用的就是VB,然后是Delphi等,后来转到.Net,中间断断续续还用过PowerBuilder等,无一例外,所研发设计的项目或系统都是WinForm应用程序,基于C/S模式的窗口应用程序开发那个时候还是正道,而Web开发还没有现在这么红火,技术也没有现在这么多姿多彩。

后来,B/S技术日渐成熟起来,jquery、node.js、flex、spring、structs、hibernate等技术框架相继涌现出来,进行Web开发的门槛降了下来,开发效率提高了许多,C/S开发慢慢地受到了冷落。

不过,在闲暇之余,笔者本人仍会时常设计一些窗口小程序,或者用WinForm程序开发的方式测试Web开发中遇到的算法问题。尤其是有些时候,笔者仅仅是想测试一个类或者接口方法,如果在Web工程中编码测试的话,你就要配置一大堆东西,最后还要启动个IIS,或者Tomcat,或者JBoss什么的,破费周折;当然了,你也可以脱离Web工程环境,写个类似dos的小程序也行,不过那样的话人机交互性实在太差劲。就好像下面这个窗口:

就以上弊病而言,WinForm开发算是有得天独厚的优势了,考虑到跨平台的问题,再加上最近一年笔者都在持续地研究大数据方面的技术,基本上都是在用java进行技术研发和探索,所以很自然地,Swing就成了首选技术。

感觉Swing好像被冷落了好多年了,这也难怪,从当初的JCreator、JBuilder到NetBean,以及现在的Eclipse等,C/S开发好像都是非主流的,B/S才是主流,而且RAD特性也远远没有微软的VS好。好在有一点它是非常突出的,那就是跨平台,可以轻松部署在Linux系统中。

经过最近半年多试用Swing,笔者慢慢地积累了一些东西,断断续续的,偏偏面面的,各位不要太过于责怪,笔者会尽量将其归类整理,并给出相关的运行实例程序代码。

首先,在前面几个章节,我们会构建个Java基础功能包,介绍一些设计实现思路,封装设计一些接口方法,作为我们进行Swing应用开发的基础,有了这个基础功能包,我们接下来的Swing开发会有事半功倍的效果。

1、自定义JdbcTemplate

Hibernate中的JdbcTemplate组件功能已经很强悍了,不过现在我们要自定义设计个轻量级别的JdbcTemplate组件,作为我们Swing开发的基础功能包的一部分。我们主要对常用的关系数据库进行接口封装,包括Oracle和MySql两种数据库。

1.1 数据库类型枚举类

/**
* Description: 数据库类型。<br>
* Copyright: Copyright (c) 2015<br>
* Company: 河南电力科学研究院智能电网所<br>
* @author shangbingbing 2015-01-01编写
* @version 1.0
*/
public enum DBType {
ORACLE,
MYSQL
}

1.2 数据库JDBC操作类

/**
* Description: 关系数据库数据操作接口模板。<br>
* Copyright: Copyright (c) 2015<br>
* Company: 河南电力科学研究院智能电网所<br>
* @author shangbingbing 2015-01-01编写
* @version 1.0
*/
public class JdbcTemplate {
private DBType dataBaseType = DBType.ORACLE;
private String userName = "";
private String password = "";
private String driver = "";
private String connectionUrl = "";
/**
* 获取数据库用户名称
* @return
*/
public String getUserName() {
return this.userName;
}
/**
* 设置数据库用户名称
* @param userName
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* 获取数据库用户密码
* @return
*/
public String getPassword() {
return this.password;
}
/**
* 设置数据库用户密码
* @param password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取数据库驱动程序
* @return
*/
private String getDriver() {
if(this.dataBaseType == DBType.ORACLE) {
this.driver = "oracle.jdbc.driver.OracleDriver";
} else if (this.dataBaseType == DBType.MYSQL) {
this.driver = "com.mysql.jdbc.Driver";
}
return driver;
}
/**
* 获取数据库连接URL
* @return
*/
public String getConnectionUrl() {
return this.connectionUrl;
}
/**
* 设置数据库连接URL
* @param url
*/
public void setConnectionUrl(String url) {
this.connectionUrl = url;
}
/**
* 默认构造函数。
* @param dataBaseType
*/
public JdbcTemplate() { }
/**
* 构造函数,并确定数据库类型。
* @param dataBaseType
*/
public JdbcTemplate(DBType dataBaseType) {
this.dataBaseType = dataBaseType;
}
/**
* 数据库连接对象
*/
private Connection conn = null;
/**
* 获取数据库连接对象
* @return
*/
public Connection getConnection() {
try {
if(this.conn == null || this.conn.isClosed()) {
Class.forName(this.getDriver());
this.conn = DriverManager.getConnection(getConnectionUrl(),getUserName(),getPassword());
}
} catch (Exception e) {
e.printStackTrace();
}
return this.conn;
}
/**
* SQL语句对象
*/
private Statement stmt = null;
/**
* 执行增删改SQL语句
* @param strSql
* @return
*/
public boolean executeSql(String strSql) {
if(strSql == null || strSql.isEmpty()) {
return false;
}
try {
LogInfoUtil.printLog(strSql);
this.stmt = this.getConnection().createStatement();
this.stmt.execute(strSql);
//execute返回值出现问题,即使SQL执行成功也会返回false的。
return true;
} catch(Exception e) {
e.printStackTrace();
return false;
}
} /**
* 批量执行增删该SQL语句
* @param strSqlList
*/
public void executeSql(List<String> strSqlList) {
if(strSqlList == null || strSqlList.size() == 0) {
return;
}
try {
this.stmt = this.getConnection().createStatement();
//每500作为一个插入批量操作
int batchSize = 500;
int count = 0;
for(String strSql : strSqlList) {
LogInfoUtil.printLog(strSql);
this.stmt.addBatch(strSql);
if(++count % batchSize == 0) {
this.stmt.executeBatch();
}
}
//插入剩余的数据
this.stmt.executeBatch();
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* 获取SQL检索语句结果集中的列名称及类型信息。
* @param strSql
* @return
*/
public TreeMap<String,Integer> getColumnTypeList(String strSql) {
TreeMap<String,Integer> columnTypeList = new TreeMap<String,Integer>();
try {
LogInfoUtil.printLog(strSql);
this.stmt = this.getConnection().createStatement();
ResultSet rs = this.stmt.executeQuery(strSql);
//获取数据集的列信息
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i=1; i<=columnCount; i++) {
String columnName = rsmd.getColumnName(i);
columnTypeList.put(columnName,rsmd.getColumnType(i));
}
rs.close();
return columnTypeList;
} catch(Exception e) {
e.printStackTrace();
return columnTypeList;
}
}
/**
* 获取SQL检索语句结果集中的列名称及类型信息。
* @param strSql
* @return
*/
public TreeMap<String,String> getColumnTypeNameList(String strSql) {
TreeMap<String,String> columnTypeList = new TreeMap<String,String>();
try {
LogInfoUtil.printLog(strSql);
this.stmt = this.getConnection().createStatement();
ResultSet rs = this.stmt.executeQuery(strSql);
//获取数据集的列信息
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i=1; i<=columnCount; i++) {
String columnName = rsmd.getColumnName(i);
columnTypeList.put(columnName,rsmd.getColumnTypeName(i));
}
rs.close();
return columnTypeList;
} catch(Exception e) {
e.printStackTrace();
return columnTypeList;
}
}
/**
* 执行SQL查询语句,将结果以List<Properties>形式组装返回.
* @param strSql
* @return
*/
public List<Properties> executeQuery(String strSql) {
List<Properties> propertiesList = new ArrayList<Properties>();
if(strSql == null || strSql.isEmpty()) {
return propertiesList;
} try {
LogInfoUtil.printLog(strSql);
this.stmt = this.getConnection().createStatement();
ResultSet rs = this.stmt.executeQuery(strSql);
//获取数据集的列信息
ResultSetMetaData rsmd = rs.getMetaData();
HashMap<String,Integer> columnList = new HashMap<String,Integer>();
int columnCount = rsmd.getColumnCount();
for(int i=1; i<=columnCount; i++) {
String columnName = rsmd.getColumnName(i);
columnList.put(columnName,rsmd.getColumnType(i));
} while(rs.next()) {
Properties properties = new Properties();
for(String columnLabel : columnList.keySet()) {
int columnType = columnList.get(columnLabel);
Object columnValue = null; switch (columnType) {
case Types.VARCHAR :
columnValue = rs.getString(columnLabel);
break;
case Types.NUMERIC:
columnValue = rs.getBigDecimal(columnLabel);
break;
case Types.DATE:
columnValue = rs.getDate(columnLabel).toString() + " " + rs.getTime(columnLabel).toString();
break;
case Types.NVARCHAR:
columnValue = rs.getNString(columnLabel);
break;
case Types.DECIMAL:
columnValue = rs.getBigDecimal(columnLabel);
break;
case Types.FLOAT:
columnValue = rs.getFloat(columnLabel);
break;
case Types.DOUBLE:
columnValue = rs.getDouble(columnLabel);
break;
case Types.BOOLEAN:
columnValue = rs.getBoolean(columnLabel);
break;
case Types.INTEGER:
columnValue = rs.getInt(columnLabel);
break;
case Types.BIGINT:
columnValue = rs.getLong(columnLabel);
break;
case Types.TIME:
columnValue = rs.getTime(columnLabel);
break;
case Types.BLOB:
columnValue = rs.getBlob(columnLabel);
break;
case Types.CLOB:
columnValue = rs.getClob(columnLabel);
break;
default:
columnValue = rs.getObject(columnLabel);
break;
} if(columnValue == null) {
properties.put(columnLabel, "");
} else {
properties.put(columnLabel, columnValue);
}
}
propertiesList.add(properties);
}
rs.close();
return propertiesList;
} catch(Exception e) {
e.printStackTrace();
return propertiesList;
}
}
/**
* 获取指定表中的记录总数
* @param tableName 指定表名称
* @return 表中的记录总数
*/
public int getTableRecordTotalCount(String tableName) {
int totalCount = 0;
String strSql = "select count(rowid) as RECORD_COUNT from " + tableName;
try {
LogInfoUtil.printLog(strSql);
this.stmt = this.getConnection().createStatement();
ResultSet rs = this.stmt.executeQuery(strSql);
while(rs.next()) {
totalCount = rs.getInt("RECORD_COUNT");
}
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
return totalCount;
}/**
* 释放连接资源
*/
public void close() {
try {
if(this.stmt != null) {
this.stmt.close();
this.stmt = null;
}
if(this.conn != null) {
this.conn.close();
this.conn = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读取指定的JDBC Properties文件,初始化数据连接信息。
* @param jdbcPropertiesFile
*/
public void initJdbcTemplate(String jdbcPropertiesFile) {
HashMap<String,String> pps = PropertiesUtil.readProperties(jdbcPropertiesFile);
String url = pps.get("jdbc.url");
String userName = pps.get("jdbc.username");
String password = pps.get("jdbc.password");
this.connectionUrl = url;
this.userName = userName;
this.password = password;
}
}

我们仅仅设计了几个常用的接口方法,看官可以根据自己的实际需要进行丰富和完善,譬如可以增加读写Blob字段的功能等等。

1.3 应用开发实例

  • 操作Oracle数据库
JdbcTemplate jdbcTemplate = new JdbcTemplate();
或者
JdbcTemplate jdbcTemplate = new JdbcTemplate(DBType.ORACLE);
jdbcTemplate.setConnectionUrl(“jdbc:oracle:thin:@ ......”);
jdbcTemplate.setUserName(“admin”);
jdbcTemplate.setPassword(“admin”);
String strSql = "SELECT * FROM SYSTEM_USER";
List<Properties> list = jdbcTemplate.executeQuery(strSql);
  • 操作MySql数据库
JdbcTemplate jdbcTemplate = new JdbcTemplate(DBType.MYSQL);
jdbcTemplate.setConnectionUrl(“jdbc:mysql://10.231.45.34 ......”);
jdbcTemplate.setUserName(“admin”);
jdbcTemplate.setPassword(“admin”);
String strSql = "SELECT * FROM SYSTEM_USER";
List<Properties> list = jdbcTemplate.executeQuery(strSql);

【完】

作者:商兵兵

单位:河南省电力科学研究院智能电网所

QQ:52190634

主页:http://www.cnblogs.com/shangbingbing

空间:http://shangbingbing.qzone.qq.com

Swing应用开发实战系列之一:自定义JdbcTemplate的更多相关文章

  1. Swing应用开发实战系列之五:后台日志信息前台监控器

    作为一个程序设计人员,我们深知日志的重要性,对于日志的监控,我们通常不外乎采用以下两种方式:日志文件方式和后台打印方式,常规情况下,这两种日志监控方式完全可以满足我们对日志监控的需要.但是,当我们用S ...

  2. Swing应用开发实战系列之四:组件内容实时刷新问题

    窗口组件动态刷新问题,在dotnet中根本不算什么问题,用几句代码很轻松就能搞定,但是在Swing中,实现动态刷新组件内容却是一件颇为吃力的事情.譬如针对我们经常用到的刷新JLable.JTextFi ...

  3. Swing应用开发实战系列之三:动态信息提示窗口

    这里所说的“动态信息提示窗口”可不同于JOptionPane中的Message窗口和Confirm窗口,它们都是静态的模态的,更重要的是线程阻塞的,迫使你必须选择某个动作才能继续执行.我们接下来要分享 ...

  4. Swing应用开发实战系列之二:设计日期选择面板窗口

    Swing本身没有提供什么华丽丽的日期时间选择控件,所以笔者就在网上搜了个第三方的jar包jdatepicker-1.3.2.jar,基于此设计了个很轻量的日期选择面板,很简单的.效果图如下所示: 代 ...

  5. WCF开发实战系列一:创建第一个WCF服务

    WCF开发实战系列一:创建第一个WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在这个实战中我们将使用DataContract,ServiceContract ...

  6. WCF开发实战系列二:使用IIS发布WCF服务

    WCF开发实战系列二:使用IIS发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇中,我们创建了一个简单的WCF服务,在测试的时候,我们使用VS200 ...

  7. WCF开发实战系列三:自运行WCF服务

    WCF开发实战系列三:自运行WCF服务 (原创:灰灰虫的家 http://hi.baidu.com/grayworm)上一篇文章中我们建立了一个WCF服务站点,为WCF服务库运行提供WEB支持,我们把 ...

  8. WCF开发实战系列四:使用Windows服务发布WCF服务

    WCF开发实战系列四:使用Windows服务发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇文章中我们通过编写的控制台程序或WinForm程序来为本 ...

  9. WCF开发实战系列五:创建WCF客户端程序

    WCF开发实战系列五:创建WCF客户端程序 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在前面的三篇文章中我们分别介绍了WCF服务的三种载体:IIS.Self-Hos ...

随机推荐

  1. CSS中的rem

    为什么会使用rem呢?主要还是浏览器和设备的大小不一. 这样就涉及到页面布局的不统一啦,先说说pc中的多栏布局吧,多栏布局有三种基本的实现方式:固定宽度.流动.弹性,下面我们就分别说说这三种布局吧. ...

  2. [团队项目]sprint3 & 团队贡献分

    希望各组认真准备,拿出最好的阵容最好的状态,展示一学期的学习与工作成果. 各组注意完成sprint3的博客,写上团队贡献分. 将演示PPT(如果有)和代码上传到github. 截止日期:2016.6. ...

  3. HTML5使用ApplicationCache

    在html5中使用application cache可以把一些静态资源保存在客户端的浏览器上面.这样可以提高访问的速度,甚至是离线应用.关于application cache的优缺点:1.离线浏览 - ...

  4. C#递归题目代码

    一列数的规则如下: 1.1.2.3.5.8.13.21.34...... 求第30位数是多少, 用递归算法实现. 代码: public class MainClass { public static ...

  5. ExtJS4图片验证码的实现

    ExtJS4学习笔记(十)---ExtJS4图片验证码的实现 转自:http://blog.sina.com.cn/s/blog_8d4bbd890100xaxh.html     上多少篇文章,重要 ...

  6. 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

    [源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...

  7. Hibernate+maven+mysql

    最近在研究hibernate,想建立一个简单的Hibernate+maven+mysql工程,网上找了一大堆的示例,要么看不懂结构,要么就是缺少必要文件.总之都没有成功,结果无意在一个外文网上找了一个 ...

  8. 配置文件,环境配置和war报分离,方便生产更改

    在生产环境实现配置文件和war包 的分离,为方便在必要的时候进行一定的更改,可以避免修改包,但是需要重启 最初为这样的选择配置,单不知为何未生效,修改为配置2配置方法,但不灵活,待跟进.配置1: &l ...

  9. [js开源组件开发]js多选日期控件

    js多选日期控件 详情请见:http://www.lovewebgames.com/jsmodule/calendar.html 它的github地址:https://github.com/tianx ...

  10. jquery实现页面控件拖动效果js代码

    ;(function($) { var DragPanelId = "divContext"; var _idiffx = 0; var _idiffy = 0; var _Div ...