仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 879|回复: 8
打印 上一主题 下一主题

[学习教程] MSSQL教程之让JDBC查询日记变得复杂

[复制链接]
不帅 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:32:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
因此我们的保存数据方法就是:在删除的动作开始之前,把表数据备份起来,然后留一个空表,在空表上执行“删除”操作。
 JDBCjava.sql.PreparedStatement接口的复杂扩大可使查询日记更少出错,同时收拾您的代码。在本文中,IBM电子商务参谋JensWyke向您先容怎样使用基础的封装手艺(“经由过程封装来完成扩大”也称为Decorator计划形式)来取得最中意的了局。

  在年夜多半情形下,JDBCPreparedStatements使实行数据库查询更烦琐并能够明显提拔您全体使用程序的功能。当谈到日记查询语句时PreparedStatement接口就显得有些不敷了。PreparedStatement的上风在于其可变性,可是一个好的日记条目必需准确形貌怎样将SQL发送到数据库,它将亲切存眷用实践的参数值来交换一切参数占位符。固然有多种办法能够办理这一困难,但没有任何一种易于年夜范围实行而且年夜部分将侵扰您的程序代码。

 在本文中,您将懂得到怎样扩大JDBCPreparedStatement接口来举行查询日记。LoggableStatement类完成PreparedStatement接口,但增加用于取得查询字符串的办法,利用一种合用于纪录的格局。利用LoggableStatement类能够削减日记代码中产生毛病的概率,天生复杂且易于办理的代码。

  注重:本文假定您有丰厚的JDBC和PreparedStatement类履历。

  典范日记办理计划  

  表1先容了数据库查询时一般是怎样利用PreparedStatement(固然疏忽了初始化和毛病处置)。在本文中,我们将利用SQLquerySELECT做为例子,但会商利用别的范例的SQL语句,如DELETE、UPDATE和INSERT。

  表1:一个典范的SQL数据库查询


Stringsql="selectfoo,barfromfoobarwherefoo<?andbar=?";StringfooValue=newLong(99);StringbarValue="christmas";Connectionconn=dataSource.getConnection();PreparedStatementpstmt=conn.prepareStatement(sql);pstmt.setLong(1,fooValue);pstmt.setString(2,barValue);ResultSetrs=pstmt.executeQuery();//parseresult...


  表1中一个好的查询日记条目看起来应与上面有几分相似:


Executingquery:selectfoo,barfromfoobarwherefoo<99andbar=christmas


  上面是查询的日记代码的一个例子。注重:表1中的问号已被每一个参数的值交换。


