• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

J2EE综合--浅析Java程序员的存储过程

发布: 2008-4-22 13:51 | 作者: 不详 | 来源: 不详 | 查看: 39次 | 进入软件测试论坛讨论

领测软件测试网

 

下面是调用该存储过程的Java方法,将结果输出到PrintWriter:
PrintWriter:

static void sendEarlyDeaths(PrintWriter out) 

    Connection con = null; 
    CallableStatement toesUp = null; 
    try 
    { 
        con = ConnectionPool.getConnection(); 

        // PostgreSQL needs a transaction to do this... 
        con.setAutoCommit(false); 

        // Setup the call. 
        CallableStatement toesUp 
            = connection.prepareCall("{ ? = call list_early_deaths () }"); 
        toesUp.registerOutParameter(1, Types.OTHER); 
        getResults.execute(); 

        ResultSet rs = (ResultSet) getResults.getObject(1); 
        while (rs.next()) 
        { 
            String name = rs.getString(1); 
            int age = rs.getInt(2); 
            out.println(name + " was " + age + " years old."); 
        } 
        rs.close(); 
    } 
    catch (SQLException e) 
    { 
        // We should protect these calls. 
        toesUp.close(); 
        con.close(); 
    } 


因为JDBC并不直接支持从存储过程中返回游标,我们使用Types.OTHER来指示存储过程的返回类型,然后调用getObject()方法并对返回值进行强制类型转换。
这个调用存储过程的Java方法是mapping的一个好例子。Mapping是对一个集上的操作进行抽象的方法。不是在这个过程上返回一个集,我们可以把操作传送进去执行。本例中,操作就是把ResultSet打印到一个输出流。这是一个值得举例的很常用的例子,下面是调用同一个存储过程的另外一个方法实现:

public class ProcessPoetDeaths 

    public abstract void sendDeath(String name, int age); 


static void mapEarlyDeaths(ProcessPoetDeaths mapper) 

    Connection con = null; 
    CallableStatement toesUp = null; 
    try 
    { 
        con = ConnectionPool.getConnection(); 
        con.setAutoCommit(false); 

        CallableStatement toesUp 
            = connection.prepareCall("{ ? = call list_early_deaths () }"); 
        toesUp.registerOutParameter(1, Types.OTHER); 
        getResults.execute(); 

        ResultSet rs = (ResultSet) getResults.getObject(1); 
        while (rs.next()) 
        { 
            String name = rs.getString(1); 
            int age = rs.getInt(2); 
            mapper.sendDeath(name, age); 
        } 
        rs.close(); 
    } 
    catch (SQLException e) 
    { 
        // We should protect these calls. 
        toesUp.close(); 
        con.close(); 
    } 


这允许在ResultSet数据上执行任意的处理,而不需要改变或者复制获取ResultSet的方法:

static void sendEarlyDeaths(final PrintWriter out) 

    ProcessPoetDeaths myMapper = new ProcessPoetDeaths() 
    { 
        public void sendDeath(String name, int age) 
        { 
            out.println(name + " was " + age + " years old."); 
        } 
    }; 
    mapEarlyDeaths(myMapper); 


这个方法使用ProcessPoetDeaths的一个匿名实例调用mapEarlyDeaths。该实例拥有sendDeath方法的一个实现,和我们上面的例子一样的方式把结果写入到输出流。当然,这个技巧并不是存储过程特有的,但是和存储过程中返回的ResultSet结合使用,是一个非常强大的工具。

结论

存储过程可以帮助你在代码中分离逻辑,这基本上总是有益的。这个分离的好处有:
• 快速创建应用,使用和应用一起改变和改善的数据库模式。 
• 数据库模式可以在以后改变而不影响Java对象,当我们完成应用后,可以重新设计更好的模式。
• 存储过程通过更好的SQL嵌入使得复杂的SQL更容易理解。
• 编写存储过程比在Java中编写嵌入的SQL拥有更好的工具--大部分编辑器都提供语法高亮!
• 存储过程可以在任何SQL命令行中测试,这使得调试更加容易。

并不是所有的数据库都支持存储过程,但是存在许多很棒的实现,包括免费/开源的和非免费的,所以移植并不是一个问题。Oracle、PostgreSQL和DB2都有类似的存储过程语言,并且有在线的社区很好地支持。
存储过程工具很多,有像TOAD或TORA这样的编辑器、调试器和IDE,提供了编写、维护PL/SQL或pl/pgsql的强大的环境。
存储过程确实增加了你的代码的开销,但是它们和大多数的应用服务器相比,开销小得多。如果你的代码复杂到需要使用DBMS,我建议整个采用存储过程的方式。

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

44/4<1234

关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网