笔者本人真正意义上接触编程开发是在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