System.out.println("Executingquery:  selectfoo,barfromfoobarwherefoo<"+fooValue+"andbar=+barValue+"")


  一种更好的办法是创立办法,我们称之为replaceFirstQuestionMark,它读取查询字符串并用参数值交换问号,如表2所示。这类办法的利用无需创立复制的字符串来形貌SQL语句。

  表2:利用replaceFirstQuestionMark来举行字符串交换


//listing1goesheresql=replaceFirstQuestionMark(sql,fooValue);sql=replaceFirstQuestionMark(sql,barValue);System.out.println("Executingquery:"+sql);


  固然这些办理计划都易于实行,但没有一种是完善的。成绩是在变动SQL模板的同时也必需变动日记代码。您将在某一点上出错几近是不成制止的。查询将变动但您健忘了更新日记代码,您将停止与将发送到数据库的查询不婚配的日记条目--调试噩梦。

  我们真正必要的是一种使我们可以一次性利用每一个参数变量(在我们的实例中为fooValue和barValue)的计划计划。我们但愿有一种办法,它使我们可以取得查询字符串,并用实践的参数值交换参数占位符。因为java.sql.PreparedStatement没有此类办法,我们必需本人完成。

  定制办理计划

  我们的PreparedStatement定制实行将做为环绕JDBC驱动器供应的“实在语句(realstatement)”的封装器(Wrapper)。封装器语句将转发一切办法挪用(比方setLong(int,long)和setString(int,String))到“实在语句”。在如许做之前它将保留相干的参数值,从而它们能够用于天生日记输入了局。

  表3先容了LoggableStatement类怎样完成java.sql.PreparedStatement,和它怎样利用JDBC毗连和SQL模板作为输出来构建。

  表3:LoggableStatement完成java.sql.PreparedStatement


publicclassLoggableStatementimplementsjava.sql.PreparedStatement{//usedforstoringparametervaluesneeded//forproducinglogprivateArrayListparameterValues;//thequerystringwithquestionmarksas//parameterplaceholdersprivateStringsqlTemplate;//astatementcreatedfromarealdatabase//connectionprivatePreparedStatementwrappedStatement;publicLoggableStatement(Connectionconnection,Stringsql)throwsSQLException{//useconnectiontomakeapreparedstatementwrappedStatement=connection.prepareStatement(sql);sqlTemplate=sql;parameterValues=newArrayList();}}


  LoggableStatement怎样事情

  表4先容了LoggableStatement怎样向saveQueryParamValue()办法增加一个挪用,和在办法setLong和setString的“实在语句”上挪用响应的办法。我们接纳与用于参数设置的一切办法(比方setChar、setLong、setRef和setObj)不异的体例来增添saveQueryParamValue()挪用。表4还显现了在不挪用saveQueryParamValue()的情形下怎样封装办法executeQuery,由于它不是一个“参数设置”办法。

  表4:LoggableStatement办法


publicvoidsetLong(intparameterIndex,longx)throwsjava.sql.SQLException{wrappedStatement.setLong(parameterIndex,x);saveQueryParamValue(parameterIndex,newLong(x));}publicvoidsetString(intparameterIndex,Stringx)throwsjava.sql.SQLException{wrappedStatement.setString(parameterIndex,x);saveQueryParamValue(parameterIndex,x);}publicResultSetexecuteQuery()throwsjava.sql.SQLException{returnwrappedStatement.executeQuery();}


  表5中显现了saveQueryParamValue()办法。它把每一个参数值转换成String暗示,保留以便getQueryString办法往后利用。缺省情形下,一个工具利用其toString办法将被转换成String,但假如工具是String或Date,它将用单引号()暗示。getQueryString()办法使您可以从日记复制年夜多半查询并举行粘贴,无需修正交互式SQL处置器便可举行测试和调试。您能够依据必要订正该办法来转换别的类的参数值。

  表5:saveQueryParamValue()办法


privatevoidsaveQueryParamValue(intposition,Objectobj){StringstrValue;if(objinstanceofString||objinstanceofDate){//ifwehaveaString,includeinthesavedvaluestrValue=""+obj+"";}else{if(obj==null){//convertnulltothestringnullstrValue="null";}else{//unknownobject(includesallNumbers),justcalltoStringstrValue=obj.toString();}}//ifwearesettingapositionlargerthancurrentsizeof//parameterValues,firstmakeitlargerwhile(position>=parameterValues.size()){parameterValues.add(null);}//savetheparameterparameterValues.set(position,strValue);}


  当我们利用尺度办法来设置一切参数时,我们在LoggableStatement中复杂挪用getQueryString()办法来取得查询字符串。一切问号都将被真实的参数值交换,它筹办输入到我们选定的日记目标地。

  利用LoggableStatement

  表6显现怎样变动表1和表2中的代码来利用LoggableStatement。将LoggableStatement引进到我们的使用程序代码中能够办理复制的参数变量成绩。假如改动了SQL模板,我们只需更新PreparedStatement上的参数设置挪用(比方增加一个pstmt.setString(3,"new-param-value"))。这一变动将在日记输入了局中反应出,无需任何纪录代码的手工更新。

  表6:利用LoggableStatement

  
Stringsql="selectfoo,barfromfoobarwherefoo<?andbar=?";longfooValue=99;StringbarValue="christmas";Connectionconn=dataSource.getConnection();PreparedStatementpstmt;if(logEnabled)//useaswitchtotogglelogging.pstmt=newLoggableStatement(conn,sql);elsepstmt=conn.prepareStatement(sql);pstmt.setLong(1,fooValue);pstmt.setString(2,barValue);if(logEnabled)System.out.println("Executingquery:"+((LoggableStatement)pstmt).getQueryString());ResultSetrs=pstmt.executeQuery();


  停止语

  利用本文先容的十分复杂的步骤,您能够为查询纪录扩大JDBCPreparedStatement接口。我们在此处利用的手艺能够被视为“经由过程封装来完成扩大”,或作为Decorator计划形式的一个实例(见参考材料)。经由过程封装来完成扩大在当您必需扩大API但subclassing不是一项可选功效时极为有效。

  您将在参考材料部分找到LoggableStatement类的源代码。您能够按原样利用它,大概举行定制以满意您的数据库使用程序的特别需求。

  参考材料

  ◆下载LoggableStatement类的源代码。

  ◆您将在RomanVichr的提醒和技能:JDBC提醒(developerWorks,2002年10月)中找到利用PreparedStatements的扼要先容.

  ◆LennartJorelid的“UseJDBCforindustrial-strengthperformance”(developerWorks,2000年1月)是一篇不错的在JDBC中计划形式的两部分先容性文章。

  ◆JoshHeidebrecht撰写的“JDBC3.0新特征”(developerWorks,2001年7月)供应JDBC3.0的概述。

  ◆您能够从java.sun.com下载Javaplatform,StandardEdition和JDBC3.0API标准。

  ◆DavidGallardo的“Java计划形式101”(developerWorks,2002年1月)是GangofFour模板不错的先容。

  ◆PaulMonday的“Java计划形式201”(developerWorks,2002年4月)为初级学员供应了Java计划形式更具观点性的申明。

  ◆VinceHuston的DesignPatternssite是别的一个懂得计划形式不错的资本。

  ◆BrianGoetz的“Java实际与理论:功能办理—您有计划吗?”(developerWorks,2003年3月)论述了一些您能够实行用来提拔Java使用程序全体功能的措施。

线上或者测试环境经常出现的误操作总是让DBA同学那么闹心。
小妖女 该用户已被删除
沙发
发表于 2015-1-19 16:18:04 | 只看该作者
groupby子句可以将查询结果分组,并返回行的汇总信息Oracle按照groupby子句中指定的表达式的值分组查询结果。
谁可相欹 该用户已被删除
板凳
发表于 2015-1-25 19:40:53 | 只看该作者
光写几个SQL实在叫无知。
变相怪杰 该用户已被删除
地板
发表于 2015-2-3 17:53:55 | 只看该作者
学习SQL语言的话如果要学会去做网站就不是很难!但是要做数据库管理的话就有难度了!
金色的骷髅 该用户已被删除
5#
发表于 2015-2-9 04:19:30 | 只看该作者
分区表是个亮点!从分区表也能看出微软要做大作强SQLServer的信心。资料很多,这里不详细说。但是重点了解的是:现在的SQLServer2005的表,都是默认为分区表的。因为它要支持滑动窗口的这个特性。这种特性对历史数据和实时数据的处理是很有帮助的。
飘飘悠悠 该用户已被删除
6#
发表于 2015-2-26 22:06:11 | 只看该作者
连做梦都在想页面结构是怎么样的,绝非虚言
活着的死人 该用户已被删除
7#
发表于 2015-3-8 18:15:06 | 只看该作者
可以动态传入参数,省却了动态SQL的拼写。
admin 该用户已被删除
8#
发表于 2015-3-16 10:12:53 | 只看该作者
无法深入到数据库系统层面去了解和探究
兰色精灵 该用户已被删除
9#
发表于 2015-3-22 22:11:45 | 只看该作者
我是一个ERP初学者,对于前台运用基本熟悉,但对于后台SQLServer的运用一点也不懂,特想学习下相关资料。至少懂得一些基本的运用。希望各位能给于建议,小弟再谢过!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 05:48

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表