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;
        } finally {
            destroyConnection();
        }
    }

    /**
     * 批量执行增删该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();
        } finally {
            destroyConnection();
        }
    }
    /**
     * 获取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;
        } finally {
            destroyConnection();
        }
    }
    /**
     * 获取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;
        } finally {
            destroyConnection();
        }
    }
    /**
     * 执行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;
        } finally {
            destroyConnection();
        }
    }
    /**
     * 获取指定表中的记录总数
     * @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;
    }
    /**
     * 释放连接资源
     */
    private void destroyConnection() {
        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();
        }
    }
    /**
     * 释放连接资源
     */
    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

时间: 2024-10-17 08:48:06

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

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

作为一个程序设计人员,我们深知日志的重要性,对于日志的监控,我们通常不外乎采用以下两种方式:日志文件方式和后台打印方式,常规情况下,这两种日志监控方式完全可以满足我们对日志监控的需要.但是,当我们用Swing进行前台开发时,常常想能不能把后台服务运行日志实时地显示在前台窗口中,或者只是将某类我们比较关心的日志信息(譬如异常日志等)实时动态地显示在前台窗口中,这样方便我们及时监控和处理.这个设想我们称之为“后台日志信息前台监控器”. 设计这样一个“后台日志信息前台监控器”,有两个难点,第一个是,当

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

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

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

  这里所说的"动态信息提示窗口"可不同于JOptionPane中的Message窗口和Confirm窗口,它们都是静态的模态的,更重要的是线程阻塞的,迫使你必须选择某个动作才能继续执行.我们接下来要分享的这个动态信息提示窗口,重点就是信息是动态的且实时刷新显示的,我们设想这样一个应用场景,当我们要向数据库中写入10000条记录时,这肯定是一个颇为耗时的工作,很有必要在前台界面中实时地告知用户数据写入进度,并在写入完成后,自动隐藏提示窗口. 首先,设计信息提示窗体,调整到适当大小,并将

WCF 开发实战系列 (一)

也许有读者会说,为什么要谈 WCF?近期不是 Web API 比较热门?在这个手机.Devices 当道的现在,究竟有什么地方会需要使用到 WCF 呢? 的确,现在访间你能找到的课程,或者您可能参与某项目的实践 (网页应用程序.手机 APP 也好),你需要的通常也都是提供 Services 层,而这个 Services 层通常也就是 Web API.那么,难道 WCF 就无用武之地?其实也不是,看什么情况用什么技术,有一些地方是 Web API 无法做到的 前言 也许有读者会说,为什么要谈 WC

大数据开发实战系列之电信客服(1)

大数据实战开发系列,以实战为主,辅以一些基础知识,关于电信客服,在网上也有很多的资料,这里我自然会去参考网上的资料,程序的整体设计是在今天开始的,老夫尽量在本周末钱结束这个电信客服的程序编写.因为我也是一个学习者,所以在程序编写过程中难免会存在问题,有问题还请大家指出,有则改之,无则加勉.大家共同进步.本教程适合接触大数据开发不久或者还没接触大数据开发,或者小萌新.老鸟就多提意见吧,我改. 博客原文地址:大数据开发实战系列之电信客服(1) 项目背景 关于项目背景,我就照搬网上的了.通信运营商每时

跨平台开发实战系列篇-开篇

本系列文章将带着你从React Native入门到精通React Native开发,包括大型电商项目实战.大型新闻项目实战(一套代码运行在iOS平台和Android平台).持续更新中...... 一.前言 React Native于F8大会开源,在短短不到一年的时间里,它成为手机端必不可少的开发模式之一. 它充分利用了Facebook现有的业务轮子, 其核心设计理念:既拥有Native的用户体验.又保留React的开发效率, 也就是"learn once,write everywhere&quo

程序员入门必备的大数据开发实战系列丛书

想要入行大数据却不知从哪里开始?作为入行十年的码农为大家推荐一套"一站式实战型大数据应用开发学习指导"丛书,帮助读者踏上由开发入门到大数据实战的"互联网+大数据"开发之旅! 此套丛书以实用性.案例丰富见长.由国内知名的IT教育机构课工场创始人肖睿主编,人民邮电出版社出版.编撰此书时为满足企业对人才的技能需求,课工场大数据开发教研团队,通过对数百位BAT一线技术专家进行访谈.上千家企业人力资源情况进行调研.上万上企业招聘岗位进行需求分析,在此基础上,整合了大量案例说明

在线客服系统 开发实战系列(一:需求分析及技术方案初步选型)

在这个系列的文章里,我将尝试一步一步开发一套功能完备的在线客服系统,并最终将其开源在 Git 上,欢迎关注. 鉴于水平限制,难免有所疏漏,欢迎批评指正. 文章将分为几个部分 一.需求分析及技术方案初步选型 二.技术方案选型,验证 三.底层框架设计,开发 四.服务器设计开发 五.客户端设计开发 六.Web端设计开发 在这个系列的文章中,您将了解并学习到以下技术知识: MSMQ.YUI.WebSocket.WinForms 如果这些技术对您有用,还请您 推荐 一下本文章,谢谢! 首先我们大概看看什么

Python开发实战教程(8)-向网页提交获取数据

来这里找志同道合的小伙伴!↑↑↑ Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习Python这门语言. 本次课程是在掌握python基础之上进行的.基础没有学习的话建议先查看文章学习基础目录:Python开发实战系列教程-链接汇总,持续更新.进行学习. 最近几天感冒中,四肢乏力以及最近比较忙导致,更新较慢.还请见谅. 概述 很多时候我们需要给网