Swing应用开发实战系列之一:自定义JdbcTemplate

12/12/2015来源:Java教程人气:1386

 

笔者本人真正意义上接触编程开发是在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的小程序也行,不过那样的话人机交互性实在太差劲。就好像下面这个窗口:

dos_dialog

就以上弊病而言,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开发的基础功能包的一部分。我们主要对常用的关系数据库进行接口封装,包括OracleMySQL两种数据库。

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