Swing应用开发实战系列之一:自定义JdbcTemplate
笔者本人真正意义上接触编程开发是在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
Swing应用开发实战系列之一:自定义JdbcTemplate的更多相关文章
- Swing应用开发实战系列之五:后台日志信息前台监控器
作为一个程序设计人员,我们深知日志的重要性,对于日志的监控,我们通常不外乎采用以下两种方式:日志文件方式和后台打印方式,常规情况下,这两种日志监控方式完全可以满足我们对日志监控的需要.但是,当我们用S ...
- Swing应用开发实战系列之四:组件内容实时刷新问题
窗口组件动态刷新问题,在dotnet中根本不算什么问题,用几句代码很轻松就能搞定,但是在Swing中,实现动态刷新组件内容却是一件颇为吃力的事情.譬如针对我们经常用到的刷新JLable.JTextFi ...
- Swing应用开发实战系列之三:动态信息提示窗口
这里所说的“动态信息提示窗口”可不同于JOptionPane中的Message窗口和Confirm窗口,它们都是静态的模态的,更重要的是线程阻塞的,迫使你必须选择某个动作才能继续执行.我们接下来要分享 ...
- Swing应用开发实战系列之二:设计日期选择面板窗口
Swing本身没有提供什么华丽丽的日期时间选择控件,所以笔者就在网上搜了个第三方的jar包jdatepicker-1.3.2.jar,基于此设计了个很轻量的日期选择面板,很简单的.效果图如下所示: 代 ...
- WCF开发实战系列一:创建第一个WCF服务
WCF开发实战系列一:创建第一个WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在这个实战中我们将使用DataContract,ServiceContract ...
- WCF开发实战系列二:使用IIS发布WCF服务
WCF开发实战系列二:使用IIS发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇中,我们创建了一个简单的WCF服务,在测试的时候,我们使用VS200 ...
- WCF开发实战系列三:自运行WCF服务
WCF开发实战系列三:自运行WCF服务 (原创:灰灰虫的家 http://hi.baidu.com/grayworm)上一篇文章中我们建立了一个WCF服务站点,为WCF服务库运行提供WEB支持,我们把 ...
- WCF开发实战系列四:使用Windows服务发布WCF服务
WCF开发实战系列四:使用Windows服务发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇文章中我们通过编写的控制台程序或WinForm程序来为本 ...
- WCF开发实战系列五:创建WCF客户端程序
WCF开发实战系列五:创建WCF客户端程序 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在前面的三篇文章中我们分别介绍了WCF服务的三种载体:IIS.Self-Hos ...
随机推荐
- 想要愉快入住酒店?缺了它还真不行!(含PPT)
编者注:别想歪了!我们说的是“机器学习”~ 在携程技术中心推出的线上公开课程[携程技术微分享]上,来自携程酒店研发的BI经理潘鹏举,介绍了如何借助大数据和算法,通过机器学习去克服酒店服务行业挑战,给用 ...
- Sprint总结
# Sprint 1 总结 > Sprint 1 主要是界面设计 > 为了遵循Material design,实际操作中依然遇到许多困难 > 预计耗时两小时每天,但是因为网络问题工作 ...
- C#中国象棋+游戏大厅 服务器 + 客户端源码
来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设 ...
- 使用VS开发C语言
在嵌入开发板上做了一段时间的C语言开发后,今天突然心血来潮,想起大学时期在TurboC和TC3下写代码的情形.大一时宿舍里有台386(在当时是算比较先进的了),大一大二基本上都在玩DOS和WIN31. ...
- sencha/extjs 动态创建grid表格
//创建普通表格 id,父容器,标题,json数据字符串,列名(逗号分隔),json数据key即store的fields属性(逗号分隔) function createCommonTable(id, ...
- 基于FreeBSD 64位内核的kFreeBSD无法在Virtualbox下安装
ArchBSD同上 感谢大A(豆瓣)的投稿 :)
- 泛函编程(16)-泛函状态-Functional State
初接触泛函状态觉着很不习惯.主要是在使用State数据类型时很难理解其中的原理,特别是泛函状态变迁机制(state transition mechanism):怎么状态就起了变化,实在难以跟踪.我想这 ...
- Sigleton 单例模式 的简单应用
需求:一个简单的后台java程序,收集信息,并将信息发送到远端服务器. 实现:实现一个后台线程,实时处理发送过来的信息,并将信息发送到服务器. 技术要点: 1.单例模式 2.队列 并没有实现全部代码, ...
- c#多线程生产者消费者(手稿)
屋舍简陋,隔壁的娃娃哭了一晚,心中无恶意纯中性的想,有病就赶紧带孩子去看医生吧,能哭这么久估计孩子真的不舒服.
- 养只爬虫当宠物(Node.js爬虫爬取58同城租房信息)
先上一个源代码吧. https://github.com/answershuto/Rental 欢迎指导交流. 效果图 搭建Node.js环境及启动服务 安装node以及npm,用express模块启 ...