zoukankan      html  css  js  c++  java
  • JDBC初级应用实例

    在了解JDBC基础知识以后,我们先来写一个数据库操作的类(Bean)以后我们会
    在这个类的基础上,随着介绍的深入不断提供优化的方案.
        要把一个数据库操作独立到一个类(Bean)中,至少要考虑以下几个方面:
        1.对于不同层次的应用,应该有不同的得到连结的方法,如果得到连结的方法要随
    着应用层次的不同而改变,我们就应该把他独立成一个专门的类中,而把在任何应用层次
    中都通用的处理方法封装到一个(类)Bean中.
        2.既然考虑到既作为javaBean使用又可以用为一个普通类调用,要考虑到javaBean
    的规范和普通类的灵活性.
        3.对于特定的数据库操作不应封装到共性的(类)Bean中,而应该成为它的扩展类.

        以上几点是充分考虑JAVA的面象对象的思想,经过深入的抽象形成的层次,下面我
    们就按这个思想来设计:
        一:定义一个用于连结的Bean,以后如果要在不同的应用中,如可以在J2EE中从
    DataSource中得到连结,或从普通的连结池中得到连结,以及直接从DriverManager中得到
    连结,只需修改本类中的得到连结的实现方法.
        package com.imnamg.axman.beans;
        import java.sql.*;
        import ..................
        public class ConnectionFactory{
            protected Connection conn;
            ConnectionFactory() throws SQLException 
            {    //构造方法中生成连结
                //无论是从DataSource还是直接从DriverManager中取得连结.
                //先初始化环境,然后取得连结,本例作为初级应用,从
                //DriverManager中取得连结,因为是封装类,所以要把异常抛
                //给调用它的程序处理而不要用try{}catch(){}块自选处理了.
                //因为要给业务方法的类继承,而又不能给调用都访问,所以
                //conn声明为protected
                conn =     DriverManager.getConnection(url,user,passwd);
            }
            
            /**
                在多线程编程中,很多时候有可能在多个线程体中得到同一连
                结的引用,但如果在一个线程中关闭了连结,则另一个得到相同
                引用的线程就无法操作了,所以我们应该加一个重新建立连结
                的辅助方法,有人问为什么既然有这个辅助方法不直接调用这个
                辅助而要在构造方法中生成连结?因为这样可以增加效率,如果
                在构造时不能生成连结则就不能生成这个对象了,没有必要在
                对象生成后再测试能不能生成连结.
            */
            public void makeConnection(){
                //此处的代码同构造方法,无论以后如果实现连结,都将构造方
                //法的代码复制到此处.
                conn =     DriverManager.getConnection(url,user,passwd);
            }
        }

        这个类就封装到这里,当然你可以在这儿增加业务方法,但如果要修改连结的实现,
    整个类都要重新编译,因为业务方法和应用层次无关,代码一经生成不易变动,所以独立封装.
    以下我们实现业务方法:

        package com.imnamg.axman.beans;
        import java.sql.*;
        import ..................
        public class DBOperater extends ConnectionFactory{
            //private Statement stmt;
            //private ResultSet rs;
            //为什么要注释成员变量stmt和rs,基础部分已经说过,如果声明为成员变量,
            //在关闭conn时可以显示地先关闭rs和stmt,别的没有任何好处,而显示关
            //闭只是说明你编程风格好,但综合考虑,我们要生成多个stmt或不是类型的
            //stmt就不能声明为成员方法,否则引用同一对象,所以我们要业务方法中生
            //成stmt对象.不仅可以同时处理多个结果集,还可以提高性能和灵活性.

            public ResultSet executeQuery(String sql) throws SQLException{
                if(conn==null || conn.isClosed())
                    makeConnection();
                Statement stmt = con.createStatement(
                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                                             ResultSet.CONCUR_READ_ONLY);
                //对于一般的查询操作,我们只要生成一个可流动的结果集就行了.
                //而对于在查询时要更新记录,我们用另一个业务方法来处理,这样,
                //这样可以在普通查询时节省回滚空间.
                ResultSet rs = stmt.executeQuery(sql);
                return rs;
            }
            

            public ResultSet executeUpdatabledQuery(String sql) throws SQLException{
                if (con == null || con.isClosed())
                    makeConnection();
                Statement stmt = con.createStatement(
                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                        ResultSet.CONCUR_UPDATABLED);
                //可更新的结果结要更大的回滚空间,普通查询时不要调用这个方法
                ResultSet rs = stmt.executeQuery(sql);
                return rs;
            }

            /**
                基于同上的原因,在执行更新操作是我们根本不要任何回滚空间,所以建立
                一个基本类型的stmt,实现如下
            */



            public int executeUpdate(String sql) throws SQLException{
                if (con == null || con.isClosed()) 
                    makeConnection();
                Statement stmt = con.createStatement();
                //这个stmt在执行更新操作时更加节省内存,永远记住,能节省的时候要节省
                //每一个字节的内存,虽然硬件设备可能会有很大的物理内存,但内存是给用
                //户用的而不是给程序员用的(!!!!!!!!!!!!!!!!!!)
                int s = stmt.executeUpdate(sql);
                return s;
            }

            //以上实现了常用功能,还有两个通用的功能也是\"共性\"的,我们一起在这个封装类
            //中实现:
            public PreparedStatement getPreparedStmt(String sql) throws SQLException{
                if (con == null || con.isClosed()) 
                    makeConnection();
                PreparedStatement ps = con.prepareStatement(sql);
                return ps;
            }
            public CallableStatement getCallableStmt(String sql) throws SQLException{
                if (con == null || con.isClosed()) 
                    makeConnection();
                PreparedStatement ps = con.prepareCall(sql);
                return ps;
            }

            //记住:对于封装类而言预编译语句和存储过程调用应该从连结中返PreparedStatement
            //和CallableStatement供调用者处理而不是返回它们的处理结果.也就是说封装类只封
            //装了它们的连结过程.最后再次声明,一定要有一个close()方法供调用者调用,而且告
            //诉调用者无论如果要调用这个方法:

            public void close() throws SQLException{
                if(conn != null && !conn.isClosed())
                    conn.close();
            }
            //这个方法最好放在ConnectionFactory中,这样可以直接调用来只测试连结.而不用再
            调用子类来关闭
        }

        OK,我们已经实现了数据库常用操作的封装,注意这些业务方法都是把异常抛给调用者而没有用
    try...catch来处理,你如果在这里处理了那么调用者则无法调试了.对于特定的数据库的特殊操作,不要封
    装到此类中,可以再从这个类继承,或直接从ConnectionFactory类继承,当然最好是从这个业务类中继承,
    这样不仅可以调用特殊方法也可以调用共性的业务方法,兴一个例子,我在应用Oracle时要把XML文件直接
    存到数据数和把数据直接读取为XML文件,那么这两个方法只对Oracle才用到,所以:

        package com.inmsg.axman.beans;

        import java.sql.*;
        import oracle.xml.sql.query.OracleXMLQuery;
        import oracle.xml.sql.dml.OracleXMLSave;
        
        public class OracleDBOperater extends DBOperater{
             public OracleXMLQuery getOXQuery(String sql,String table) throws Exception
                     {
                             OracleXMLQuery qry = new OracleXMLQuery(con,sql);
                             qry.setRowsetTag(table);
                             qry.setRowTag(\"RECORD\");
                             return qry;
                     }
                     public int insertXML(String path,String table) throws Exception
                     {
                             OracleXMLSave sav = new OracleXMLSave(con,table);
                             URL url = sav.createURL(path);
                             sav.setRowTag(\"RECORD\");
                             int x = sav.insertXML(url);
                             sav.close();
                             return x;
                     }
        }

  • 相关阅读:
    链接服务器创建
    线性RAM地址非线性映射转换充分应用RAM地址空间TFT液晶驱动
    FPGA跨时钟域同步,亚稳态等
    Go常见的坑
    VSCode+PicGo+Gitee实现高效markdown图床
    友链
    linux 命令行使用codeql
    Linux 多进程服务配置 systemd
    列表中重复元素的个数
    起不出来题目了呜呜
  • 原文地址:https://www.cnblogs.com/zhuor/p/270747.html
Copyright © 2011-2022 走看看