Cactus
Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ如HttpServletRequest,HttpServletResponse,HttpSession{?/P>
??xml version="1.0" encoding="utf-8" standalone="yes"?>
ideation 发表?2005-6-8 16:26:22 在java对oracle的操作中Q日期字D|很头疼的事情Q其实仔l研I一下也q不难掌握?/p>
举个例子来说明: ?book 中有name varchar2(20)//书籍名称,buydate Date //购买日期 两个字段?/p>
已经创徏了数据库q接Connection conn; Ҏ一、用java.sql.Date实现比较单的yyyy-mm-dd格式日期?/p>
java.sql.Date不支持时间格式。切C要用new java.sql.Date(int year,int month,int date),因ؓq要处理旉差问题?/p>
PreparedStatement pstmt = conn.prepareStatement("insert into book (name,buydate) values (?,?)"); java.sql.Date buydate=java.sql.Date.valueOf("2005-06-08"); Ҏ二、用java.sql.Timestamp,同上不用new Timestamp(....) PreparedStatement pstmt = conn.prepareStatement("insert into book (name,buydate) values (?,?)"); java.sql.Timestamp buydate=java.sql.Timestamp.valueOf("2004-06-08 05:33:99"); Ҏ三、用oracle 的to_date内置函数 PreparedStatement pstmt = conn.prepareStatement("insert into book (name,buydate) values (?,to_date(?, 'yyyy-mm-dd hh24:mi:ss')"); String buydate="2004-06-08 05:33:99"; ?oracle日期格式参数 含义说明 JUnit是由 Erich Gamma ?Kent Beck ~写的一个回归测试框Ӟregression testing frameworkQ。Junit试是程序员试Q即所谓白盒测试,因ؓE序员知道被试的Y件如何(HowQ完成功能和完成什么样QWhatQ的功能。Junit是一套框Ӟl承TestCasec,可以用Junitq行自动试了? Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ如HttpServletRequest,HttpServletResponse,HttpSession{?/P> Abbot是一个用来测试Java GUIs的框架。用单的ZXML的脚本或者Java代码Q你可以开始一个GUI?/P> Junitperf实际是junit的一个decoratorQ通过~写用于junitperf的单元测试,我们也可使测试过E自动化?/P> DbUnit是ؓ数据库驱动的目提供的一个对JUnit 的扩展,除了提供一些常用功能,它可以将你的数据库置于一个测试轮回之间的状态? Mockrunner用在J2EE环境中进行应用程序的单元试。它不仅支持Struts actions, servletsQ过滤器和标{q包括一个JDBC和一个JMS试框架Q可以用于测试基于EJB的应用程序?/P> DBMonster是一个用生成随机数据来测试SQL数据库的压力试工具?/P> MockEJB是一个不需要EJB容器pq行EJBq进行测试的轻量U框架?/P> StrutsTestCase 是Junit TestCasecȝ扩展Q提供基于Struts框架的代码测试。StrutsTestCase同时提供Mock 对象Ҏ和CactusҎ用来实际q行Struts ActionServletQ你可以通过q行servlet引擎来测试。因为StrutsTestCase使用ActionServlet控制器来试你的代码Q因此你不仅可以试Action对象的实玎ͼ而且可以试mappingsQfrom beans以及forwards声明。StrutsTestCase不启动servlet容器来测试struts应用E序Q容器外试Q也属于Mock对象试Q但是与EasyMock不同的是QEasyMock是提供了创徏Mock对象的APIQ而StrutsTest则是专门负责试Struts应用E序的Mock对象试框架? JFCUnit使得你能够ؓJava偏移应用E序~写试例子。它Z用代码打开的窗口上获得句柄提供了支持;为在一个部件层ơ定位部件提供支持;为在部g中发起事Ӟ例如按一个按钮)以及以线E安全方式处理部件测试提供支持?/P> JTestCase 使用XML文g来组l多试案例数据Q声明条Ӟ操作和期望的l果Q,提供了一套易于用的Ҏ来检索XML中的试案例Q按照数据文件的定义来声明结果?/P> SQLUnit是一个单元测试框Ӟ用于Ҏ据库存储q程q行加归试。用 Java/JUnit/XML开发? JTR (Java Test Runner)是一个开源的Z反{控制(IOC)的J2EE试框架。它允许你构建复杂的J2EE试套g(Test Suites)q连到应用服务器执行试,可以包括多个试实例。JTR的licensed是GPL协议?/P> Marathon是一个针对用Java/Swing开发GUI应用E序的测试框Ӟ它由recorder, runner ?editorl成Q测试脚本是python代码。Marathon的焦Ҏ攑֜最l用L试上?/P> TestNG是根据JUnit ?NUnit思想而构建的一个测试框Ӟ但是TestNG增加了许多新的功能得它变得更加强大与容易用比如: Surrogate Test framework是一个值得U赞单元试框架Q特别适合于大型,复杂Javapȝ的单元测试。这个框架能与JUnit,MockEJB和各U支持模拟对象(mock object Q的试工具无缝l合。这个框架基于AspectJ技术?/P> MockCreator可以为给定的interface或class生成模拟对象QMock objectQ的源码?/P> jMock利用mock objects思想来对Java codeq行试。jMockh以下特点:Ҏ扩展Q让你快速简单地定义mock objects,因此不必打破E序间的兌Q让你定义灵zȝ越对象之间交互作用而带来测试局限,减少你测试地脆弱性?/P> EasyMock为Mock Objects提供接口q在JUnit试中利用Java的proxy设计模式生成它们的实例。EasyMock最适合于测试驱动开发?/P> The Grinder是一个负载测试框架。在BSD开源协议下免费使用?/P> XMLUnit不仅有Java版本的还?Net版本的。Java开发的XMLUnit提供了两个JUnit 扩展cXMLAssert和XMLTestCase,和一l支持的cR这些类可以用来比较两张XML之间的不同之处,展示XML利用XSLT?校验XML,求得XPath表达式在XML中的?遍历XML中的某一节点利DOM展开, Jameleon一个自动化试工具。它被用来测试各U各L应用E序Q所以它被设计成插g模式。ؓ了整个试q程变得单Jameleon提供了一个GUI,因此Jameleon实现了一个Swing 插g?/P> J2MEUnit是应用在J2ME应用E序的一个单元测试框架。它ZJUnit. Jetif是一个用UJava实现的回归测试框架。它为JavaE序单元试以及功能试提供了一个简单而且?伸羃的架构,可以用于个h开发或企业U开发的试。它Ҏ使用Q功能强大,而且拥有一些企业试?重要功能。Jetif来源于JUnit, JTestCase以及TestNG的启发,有几个基本的概念直接来自于JUnitQ?比如说断a机制QTest Listener的概念,因此从JUnit转到Jetif是非常容易的?/P> GroboUtils使得扩展Java试变得可能。它包括用在Java不同斚w试的多个子目。在GroboUtils中最常被到的工具?多线E测?multi-threaded tests),整体单元试(hierarchial unit tests),代码覆盖工具(code coverage tool)?/P> TESTARE是用来简化分布式应用E序(比如:在SERVLETS,JMS listeners, CORBA ORBs或RMI环境?试开发过E的一个测试框? MockLib是一个很的包所以可Ҏ地动态创Z个模拟对?你可以从模拟的系l中抛出异常来确保你的系l能够正处理错?它同样也是一个线E安全的模拟对象? JellyUnit是一个基于Jelly的JUnit试机制.它允许用Jelly脚本来完成单元测?其是对于XML,XPath,SQL,HTTP,JMS和SOAP交互的测试特别有? q个目l承于JUnit目的是提供一个分布式的测试环?它给开发?试人员一个运行远EJUnits和复杂测试案例的能力Q这个案例由几个q行q行的远EJUnit试l成?/P> JUnitEE是对JUnit的一个简单扩展,可以支持在一个J2EE应用E序服务器上执行标准的测试案例。它主要׃个把试l果输出为html的servletl成?/P> 引言 管对于Java中文处理问题的讨论已不乏其数Q但׃Java技术涉及内容广QJ2EE包含了十几种相关技术)Q技术供应商J多Q面向Java的Web服务器、应用服务器以及JDBC数据库驱动等都没有官方的标准Q所以Java应用在处理中文过E中Z存在固有的问题外也存在随着选用的服务器Q驱动程序的不同而带来的Java中文问题的多变性,增加了问题的复杂度。那么,我们如何在这么纷J的现象中找到问题的症结呢? Java中文问题的一般解军_?/STRONG> 事实上,Java的中文问题都是由于Java应用所采用的缺省编码格式与目标或者应用所要读入字W的~码格式不同而造成的(具体参见文献1Q。对于如何解决Java的中文问题,通常有四U方法: 1Q选择JDK的中文本地化版本。尽Java2 JDK的中文本地化版本Q?A target=_blank>http://java.sun.com/products/jdk/1.2/chinesejdk.htmlQƈ不是一个官方的版本QSun公司也没有承Z对该本地化版本进行升U,但其仍不׃ؓ一个Java中文问题的解x案?/P>
2Q选择合适的~译参数。对于Java的国际版本来Ԍ我们也可以在~译Java应用的时候通过指定定的编码机制来实现其编译结果对中文的支持。例如,对于需要支持繁体中文和体中文应用可以通过javac -encoding big5 sourcefile.java 和javac -encoding gb2312 sourcefile.java来编译源E序?/P>
3Q通过~程的方式实现字W编码的转换代码。通过~程的方式来解决Java的中文问题,已经成ؓ了一U较为普遍的做法。下面就是一U最常见的字W编码{换函敎ͼ其将字符的编码格式{换ؓ中文Windowspȝ的GBK~码形式?/P>
public static String toChinese(String strvalue) 4Q定义字W输出集。对于JSP应用Q我们可以通过<%@ page contentType="text/html; charset=GBK" %>?lt;%@ page contentType="text/html; charset=GB2312" %>来定义JSP面的字W输出集。当Ӟ我们也可以通过HTML的标?lt;META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">来定义字W的输出集?/P>
存在的问?/STRONG> ҎҎ实现的方式,我们可以以上四U方法分Zc,一cL通过利用某些标准或者规则来实现的方法,上面?)?)?Q都属于此类Q一cL通过针对性的~程来实现的ҎQ上面所提的Ҏ3Q就属于此类?/P>
׃Ҏ1)Q?)Q?Q是h规范性的一cL法,所以方法比较简单,解决Ҏ也不具备较大的针Ҏ,较ؓ通用Q例如我们可以采用方?Q的~译方式通过~译Java源文件来实现内码的预|,而无需考虑源码到底有哪些部分出CJava的中文处理问题,诸如输出q{等?/P>
但是Q正׃q些Ҏ不具备针Ҏ,解决问题的方法过于统一Q所以在某些情况下,它们q不能彻底地解决Java的中文问题。D一个非常常见的例子。在通常情况下,用户的Java应用往往需要与其它Java应用接口q行交互Q例如通过某种版本的JDBC讉K数据库。由于JDBC的驱动所支持的编码随着提供商乃至版本的不同而不同,所以如果在数据库的输入输出q程中出C文不能正处理问题时Q我们需要在数据的输入和输出q程做两ơ正好相反的~码转换Q这对于Ҏ1Q,2Q,4Q来_往往是无法解决的。当Ӟ对于Ҏ2Q我们也可以通过采用一些技巧来满上面的情况Q一个最有效的办法就是尽量将Java应用的各个部分组件化。例如我们可以通过数据库的读入和输出代码分解在不同的源文件上来实现分别编译,从而满不同的字符~码要求。但是通常的程序设计都不太可能满q种要求Q因U程序的划分l果很可能是不合理的。例如,我们数据库的读出和写入Ҏ装C个类中是比较合适的一U设计,但如果将该类的这两个Ҏ分别实现在两个文仉则变得非怸合理。因此对?Q,2Q,4Q方法来_虽然实现比较单,但却h一些无法克服的~点。这也是那些实现h相对复杂的编E方法得以流行的原因?/P>
相对于方?Q,2Q,4Q来_Ҏ3Q具有更好的针对性和灉|性。程序可以根据不同的情况做出灉|的处理,在Q何需要的地方q行字符的编码{换,但是该方法的特点也对软g的开发h员提Z更高要求--必须能够准确的捕捉到有可能发生中文处理问题的地方Qƈ做出正确的判断和处理?/P>
分析的原?/STRONG> ȝ说来Q所有解决Java中文处理的方法都不是很复杂。相反的是,׃Java技术特别是J2EE技术涉及的内容J多Q各UWeb服务器、应用服务器以及JDBC数据库驱动等参差不齐Q所以如何正而及时的发现应用的中文处理问题则变得相对复杂的多。那么我们如何来发现q些问题呢? 通常QJava处理中文时所产生的问题都是由于用LJava应用所采用的缺省编码格式与目标或者应用所要读入字W的~码格式不同而造成的,而引赯些不同的一个主要原因就是用LJava应用与其它应用进行了~码格式不匹配的数据交换Q包括直接或间接的数据输入、输出)。所以,Z及时发现问题Q我们可以由q一点入手,Ҏ以下的原则对应用q行分析Q?/P>
1. 注意字符变量情况。由于变量的字符~码形式较ؓ隐蔽Q多ơ变量间数值的改变和运可能会引v字符集的改变Q在变量与页面所提交数据的各U操作中Q较Ҏ发生不同~码格式字符q行q算的情c? 2. 注意M形式的字W读入与输出。之所以要提到M形式Q是因ؓJava应用大多数都是作为网l应用开发的Q所以与其它语言的应用相比,Java应用需要面对网l世界各U各L字符数据交换形式。例如各U表单的数据提交QURL形式的数据读入,l过加密q算的字W数据交换,|页控g选择l果的输入,控g内容的的昄Q如List控gQ等{? 3. 心使用W三方的lg和应用。由于第三方lg和应用的实现是非透明的,所以一般情况下Q我们很隑ֈ断这些组件或驱动的缺省编码格式是什么,也无法对其进行控制。因此,在用它们所提供的接口函数进行数据交换的时候要特别注意Q如果确实出C文无法正处理情况,应首先检查我们自q代码q调整相关代码以适应q些接口Q因些组件或者应用基本上不会提供调整~码机制的接口。必要时Q我们可能需要采用其它可替换的组件或者应用? 4. 注意被请求对象所含有的数据输入与输出。这是非帔R蔽的一cL况,当我们的应用以对象的方式Q例如序列化的对象)q行交互Ӟ如果q个对象内部含有字符数据的处理过E,或者含有某些数据的输入、输出,甚至是抛ZD는中文注解的异常,都可能出C文无法正显C等问题。由于这些行为往往被封装在对象中,所以我们在~写E序Ӟ很容易忽略这U可能情cƈ且这U情况带有一定的不可预见性,例如我们可能不清楚这个对象会在什么时候抛Z么样的异常,所以这时我们就需要做一定的试工作? 5. 注意数据库的数据讉Kq程。Java通过JDBC与数据库建立q接。对于JDBC驱动E序来说Q由于目前大部分的JDBC驱动E序q不是针对中文系l而设计的(中文数据大都采用ISO-8859-1~码方式)Q所以一般情况下在数据读写过E中往往都需要字W编码的转化。但是我们仍用户在用这些JDBC驱动Ӟ仔细阅读它的说明。如果确实无法弄清JDBC字符数据的编码到底是什么,我们的徏议是做一些必要的试。例如下面是一l在体中文Win2000q_下,采用Weblogic 6.0所提供的JDBC驱动从MS SQL Server2000中正读入中文字W的代码Q例子中q行了字W运)Q? ... 然而,需要注意的是,不同的JDBC驱动对相同的数据库的支持q不同,而同一cJDBC驱动对不同的数据库的支持也不相同Q也是说我们的字符转化代码在JDBC驱动改变甚至是版本变化情况下都有可能无法正确工作。例如对于上面的例子Q在同样的环境下改用i-net 的Una 2000 Driver Version 2.03 for MS SQL ServerӞ是无法正处理中文的。原因很单,q个JDBC驱动本n支持的就是GBK的编码机Ӟ所以根本就不需要做M的编码{化? 6. 必要的测试。由于Java中文问题的生随着Web服务器,览器,q行环境和开发工L不同都可能发生变化,所以ؓ了更好的避免问题的发生,我们必须作一些针Ҏ的试。另外,在我们确实无法通过分析来确定Java的中文处理问题是否可能发生的情况下或者无法知道问题的发生是由于哪个环节(是Web服务器,览器还是JDBC数据驱动{等Q引L时候,试工作则变得非帔R要。ƈ且我们可能需要较为全面的试Q例如对Web服务器,览器和JDBC数据驱动{都要做试Q这h利于我们扑և那些隐藏在多个环节协调过E中所产生的问题?/P>
l论 事实上,Java中文处理之所以存在问题,其根本原因是׃被操作的中文字符Q变量)的编码格式与目标的编码格式不同造成的,所有这些问题其实都是发生在字符的读入、输E中的,只要我们把握住这一环节Q就可以更好的发现、分析、处理和预防Java的中文问题了?/P>
pstmt.setString(1, "Java~程思想");
pstmt.setDate(2,buydate );
pstmt.execute();
pstmt.setString(1, "Java~程思想");
pstmt.setTimestamp(2,buydate );
pstmt.execute();
pstmt.setString(1, "Java~程思想");
pstmt.setString(2,buydate );
pstmt.execute();
d: 一周中的星期几
day: 天的名字Q用空格填充到9个字W ?br />dd: 月中的第几天
ddd: q中的第几天
dy: 天的写名
iw: ISO标准的年中的W几周 ?br />iyyy: ISO标准的四位年q?br />yyyy: 四位q䆾
yyy,yy,y: q䆾的最后三位,两位Q一位 ?br />hh: 时Q按12时计 ?br />hh24: 时Q按24时计 ?br />mi: 分 ?br />ss: U ?br />mm: 月 ?br />mon: 月䆾的简写 ?br />month: 月䆾的全名 ?br />w: 该月的第几个星期
ww: q中的第几个星期
到此刻,你应该烦恼已消,L了很多吧?/p>
]]>
原因是SQL中不区分大小写,MM和mm被认为是相同的格式代码,所以Oracle的SQL采用了mi代替分钟?br />select to_date('2005-01-01 13:14:20','yyyy-MM-dd HH24:mi:ss') from dual;
二、另要以24时的Ş式显C出来要用HH24
select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual;//mi是分?br />select to_char(sysdate,'yyyy-MM-dd HH24:mm:ss') from dual;//mm会显C月?img src ="http://www.tkk7.com/xiaoxiaoyupku/aggbug/42736.html" width = "1" height = "1" />
]]> JUnit
Cactus
Abbot
JUnitPerf
DbUnit
Mockrunner
DBMonster
MockEJB
StrutsTestCase
JFCUnit
JTestCase
SQLUnit
JTR
Marathon
TestNG
*支持JSR 175注释QJDK 1.4利用JavaDoc注释同样也支持)
*灉|的Test配置
*支持默认的runtime和logging JDK功能
*强大的执行模型(不再TestSuiteQ?BR>*支持独立的测试方法?/P> Surrogate Test framework
MockCreator
jMock
EasyMock
The Grinder
XMLUnit
Jameleon
J2MEUnit
Jetif
GroboUtils
Testare
MockLib
JellyUnit
Pisces
JUnitEE
]]>
Java数据库连接(JDBCQAPI是一pd能够让Java~程人员讉K数据库的接口Q各个开发商的接口ƈ不完全相同。在使用多年的Oracle公司的JDBC后,我积累了许多技巧,q些技巧能够我们更好地发挥系l的性能和实现更多的功能?
1、在客户端Y件开发中使用Thin驱动E序
在开发Java软g斚wQOracle的数据库提供了四U类型的驱动E序Q二U用于应用Y件、applets、servlets{客L软gQ另外二U用于数据库中的Java存储q程{服务器端Y件。在客户机端软g的开发中Q我们可以选择OCI驱动E序或Thin驱动E序。OCI驱动E序利用Java本地化接口(JNIQ,通过Oracle客户端Y件与数据库进行通讯。Thin驱动E序是纯Java驱动E序Q它直接与数据库q行通讯。ؓ了获得最高的性能QOracle在客L软g的开发中使用OCI驱动E序Q这g是正的。但我徏议用Thin驱动E序Q因为通过多次试发现Q在通常情况下,Thin驱动E序的性能都超q了OCI驱动E序?
2、关闭自动提交功能,提高pȝ性能
在第一ơ徏立与数据库的q接Ӟ在缺省情况下Q连接是在自动提交模式下的。ؓ了获得更好的性能Q可以通过调用带布值false参数的ConnectioncȝsetAutoCommit()Ҏ关闭自动提交功能Q如下所C:
conn.setAutoCommit(false);
值得注意的是Q一旦关闭了自动提交功能Q我们就需要通过调用Connectioncȝcommit()和rollback()Ҏ来h工的方式对事务进行管理?
3、在动态SQL或有旉限制的命令中使用Statement对象
在执行SQL命oӞ我们有二U选择Q可以用PreparedStatement对象Q也可以使用Statement对象。无论多次C用同一个SQL命oQPreparedStatement都只对它解析和编译一ơ。当使用Statement对象Ӟ每次执行一个SQL命oӞ都会对它q行解析和编译。这可能会你认为,使用PreparedStatement对象比用Statement对象的速度更快。然而,我进行的试表明Q在客户端Y件中Q情况ƈ非如此。因此,在有旉限制的SQL操作中,除非成批地处理SQL命oQ我们应当考虑使用Statement对象?
此外Q用Statement对象也得编写动态SQL命o更加单,因ؓ我们可以字W串q接在一P建立一个有效的SQL命o。因此,我认为,Statement对象可以使动态SQL命o的创建和执行变得更加单?
4、利用helper函数对动态SQL命oq行格式?
在创Z用Statement对象执行的动态SQL命oӞ我们需要处理一些格式化斚w的问题。例如,如果我们惛_Z个将名字O'Reilly插入表中的SQL命oQ则必须使用二个相连的?'”号替换O'Reilly中的?”号。完成这些工作的最好的Ҏ是创Z个完成替换操作的helperҎQ然后在q接字符串心服用公式表达一个SQL命oӞ使用创徏的helperҎ。与此类似的是,我们可以让helperҎ接受一个Date型的|然后让它输出ZOracle的to_date()函数的字W串表达式?
5、利用PreparedStatement对象提高数据库的M效率
在用PreparedStatement对象执行SQL命oӞ命o被数据库q行解析和编译,然后被放到命令缓冲区。然后,每当执行同一个PreparedStatement对象Ӟ它就会被再解析一ơ,但不会被再次~译。在~冲Z可以发现预编译的命oQƈ且可以重C用。在有大量用L企业U应用Y件中Q经怼重复执行相同的SQL命oQ用PreparedStatement对象带来的编译次数的减少能够提高数据库的M性能。如果不是在客户端创建、预备、执行PreparedStatementd需要的旉长于StatementdQ我会徏议在除动态SQL命o之外的所有情况下使用PreparedStatement对象?
6、在成批处理重复的插入或更新操作中用PreparedStatement对象
如果成批地处理插入和更新操作Q就能够显著地减它们所需要的旉。Oracle提供的Statement?CallableStatementq不真正地支持批处理Q只有PreparedStatement对象才真正地支持批处理。我们可以用addBatch()和executeBatch()Ҏ选择标准的JDBC批处理,或者通过利用PreparedStatement对象的setExecuteBatch()Ҏ和标准的executeUpdate()Ҏ选择速度更快的Oracle专有的方法。要使用Oracle专有的批处理机制Q可以以如下所C的方式调用setExecuteBatch()Q?
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);
...
pstmt.executeUpdate();
}
调用setExecuteBatch()时指定的值是一个上限,当达到该值时Q就会自动地引发SQL命o执行Q标准的executeUpdate()Ҏ׃被作为批处理送到数据库中。我们可以通过调用PreparedStatementcȝsendBatch()Ҏ随时传输批处理Q务?
7、用Oracle locatorҎ插入、更新大对象QLOBQ?
Oracle的PreparedStatementcM完全支持BLOB和CLOB{大对象的处理,其是Thin驱动E序不支持利用PreparedStatement对象的setObject()和setBinaryStream()Ҏ讄BLOB的|也不支持利用setCharacterStream()Ҏ讄CLOB的倹{只有locator本n中的Ҏ才能够从数据库中获取LOBcd的倹{可以用PreparedStatement对象插入或更新LOBQ但需要用locator才能获取LOB的倹{由于存在这二个问题Q因此,我徏议用locator的方法来插入、更新或获取LOB的倹{?
8、用SQL92语法调用存储q程
在调用存储过E时Q我们可以用SQL92或Oracle PL/SQLQ由于用Oracle PL/SQLq没有什么实际的好处Q而且会给以后l护你的应用E序的开发h员带来麻烦,因此Q我在调用存储过E时使用SQL92?
9、用Object SQL对象模式{Ud数据库中
既然可以Oracle的数据库作ؓ一U面向对象的数据库来使用Q就可以考虑应用程序中的面向对象模式{到数据库中。目前的Ҏ是创建Java bean作ؓ伪装的数据库对象Q将它们的属性映到关系表中Q然后在q些bean中添加方法。尽这样作在Java中没有什么问题,但由于操作都是在数据库之外进行的Q因此其他访问数据库的应用Y件无法利用对象模式。如果利用Oracle的面向对象的技术,可以通过创徏一个新的数据库对象cd在数据库中模仿其数据和操作,然后使用JPublisher{工L成自qJava beancR如果用这U方式,不但Java应用E序可以使用应用软g的对象模式,其他需要共享你的应用中的数据和操作的应用Y件也可以使用应用软g中的对象模式?
10、利用SQL完成数据库内的操?
我要向大家介l的最重要的经验是充分利用SQL的面向集合的Ҏ来解x据库处理需求,而不是用Java{过E化的编E语a?
如果~程人员要在一个表中查找许多行Q结果中的每个行都会查找其他表中的数据,最后,~程人员创徏了独立的UPDATE命o来成批地更新W一个表中的数据。与此类似的d可以通过在set子句中用多列子查询而在一个UPDATE命o中完成。当能够在单一的SQL命o中完成Q务,何必要让数据在网上流来流ȝQ我用户认真学习如何最大限度地发挥SQL的功能?BR>
]]>
LOBcd分ؓBLOB和CLOB两种QBLOB即二q制大型对象QBinary Large ObjectQ,适用于存贮非文本的字节流数据Q如E序、图象、媄音等Q。而CLOBQ即字符型大型对象(Character Large ObjectQ,则与字符集相养I适于存贮文本型的数据Q如历史档案、大部头著作{)?BR> 下面以程序实例说明通过JDBC操纵Oracle数据库LOBcd字段的几U情c?BR> 先徏立如下两个测试用的数据库表,Power Designer PD模型如下Q?BR>
SQL语句为:
CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB)
CREATE TABLE TEST_BLOB ( ID NUMBER(3), BLOBCOL BLOB)
一?CLOB对象的存?BR>
1、往数据库中插入一个新的CLOB对象
public static void clobInsert(String infile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 插入一个空的CLOB对象 */
stmt.executeUpdate("INSERT INTO TEST_CLOB valueS ('111', EMPTY_CLOB())");
/* 查询此CLOB对象q?*/
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
while (rs.next()) {
/* 取出此CLOB对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 向CLOB对象中写入数?*/
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
2、修改CLOB对象Q是在原CLOB对象基础上进行覆盖式的修改)
public static void clobModify(String infile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询CLOB对象q?*/
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
while (rs.next()) {
/* 获取此CLOB对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* q行覆盖式修?*/
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
3、替换CLOB对象Q将原CLOB对象清除Q换成一个全新的CLOB对象Q?/STRONG>
public static void clobReplace(String infile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 清空原CLOB对象 */
stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID='111'");
/* 查询CLOB对象q?*/
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
while (rs.next()) {
/* 获取此CLOB对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 更新数据 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
4、CLOB对象d
public static void clobRead(String outfile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询CLOB对象 */
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID='111'");
while (rs.next()) {
/* 获取CLOB对象 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 以字WŞ式输?*/
BufferedReader in = new BufferedReader(clob.getCharacterStream());
BufferedWriter out = new BufferedWriter(new FileWriter(outfile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
out.close();
in.close();
}
} catch (Exception ex) {
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
二?BLOB对象的存?/STRONG>
1?向数据库中插入一个新的BLOB对象
public static void blobInsert(String infile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 插入一个空的BLOB对象 */
stmt.executeUpdate("INSERT INTO TEST_BLOB valueS ('222', EMPTY_BLOB())");
/* 查询此BLOB对象q?*/
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
while (rs.next()) {
/* 取出此BLOB对象 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 向BLOB对象中写入数?*/
BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
2、修改BLOB对象Q是在原BLOB对象基础上进行覆盖式的修改)
public static void blobModify(String infile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询BLOB对象q?*/
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
while (rs.next()) {
/* 取出此BLOB对象 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 向BLOB对象中写入数?*/
BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
3、替换BLOB对象Q将原BLOB对象清除Q换成一个全新的BLOB对象Q?/STRONG>
public static void blobReplace(String infile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 清空原BLOB对象 */
stmt.executeUpdate("UPDATE TEST_BLOB SET BLOBCOL=EMPTY_BLOB() WHERE ID='222'");
/* 查询此BLOB对象q?*/
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
while (rs.next()) {
/* 取出此BLOB对象 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 向BLOB对象中写入数?*/
BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
4、BLOB对象d
public static void blobRead(String outfile) throws Exception
{
/* 讑֮不自动提?*/
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查询BLOB对象 */
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222'");
while (rs.next()) {
/* 取出此BLOB对象 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 以二q制形式输出 */
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outfile));
BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出错回滚 */
conn.rollback();
throw ex;
}
/* 恢复原提交状?*/
conn.setAutoCommit(defaultCommit);
}
观察上述E序对LOBcd字段的存取,我们可以看出Q较之其它类型字D,有下面几个显著不同的特点Q?BR>
一是必d消自动提交?/STRONG>
存取操作开始前Q必ȝsetAutoCommit(false)取消自动提交。其它类型字D则无此Ҏ要求。这是因为存取LOBcd字段Ӟ通常要进行多ơ操作可以完成。不q样的话QOracle抛出“读取违反顺序”的错误?BR>
二是插入方式不同?BR>
LOB数据不能象其它类型数据一L接插入(INSERTQ。插入前必须先插入一个空的LOB对象QCLOBcd的空对象为EMPTY_CLOB()QBLOBcd的空对象为EMPTY_BLOB()。之后通过SELECT命o查询得到先前插入的记录ƈ锁定Q而将I对象修改ؓ所要插入的LOB对象?BR>
三是修改方式不同?/STRONG>
其它cd的字D修ҎQ用UPDATE ?SET…命令即可。而LOBcd字段Q则只能用SELECT ?FOR UPDATE命o记录查询出来ƈ锁定Q然后才能修攏V且修改也有两种ҎQ一是在原数据基上的修改Q即覆盖式修改)Q执行SELECT ?FOR UPDATE后再Ҏ据;二是替换Q先原数据清掉Q再修改Q,先执行UPDATE命oLOB字段之D为空的LOB对象Q然后进行第一U改法。徏议用替换的ҎQ以实现与其它字DUPDATE操作后一L效果?BR>
四是存取时应使用由数据库JDBC驱动E序提供的LOB操作cR?/STRONG>
对于Oracle数据库,应用oracle.sql.CLOB和oracle.sql.BLOB。不使用由数据库JDBC驱动E序提供的LOBcLQ程序运行时易于出现“抽象方法调用”的错误Q这是因为JDBC所定义的java.sql.Clob与java.sql.Blob接口Q其中的一些方法ƈ未在数据库厂家提供的驱动E序中真正实现?BR>
五是存取手段与文件操作相ѝ?/STRONG>
对于BLOBcdQ应用InputStream/OutputStreamc,此类不进行编码{换,逐个字节存取。oracle.sql.BLOBcȝ应提供了getBinaryStream()和getBinaryOutputStream()两个ҎQ前一个方法用于读取Oracle的BLOB字段Q后一个方法用于将数据写入Oracle的BLOB字段?BR> 对于CLOBcdQ应用Reader/Writerc,此类q行~码转换。oracle.sql.CLOBcȝ应提供了getCharacterStream()和getCharacterOutputStream()两个ҎQ前一个方法用于读取Oracle的CLOB字段Q后一个方法用于将数据写入Oracle的CLOB字段?BR> 需要说明的是,Z大幅提高E序执行效率Q对BLOB/CLOB字段的读写操作,应该使用~冲操作c(带Buffered前缀Q,卻IBufferedInputStreamQBufferedOutputStreamQBufferedReaderQBufferedWriter。例E中全部使用了缓冲操作类?BR>
结Q通过JDBC操纵Oracle数据库的LOB字段Q不外乎插入、修攏V替换、读取四U方式,掌握hq不难。在实际操作中要注意上面所说的几点Q结合阅ME源E序Q用户会很快明白LOBcd字段的用的Q也必将领悟到这U类型字D늚妙处Q?/STRONG>
]]>
LOBcd分ؓBLOB和CLOB两种QBLOB即二q制大型对象QBinary Large ObjectQ,适用于存贮非文本的字节流数据Q如E序、图象、媄音等Q。而CLOBQ即字符型大型对象(Character Large ObjectQ,则与字符集相养I适于存贮文本型的数据Q如历史档案、大部头著作{)?BR>
对于一般的java应用E序Qclobcd的数据用对象形式插入卛_Q连接方式采用Oracle Thin JDBC Driver
注意Q存取操作开始前Q必ȝsetAutoCommit(false)取消自动提交Q否则Oracle抛出“读取违反顺序”的错误?BR>
取: ...
con.setAutoCommit(false);
....
if(rss.next())
{
Clob clob = rss.getClob(1);
if(clob!=null)
//直接转换为Stringq回Q也可用getCharacterOutputStream()或getAsciiOutputStream()
//
String str=clob.getSubString((long) 1, (int) clob.length());
}
写:LOBcd字段Q则只能用SELECT ?FOR UPDATE命o记录查询出来ƈ锁定Q然后才能修?BR>import oracle.sql.CLOB;
OracleResultSet rss=(OracleResultSet)stmt.executeQuery("select my_clob from test where id=1 for update");
if(rss.next())
{
CLOB clob=(CLOB)rss.getClob(1);
//content为大?k 的String,当然也可使用Ş式写?BR> clob.putString(1,content);
.....
OraclePreparedStatement pstmt=(OraclePreparedStatement)con.prepareStatement("update test set my_clob=?");
pstmt.setClob(1,(Clob)clob);
pstmt.executeUpdate();
...
}
但同LҎ在BEA WLS 8.1SP2上取数据没有问题Q写CLOB会有问题的,会报一U这L错误:java.lang.ClassCastException
Ҏbea 是这栯释ƈ解决的:
For most extensions that Oracle provides, you can use the standard technique as described in Using Vendor Extensions to JDBC Interfaces. However, the Oracle Thin driver does not provide public interfaces for its extension methods in the following classes:
oracle.sql.ARRAY
oracle.sql.STRUCT
oracle.sql.REF
oracle.sql.BLOB
oracle.sql.CLOB
WebLogic Server provides its own interfaces to access the extension methods for those classes:
weblogic.jdbc.vendor.oracle.OracleArray
weblogic.jdbc.vendor.oracle.OracleStruct
weblogic.jdbc.vendor.oracle.OracleRef
weblogic.jdbc.vendor.oracle.OracleThinBlob
weblogic.jdbc.vendor.oracle.OracleThinClob
意思即是采用weblogic.jdbc.vendor.oracle.OracleThinClob 替代oracle.sql.CLOB
修改后的写CLOB字段Q只用修改一?其他不变?BR>weblogic.jdbc.vendor.oracle.OracleThinClob clob=(OracleThinClob)rss.getClob(1);
]]>
{
try{
if(strvalue==null)
return null;
else
{
strvalue = new String(strvalue.getBytes("ISO8859_1"), "GBK");
return strvalue;
}
}catch(Exception e){
return null;
}
}
Class.forName("weblogic.jdbc.mssqlserver4.Driver").newInstance();
conn = myDriver.connect("jdbc:weblogic:mssqlserver4", props);
conn.setCatalog("labmanager");
Statement st = conn.createStatement();
//execute a query
String testStr;
String testTempStr = new String() ;
testStr = new String(testTempStr.getBytes("ISO-8859-1"));//~码转化
DatabaseMetaData DBMetaData =conn.getMetaData();
ResultSet rs = DBMetaData.getTables(null, null,null,new String[]{"TABLE"} );
while (rs.next()){
for(int j=1; j<=rs.getMetaData().getColumnCount(); j++){
testStr = testStr +String(rs.getObject(j).toString().getBytes("ISO-8859-1"));
}
}
2.sql server 2000 sp3升?BR> 你可以在q里下蝲http://www.bossed.com.cn/download/detailcp.asp?id=74
3.sql server 2000 jdbc 驱动 //q个需要自己找?
4.jdk1.4 //以下的例子是该版?BR>在以上条件满的情况?作以下事?BR> 1.建立新数据库名ؓQTESTDB ,q在其中建立一个名为test_student的表
包括以下几列QSnoQSnameQSageQSsexQSclassQ?nbsp;
2.开始编写你自己的连接数据库的类Q我q里是借鉴他h的版权不归我所有)Q你也可以用自己的方?nbsp;
class Testj{
public static void main(String args[])
{
String RL = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=TESTDB";
String user ="king";//q里替换成你自已的数据库用户?BR> String password = "sql";//q里替换成你自已的数据库用户密码
String sqlStr = "select * from test_student";
try{ //q里的异常处理语句是必需?否则不能通过~译!
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
System.out.println( "cd例化成功!" );
System.out.println("slkdjf");
Connection con = DriverManager.getConnection(RL,user,password);
System.out.println( "创徏q接对像成功!" );
Statement st = con.createStatement();
System.out.println( "创徏Statement成功!" );
ResultSet rs = st.executeQuery( sqlStr );
System.out.println( "操作数据表成?" );
System.out.println( "----------------!" );
while(rs.next())
{
System.out.print(rs.getInt("Sno") + " ");
System.out.print(rs.getString("Sname") + " ");
System.out.print(rs.getInt("Sage") + " ");
System.out.print(rs.getString("Ssex") + " ");
System.out.println(rs.getString("Sclass"));
}
rs.close();
st.close();
con.close();
}
catch(Exception err){
err.printStackTrace(System.out);
}
}
}
下面q行调试Q?BR> javac Testj.java
java Testj
如果正确输出应该是:
cd例化成功!
slkdjf
创徏q接对像成功!
创徏Statement成功!
操作数据表成?
----------------!
2000 刚 21 ?nbsp; 12
2001 黄 22 ?nbsp; 12
2002 李娜 20 ?nbsp; 11
2003 王芳 19 ?nbsp; null
2004 黄明 22 ?nbsp; 11
2005 梅兰 21 ?nbsp; 12
2006 李玉 22 ?nbsp; 15
2007 李^ 32 ?nbsp; 12
注意Q这里有几点要说?BR>1.路径问题Q?BR> 你必配|你的classpath路径否则他在~译时会抱错
java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:141)
at Test.main(Test.java:11)
你的路径应该是这样配|:你可以在在安装jdbc驱动后看那里的帮助文档(是英文的Q;
//q里指在xppȝ?BR> classpath = ,;C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\msbase.jar;
C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\mssqlserver.jar;
C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\msutil.jar;
可千万不要写错哟Q?BR> 2.sp3补丁包问题:
如果你在~译时出C列问?nbsp;那么你需要下载ƈ安装sp3补丁?BR> java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Error establis
hing socket.
at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)
at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source)
at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source)
at com.microsoft.jdbc.sqlserver.tds.TDSConnection.<init>(Unknown Source)
at com.microsoft.jdbc.sqlserver.SQLServerImplConnection.open(Unknown Source)
at com.microsoft.jdbc.base.BaseConnection.getNewImplConnection(Unknown Source)
at com.microsoft.jdbc.base.BaseConnection.open(Unknown Source)
at com.microsoft.jdbc.base.BaseDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at Test.main(Test.java:14)
3.权限问题
如果你出现类DL问题
cd例化成功!
slkdjf
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]用户 'king' dp|?BR>原因: 未与信Q SQL Server q接相关联?BR> at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)
at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source)
at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processErrorToken(Unknown Source)
at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReplyToken(Unknown Source)
at com.microsoft.jdbc.sqlserver.tds.TDSLoginRequest.processReplyToken(Unknown Source)
at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source)
at com.microsoft.jdbc.sqlserver.SQLServerImplConnection.open(Unknown Source)
at com.microsoft.jdbc.base.BaseConnection.getNewImplConnection(Unknown Source)
at com.microsoft.jdbc.base.BaseConnection.open(Unknown Source)
at com.microsoft.jdbc.base.BaseDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(DriverManager.java:512)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at Testj.main(Testj.java:14)
原困是未讄SQL SERVERd认证模式为合认证模式,因ؓSQL SERVER默认安装后认证模式ؓWINDOWS认证模式Q从而导致出错?BR>解决ҎQ启动SQLSERVER企业理器,选择要进行认证模式设|的服务器。右击该服务器,在弹单中选择属性,SQL SERVER?BR>弹出属性对话框在属性对话框中选择安全性选项Q在w䆾验证处选择“SQL Server和Windows”,然后定?/FONT>
<Context path="/quality" docBase="quality" debug="0" reloadable="true" crossContext="true">
<Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_quality_log." suffix=".txt" timestamp="true"/>
<Resource name="jdbc/connectDB" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/connectDB">
<parameter>
<name>maxActive</name>
<!-- Maximum number of DB connections in pool.Set to 0 for no limit. -->
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<!-- Maximum number of idle DB connections to retain in pool.Set to 0 for no limit. -->
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<!-- Maximum time to wait for a DB connection to become available in ms.An exception is thrown if this timeout is exceeded.Set to -1 to wait indefinitely. -->
<value>10000</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<!-- Abandoned DB connections are removed and recycled -->
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<!-- Use the removeAbandonedTimeout parameter to set the number of seconds a DB connection has been idle before it is considered abandoned. -->
<value>60</value>
</parameter>
<parameter>
<name>logAbandoned</name>
<!-- Log a stack trace of the code which abandoned -->
<value>false</value>
</parameter>
<parameter>
<name>factory</name>
<!-DBCP Basic Datasource Factory -->
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>username</name>
<!-- Database User Name -->
<value>Iorishinier</value>
</parameter>
<parameter>
<name>password</name>
<!-- User Password -->
<value>mypasswd</value>
</parameter>
<parameter>
<name>driverClassName</name>
<!-- Database Driver Class Name -->
<value>net.sourceforge.jtds.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<!-- Database Address -->
<value>jdbc:jtds:sqlserver://127.127.127.127:1433/Northwind</value>
</parameter>
</ResourceParams>
</Context>
<!-- Database Config start -->
<resource-ref>
<description>connectDB test</description>
<res-ref-name>jdbc/connectDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<!-- Database Config end -->
<%@ page contentType="text/html;charset=GBK"%>
<%@ page errorPage="error.jsp"%>
<%@ page import="javax.naming.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="java.sql.*"%>
<html>
<head>
</head>
<body>
<%
……………?BR> ……………?BR>
// 数据库操?BR> Context ctx=null;
Connection cnn=null;
Statement stmt=null;
ResultSet rs=null;
try
{
ctx=new InitialContext();
if(ctx==null)
throw new Exception("没有匚w的环?);
DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/connectDB");
if(ds==null)
throw new Exception("没有匚w数据?);
cnn=ds.getConnection();
stmt=cnn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs=stmt.executeQuery("select * from table1");
……………?BR> ……………?BR>
}
finally
{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(cnn!=null)
cnn.close();
if(ctx!=null)
ctx.close();
}
%>
</body>
</html>
无论是独立的html,q是其他E序生成?如servlet{?注意在最l的html?lt;head>?lt;/head>之间必须加入meta标签,用来指定html中输入字W的~码.?
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>试GET && POST-Send</title>
</head>
首先必须解决E序输出(如response.writeln(String s))和接受从客户端传来的数据(如request.getParameter(String sname))~码问题Q我们可以利用文件过滤功能,具体需要所用的jsp/servlet容器或者服务器提供的功能设|,如在Tomcat5.5.9中可以在webapps/yourAppDirectory/WEB-INF/web.xml中设|如下:
<filter>
<filter-name>SetCharsetEncodingFilter</filter-name>
<display-name>SetCharsetEncodingFilter</display-name>
<description>Set CharsetEncoding Filter</description>
<filter-class>com.gg.comm.web.SetCharsetEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>gb2312</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharsetEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>其中SetCharsetEncodingFilter Class是用来讄request和reponse字符~码的filterc,其中讄语句如下Q?/P>
request.setCharacterEncoding(targetEncoding);
response.setContentType("text/html");
response.setCharacterEncoding(targetEncoding);
另外Z解决通过get(url中带有参?方式传递参数的q问题Q我们还需要设|一下url传递参数所需要的~码Q具体在Tomcat5.5.9中可以在${Tomcat_home}\conf\server.xml中的<connector>?lt;/connector>之间讄Q如下:
<!--
URIEncoding="GBK":Force GET method String(Chinese) can be transferd properly by http:urinote:Tomcat only support GBK specification,so not set charset gb2312
-->
<Connector URIEncoding="GBK" port="80" redirectPort="8443" maxSpareThreads="75" maxThreads="150" minSpareThreads="25">
</Connector>
最后ؓ了解决jsp的ؕ码问题,我们q需要作如下处理Q即在左右的jsp头均加上如下指oQ?/P>
<%@ page contentType="text/html;charset=gb2312" language="java" %>
或?BR> <%@ page pageEncoding="gb2312"%>
关于写入数据库和d数据库数据的q问题Q可以通过如下方式L解决Q?/P>
到此Q一般来说对于WEB方式的应用来_中文问题可以解决了。当然以上方法是Ҏl一~码的原则解决的以及WEB方式的文件{换关p(file->class->load->execute or transfered or response or requestQ来做的?/P>