Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
82 views

How To Write Small and Useful Programs: Downloa D Source File S - 3.99 KB

Uploaded by

xenom2
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
82 views

How To Write Small and Useful Programs: Downloa D Source File S - 3.99 KB

Uploaded by

xenom2
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

JavaProject: How to Write Small and Useful Progra...

Languages Java General


(CPOL)

http://java.codeproject.com/KB/java/HowToSmallUs...

License: The Code Project Open License

How to Write Small and Useful


Programs

Java, Windows, Java, Visual Studio,


Dev
Posted: 31 Aug 2005
Updated: 13 Sep 2005
Views: 68,262
Bookmarked: 44 times

By Xiangyang Liu
A tutorial with Java samples

53 votes for this Article.


Popularity: 7.30 Rating: 4.24 out of 5

1 2 3 4 5

Download source file s - 3.99 KB

Introduction
So far I ha ve writte n ove r 40 article s on The C ode Proje ct, m ost of the m are about tools
and softwa re com pone nts I de ve lope d. I a m not good at e x plaining and te a ching
com plicate d te chnical stuff, tha t is why m y a rticles stay at the le ve l of "he re is som e
cool code I wrote and look at how e asy it is to use ...". I a dm ire a lot of good write rs
he re a t The C ode Proje ct such as Marc C lifton, Matt Gulle t, and Micha e l Dunn (those a re
just the one s whose nam e s sta rt with M :-).
Today I am going to try som e thing diffe re nt, that is, write an article tha t aim s at
te a ching othe rs how to progra m . But what can I te a ch? I find m ost book s and le cture s
about com puting te chnology boring and avoid the m as m uch as I ca n. As a re sult, I
don't ha ve solid de ta ile d k nowle dge of the ne w and popular te chnologie s. I don't e ve n
have a basic unde rstanding of som e popular te rm s and catchy phrase s. Som e tim e s I
think those te rm s we re inve nte d to confuse ordinary pe ople in orde r to se ll m ore
products and se rvice s. He re is a funny e x change be twe e n the De te ctive and Dr. C alvin
in the m ovie iR obot.
De te ctive : So, wha t do you do around he re ?
Dr. C alvin: My ge ne ra l fie lds are advance d robotics and psychiatry although I
spe cialize in hardware -to-we tware inte rface s in a n e ffort to advance U.S.R .'s
anthropom orphization program .
De te ctive : So, wha t e x actly do you do around he re ?
Dr. C alvin: I m ak e the robots se e m m ore hum an.
De te ctive : Now wasn't that e asie r to say?
Dr. C alvin: Not re a lly. No.
I am not sa ying that popular te rm s and catchy phrase s are use le ss, the y are just not
tha t use ful in solving re al world program m ing proble m s. I think I do k now how to write

1 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

use ful program s. At m y work place , I have a re putation of be ing able to produce
long-la sting code . W e are consta ntly fix ing/upgrading/re writing our applications, but a
lot of code I wrote (som e are from 5 ye ars a go) are still be ing use d without any
significant change . O f course , for pe ople who don't lik e m y code , the y can always sa y
m y code is so bad tha t nobody wa nts to touch it.
Lik e m a ny pe ople ha ve said, program m ing is not an ex act scie nce , it is m ore lik e an
art. To be succe ssful in program m ing, you ne e d a com bination of tale nt, e x pe rie nce ,
pe rsiste nce , a nd m ost of a ll, a lot of com m on se nse. Spe ak ing of com m on se nse , I
lik e the following C hine se idiom s:
Be lie ving e ve rything in book s is worse than not re ading any book .
A te ache r can only ge t a stude nt starte d to le arn, it is up to the stude nt to finish
the le arning.
Black cat or white cat, the one that catche s m ice is the good cat.
The above are just som e com m on se nse we should have. Many progra m m e rs and
m a nage rs a re bad be cause the y don't use m uch com m on se nse in the ir work . Solving
progra m m ing proble m s is no diffe re nt tha n solving othe r proble m s in life , you use
whate ve r is available to you and the re is no point in re stricting yourse lf to som e artificia l
patte rns or popular te chnologie s just to prove to othe rs that you k now the m . I would
pre fe r to attack the proble m dire ctly inste ad of spe nding a lot of tim e and e ne rgy on
abstractions/fra m e work s in orde r to fit the final solution into som e we ll-k nown de sign
patte rn. O ne thing I hate whe n re ading som e te x tbook -lik e code is that alm ost all the
m e thods call som e othe r m e thods, it is ve ry hard to find a m e thod that actually doe s
the re al work . Don't ge t m e wrong, abstraction has its use , that doe sn't m e an you m ust
use it e ve rywhe re . In his Kong Fu m ovie , Bruce Le e te ache s his stude nts to hit the
targe t dire ctly inste ad of da ncing around. Gre at m inds think alik e , don't you agre e ? :-)
I lik e "se rvice orie nte d archite cture ". I think it is just lik e the old tim e s whe n you write a
function to solve a proble m , e x ce pt the function is now a "se rvice " and it can pote ntially
be use d by m ore program s. I m ay be com ple te ly wrong about what e x a ctly "se rvice
orie nte d archite cture " is, who care s.
In this article , I a m going to use two Java classe s as e x am ple s. W hy Java? You m ay
ask (com e on, don't te ll m e you lik e C # synta x be tte r than Java syntax ). I wrote sim ilar
code first in C ++ and VB the n in VB.NET and C #. I ha ve n't use d Java for a while , it is a
good opportunity for m e to e nhance what I did be fore and to pick up things I ha ve
alre ady forgotte n.
Be fore I go into spe cifics, I would lik e to state that the program s I am talk ing about
he re a re not large fra m e work s or librarie s that are inte nde d for the use rs to e x pa nd
(such as .NET or Java Fram e work ). My inte re st is in de ve loping sm all re usable
com pone nts or utilitie s. All the m e thods in the sam ple classe s of this article a re "final"
which m e ans that use rs are suppose d to use the m without ove rriding (but you can
cha nge whate ve r you want in the code ). Building large fram e work s and librarie s re quire
diffe re nt approache s, of course .
Disclaimer: It goe s without saying that m y ide as and m e thods m ay be incorre ct,

2 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

m isle ading, or e ve n offe nsive . I k now it is alre ady too late for the disclaim e r.

A Class to Write Log Files


The first of m y two Java classe s is XYTrace , it is for writing application inform a tion into
log file s. It is inte nde d to be use d for both de ve lopm e nt a nd production e nvironm e nts.
Be fore I be gin the ne x t se nte nce , som e we ll-inform ed re a de rs will te ll m e that the re
alre ady e x ist a lot of com m e rcial a nd fre e software tools for doing the sam e thing, why
would I bothe r to re inve nt the whe e l? Le t m e give you m y re asons, if I cannot convince
you, that is too bad.
The e x isting software tools and pa ck a ge s for logging m a y be m ore fle x ible and
powe rful. For e x am ple , the y m a y a llow you to write log m e ssa ge s into diffe re nt k inds of
m e dia , such as W indows Eve nt Vie we r or your m othe r's ce ll phone or your siste r's iPod,
be side s sim ple te x t file s. Howe ve r, are the se e x tra fe ature s re ally use ful? For m yse lf, I
have ne ve r se e n the ne e d to write tra ce inform a tion into anything e lse othe r than
sim ple te x t file s. Tools with too m a ny fe ature s are usually harde r to le arn and use .
I would lik e a sm all se lf-containe d class for this purpose . Use rs should be able to use it
without m uch le arning and it should not de pe nd on som e e x te rnal librarie s (e x ce pt the
Java run-tim e e nvironm e nt, of course ). I would lik e to include e nough use ful fe ature s
and at the sam e tim e k e e p the de sign sim ple . R e m e m be r, it is ne ve r hard to produce
a com plicate d de sign, the cha lle nge is to com e up with a de sign tha t m ak e s
com plicate d stuff look sim ple .
The Class Interface
Afte r som e "e x te nsive " re se a rch and analysis, I de cide d that the ba sic inte rface of m y
XYTrace class should be the following two public static m e thods:
final public static void SetTraceOptions
(String sTraceFolderPath, String sAppName, int nAppTraceLevel, int nCleanupDays);
final public static void WriteTrace(int nTraceLevel, String sMessage);

W hat? Two static m e thods? That's it? Ye s, that's good e nough for m e . The re a re no
e x ce ptions or e rrors for the se m e thods. The y should work , pe riod. I pre fe r static
m e thods be cause I think in this ca se it is unnatural to cre ate a n insta nce of the class
the n use it: why should we cre ate anything if we don't ne e d to? Le t m e first list the
fe ature s I wa nt m y class to have .
1. Use rs can ca ll the WriteTrace m e thod dire ctly to write any string m e ssage into
a log file in the curre nt work ing dire ctory, no initializa tion or configuration is
re quire d. The m e ssage he ade r in the log file will include a tim e stam p, a num be r
indicating the se riousne ss of the m e ssage (trace leve l), a nd a num be r ide ntifying
the curre nt thre a d.
2. The re will be one log file pe r proce ss pe r day with som e e x ce ptions e x plaine d
late r. The log file na m e will contain a date -tim e stam p so that you k now e x a ctly
whe n it was cre ate d. The size of the log file won't ge t too big. O ld log file s will be

3 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

de le te d autom atically.
3. You can dynam ica lly de te rm ine whe re to cre ate the log file and how m uch
inform ation is writte n to the log file by calling the SetTraceOptions m e thod.
4. Thre ad-safe ty and re asonable pe rform ance .
A pplication Trace Level
This is a private static inte ge r m e m be r of the class. It de te rm ine s how m uch tra ce
inform ation is writte n to the log file at run-tim e . I only use five diffe re nt value s: 0 for
no tracing, 10 for e rror m e ssage s only; 20 for e rror m e ssage s plus warning m e ssage s;
30 for e rror, warning, a nd som e a dditional inform ation; 40 for the m ost de taile d tracing
which include s de bugging m e ssage s and all pre viously m e ntione d m e ssa ge s.
If you pre fe r, you can use othe r positive inte ge rs a s the value for application trace
le ve l. The de fault application trace le ve l is 40 . The a pplication trace le ve l inte racts with
the first pa ra m e te r in the WriteTrace m e thod. The only way to m odify this value is
calling the SetTraceOptions m e thod. For e x am ple , you can ha ve the following
state m e nts in your code :
XYTrace.WriteTrace(10,
XYTrace.WriteTrace(20,
XYTrace.WriteTrace(30,
XYTrace.WriteTrace(40,

"This
"This
"This
"This

is
is
is
is

an error message");
a warning message");
just a normal message");
a debugging message");

If the application trace le ve l is 0 , the n none of the above state m e nts will ge ne rate a
m e ssage in the log file . If the a pplication trace le ve l is 10 , the n only the first state m e nt
will ge ne rate a m e ssa ge in the log file . If the application tra ce le ve l is 40 , the n all of
the above state m e nts will ge ne rate m e ssage s in the log file .
Descriptions of the Methods
Now I am going to give m ore de taile d de scriptions of the se two static m e thods a nd
the ir para m e te rs.
The SetTraceOptions m e thod ha s four para m e te rs:

sTraceFolderPath
sAppName
nAppTraceLevel
nCleanupDays
The value of sTraceFolderPath de te rm ine s whe re the log file s should be cre ate d. In
case this m e thod is not calle d or the spe cifie d folde r doe s not e x ist, log file s will be
cre ate d in the curre nt work ing folde r of the application proce ss.

sAppName is a string tha t is going to be pa rt of the log file nam e (in addition to the
tim e stam p) so tha t if we store log file s of diffe re nt a pplication proce sse s in the sam e
folde r, it will be cle ar which log file be longs to which application.

4 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

nAppTraceLevel is the application trace le ve l de scribe d above , the de fault value of


application tra ce le ve l is 40 .
nCleanupDays is the num be r of da ys be fore old log file s ge t de lete d. If this value is
0 , the n old log file s won't be de le te d. The de fault value for this prope rty is 3 , if you
don't call SetTraceOptions m e thod.
Log file s a re just sim ple te x t file s that ca n be vie we d in Note pad or othe r sim ple te x t
vie we rs/e ditors. Typically, this class cre ate s one log file pe r proce ss pe r day. If the
application is re starte d, a ne w log file will be cre ate d. C alling the SetTraceOptions
m e thod while the applica tion is running will also close the old log file and cre ate a ne w
one . I re com m e nd that this m e thod be calle d only once at the be ginning of the
application. If you don't ca ll this m e thod at all, the n de fault va lue s will be use d for all
the options. Anothe r situation whe re a ne w log file will be cre ate d is whe n the size of the
curre nt log file e x ce e ds 10 m e ga byte s.
The WriteTrace m e thod ha s two pa ram e te rs:

nTraceLevel
sMessage
The first one is the inte nde d tra ce le ve l which inte ra cts with the application trace le ve l to
de te rm ine whe the r or not the m e ssage is actua lly writte n to the log file . Error m e ssa ge s
should have a lowe r trace le ve l (say 10 ) a nd de taile d de bug m e ssage s should have a
highe r tra ce le ve l (say 40 ).
The se cond para m e te r is the m e ssage string . Me ssa ge s writte n by the above
state m e nts look lik e the following:
072800000_1_10:
072801000_1_20:
072802000_1_30:
072803000_1_40:

This
This
This
This

is
is
is
is

an error message
a warning message
just a normal message
a debugging message

Ple ase note tha t the first pa rt (9 digit num be r) of the m e ssage is a tim e stam p in the
"hour m inute se cond m illise cond" form at. The ne x t num be r is the thre ad id, and the n
the inte nde d trace le ve l. So we k now the first of the above m e ssage s was writte n at
07:28:00, the se cond at 07:28:01, ..., and all of the above m e ssage s we re writte n by
thre ad 1.
Implementation, Enhancement, and Performance
In orde r to im ple m e nt this cla ss, I was force d to add two m ore public m e thods, run
and acce pt.
The run m e thod is for the Java R unnable Inte rfa ce . W ith .NET, you ne e d to use a
ThreadStart delegate to pa ss a m e thod to be invok e d by a ne w thre ad. Java work s
diffe re ntly by passing an obje ct im ple m e nting the Runnable inte rface to a ne w thre ad,

5 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

the ne w thre a d will invok e the run m e thod of the obje ct.
The accept m e thod is for the Java FilenameFilter Inte rfa ce . In Java, the File
class ca n re pre se nt e ithe r a file or a folde r. I use a File obje ct in XYTrace inte rna lly
to re pre se nt the trace folde r. If an instance of the File class is a folde r, the
listFiles m e thod will re turn a list of all file s and subfolders of this folde r. If you pass
an obje ct that im ple m e nts the FilenameFilter Inte rfa ce to the listFiles m e thod,
the n the acce pt m e thod of the obje ct will be invok ed to filte r the file s a nd subfolde rs so
tha t the list re turne d by listFiles will only have the one s you want.
In XYTrace the run m e thod is invok e d by a back ground thre ad that de le te s old log
file s pe riodically, the back ground thre ad will be starte d at m ost once in the life of the
proce ss. The accept m e thod is a lso invok e d (indire ctly) by the back ground thre a d to
m a k e sure that only log file s ge ne rate d by this class will be de le te d (no othe r file s will
be de le te d). Although use rs are ne ve r suppose d to ca ll the se two m e thods e x plicitly,
Java dictate s that the y m ust be public .
I hate any m e thod with m ore than five param e te rs. I think it re fle cts poor de sign in
m a ny case s. If the inform ation you ne e d to use in the code can be obtaine d e lse whe re ,
why bothe r the use rs? To m ak e your program m ore useful, it is be tte r that you m a k e
the obvious de cisions for the use rs inste ad of le tting the m ge t confuse d. It is also a
good practice to provide de fault value s if you do ne e d to have m ore param e te rs and
options. I had a rule for m yse lf to use as fe w pa ram e te rs as possible for m e thods in
m y class. Howe ve r, if adding one or two param e te rs doe s provide conve nie nce to the
use r, the n the rule should be brok e n. That's why I adde d othe r WriteTrace m e thods
with m ore or le ss param e te rs. He re is the list of the additional m e thods:
// we need these because Java does not allow default values for parameters
final public static void WriteTrace(int nTraceLevel, Object oMsg);
final public static void WriteTrace(int nTraceLevel, Object oMsg0, Object oMsg1);
final public static void WriteTrace
(int nTraceLevel, Object oMsg0, Object oMsg1, Object oMsg2);
final public static void WriteTrace
(int nTraceLevel, Object oMsg0, Object oMsg1, Object oMsg2,
Object oMsg3);
final public static void WriteTrace
(int nTraceLevel, Object oMsg0, Object oMsg1, Object oMsg2,
Object oMsg3, Object oMsg4);
final public static void WriteTrace
(int nTraceLevel, Object oMsg0, Object oMsg1, Object oMsg2,
Object oMsg3, Object oMsg4, Object oMsg5);
final public static void WriteTrace(int nTraceLevel, Object[] pMessages);
final public static void WriteTrace(int nTraceLevel, Exception oBug);
final public static void WriteTrace(Exception oBug);

All of the above m e thods a re im ple m e nte d using the original WriteTrace m e thod.
The y allow use rs to write code be low:

6 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

try
{
...
int nUserID = 4;
String sUserName = "James";
// compose a single message from several objects
XYTrace.WriteTrace(40, "ID = ", nUserID, ", Name = ", sUserName");
....
return true;
}
catch(Exception oBug)
{
// Exception object as the only parameter
XYTrace.WriteTrace(oBug);
return false;
}

The two calls to diffe re nt ve rsions of the WriteTrace m e thod in the a bove code will
produce m e ssage s lik e the following:
073200000_1_40: ID = 4, Name = James
...
073201000_1_10: java.sql.SQLException: [Microsoft][ODBC Driver Manager]
Data source name not found and no default driver specified
sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6958)
sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7115)
sun.jdbc.odbc.JdbcOdbc.SQLDriverConnect(JdbcOdbc.java:3074)
sun.jdbc.odbc.JdbcOdbcConnection.initialize(JdbcOdbcConnection.java:323)
sun.jdbc.odbc.JdbcOdbcDriver.connect(JdbcOdbcDriver.java:174)
java.sql.DriverManager.getConnection(DriverManager.java:525)
java.sql.DriverManager.getConnection(DriverManager.java:193)
XYDB.OpenDB(XYDB.java:95)

Ple ase note tha t the se cond call tak e s an Exception obje ct as the only param e te r and
the re sulting log m e ssage include s the sta ck trace of the e x ce ption obje ct.
As for pe rform ance , we can te st the code of the WriteTrace m e thod in a sim ple "for
loop" to se e how m uch tim e on ave rage it tak e s to write a log m e ssa ge , but the re sult
is not m e aningful be cause re a l applica tions ne ve r write log m e ssage s this way.
Howe ve r, we ca n a t le ast do the te st to m ak e sure tha t e x e cuting the code in
WriteTrace will not have any significant im pact on the pe rform ance of m ost re al
applications. He re is the re sult I got, it tak e s 29 se conds on m y com pute r to write 1
m illion log m e ssage s. For those who wonde r, I also te ste d sim ilar VB.NET code on the
sam e m achine , the re sult is 14 se conds. I think we ca n pre tty m uch rule out the
possibility that the WriteTrace state m e nts in your code will drag down pe rform ance .
Error Handling
In this case , the re is not m uch you can or ne e d to do. Think about it, if an e rror occurs
while logging a n e rror m e ssage , whe re and how would you log it? If we le t WriteTrace
fail sile ntly, the worst that can happe n is you don't ge t log m e ssage s writte n and the re
could be (not lik e ly) a slight pe rform a nce hit. In ge ne ral, wha t we ne e d is se nsible e rror

7 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

handling which could m e an no e rror handling at all. W e will com e ba ck to the topic of
e rror handling late r.

A Brief Summary
To sum m arize , he re a re the guide line s and rule s I use to de sign and im ple m e nt sm a ll
use ful program s.
1. Attack proble m s dire ctly. Don't use unnatural abstractions.
2. Ke e p de sign and inte rface sim ple . Ex ce ssive fle x ibility and powe r can hurt
usa bility.
3. R e duce the num be r of pa ram e te rs in your class m e thods.
4. Mak e de cisions for the use rs inste ad of offe ring options that are not e x a ctly
m e aningful or use ful to the m .
5. Se nsible e rror ha ndling.
6. Bre ak the above rule s whe n ne ce ssary.
7. C om m on se nse , com m on se nse , com m on se nse ...
Im a gine that a n O O P ze a lot is de signing the XYTrace class. First, you will have to
cre ate an insta nce of XYTrace using som e k ind of factory class. The param e te r to the
WriteTrace m e thod will be an instance of an abstract TraceMessage class from
which 3 or m ore subclasse s are de rive d; Each of the de rive d cla sse s will ha ve 2 to 5
constructors ta k ing from 3 to 8 pa ra m e te rs; And there will be at le ast 2 custom
e x ce ption classe s to "he lp" use rs to handle e rror conditions. O O P is suppose d to be
fle x ible and e asy to use , in re ality it can be just the opposite if we go too far.

A Class to Access Database


The se cond cla ss is XYDB , it is for acce ssing re lational da tabase s via JDBC. This class is
de signe d and im ple m e nte d according to the sa m e guide line s and rule s e x plaine d
pre viously. Again, I wa nt a se lf-containe d class and it should satisfy all basic database
ne e ds which a re liste d be low.
1.
2.
3.
4.
5.
6.
7.

C onne ct to a ll da tabase s for which JDBC or O DBC drive r is ava ilable


Use dynam ic SQ L state m e nt to que ry or upda te data
C all store d proce dure s to que ry or update data
R e turn data in XML form a t
Pe rform sim ple tra nsactions
Im ple m e nt conne ction pooling
Sim ple e rror ha ndling

The XYDB class is built on top of the classe s in the java.sql pack age which is pa rt of
the standard Java SKD. It doe s not support all possible data type s. Use rs ne e d only to
k now how to write SQ L state m e nts a nd how to use XML, the y don't ne e d to k now de tails
of JDBC or O DBC . The re ason you can use alm ost any O DBC data source with this class
is that a spe cial JDBC drive r calle d jdbc-odbc bridge is include d with the sta ndard Ja va
e nvironm e nt.

8 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

The Class Interface


Le t's discuss the cla ss inte rface . He re is the list of a ll public m e thods in this class:
final public static boolean LoadDriver(String sDriverClass);
final public static XYDB GetDB(String sDBURL);
final public void CloseDB();
final public void ReleaseDB();
final public String ExecuteSQL(String sSQL);
final public String ExecuteSQL(String[] pSQL);
final public String ExecuteSQL(String sSQL, int[] pParamType, Object[] pParamValue);
final public String ExecuteSQLTransaction(String[] pSQL);
final public String CallProc
(String sSQL, String[] pParamName, int[] pParamType, Object[] pParamValue);
final public boolean BeginTrans();
final public boolean CommitTrans();
final public boolean RollbackTrans();
final public Exception GetLastError();

Again, I want this cla ss to be sm all and use ful. I put a lot of thought into the de sign of
the inte rface . Le t's look at the ExecuteSQL m e thod. It is suppose d to be use d for both
que ry a nd update actions.
W hy doe s it re turn a string ? In Ja va, you can use a ResultSet obje ct to hold a
colle ction of database re cords re turne d from a que ry (a ResultSet is sim ilar to a
RecordSet in ADO ). Howe ve r, using the ResultSet class as re turn type m e ans the
use r ha s to k now se ve ra l othe r cla sse s, for e x am ple the Statement class in the
java.sql pack age , in orde r to m a nipulate the re turne d data. It also m e ans the
inte rnal Statement obje ct use d in the im ple m e ntation of the ExecuteSQL m e thod ha s
to be k e pt ope n (cannot be close d im m e diate ly a fte r the que ry). Things ge t e ve n m ore
com plicate d if we want the ExecuteSQL m e thod to be able to re turn m ore than one
re sult se t.
So I de cide d to use string as the re turn type . The re turn value is null if the que ry or
update action fa ils. If the call is succe ssful, the re turn va lue will be an XML string. The
form at of the string look s lik e the following:

9 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

<DataSet>
<Table0>
<Column00>...</Column00>
<Column01>...</Column01>
<Column02>...</Column02>
...
</Table0>
<Table0>
<Column00>...</Column00>
<Column01>...</Column01>
<Column02>...</Column02>
...
</Table0>
...
<Table1>
<Column10>...</Column10>
<Column11>...</Column11>
<Column12>...</Column12>
...
</Table1>
<Table1>
<Column10>...</Column10>
<Column11>...</Column11>
<Column12>...</Column12>
...
</Table1>
...
</DataSet>

Table0 and Table1 re pre se nt re cords from two diffe re nt select que rie s in the SQ L
state m e nt. ColumnXX s a re actual fie ld nam e s in the corre sponding select que ry. As
you can se e , the ExecuteSQL m e thod m ay re turn m ore than one re sult se t de pe nding
on the input SQ L state m e nt and the unde rlying da tabase . W hat if the SQ L state m e nt is
for update only? In tha t ca se , the re turn string will be <DataSet></DateSet> .
R e m e m be r, for any failure the re turn value is null .
If you are fam iliar with the DataSet class in .NET, you will se e that the above XML
string can be use d to populate a DataSet obje ct. So you can write your .NET
application tha t calls anothe r program writte n in Java which use s this class to que ry the
database . O nce you ge t the re turn string , use it to populate a DataSet obje ct a nd
pass the DataSet obje ct to othe r m e thods in your application.
Typically an SQ L state m e nt will only re turn one re sult se t. W ith SQ L Se rve r 2000 a nd
m a y be som e othe r databa se s, you can include two or m ore select state m e nts in one
string and e x e cute the batch to ge t m ore re sult se ts (m ore than one table in the
above XML output). Eve n if the database you are using doe s not support this, you ca n
call a diffe re nt ve rsion of the ExecuteSQL m e thod which ta k e s an array of SQ L
state m e nts as input, the re sult will be as if your database doe s support m ultiple se le cts
in one SQ L state m e nt. For e x am ple , if you k now an em ploye e 's id, you can pass two
SQ L select state m e nts in an a rray to ExecuteSQL , one que rie s the e m ploye e 's
phone num be rs and addre ss (which is store d in the Employee table ) and the othe r

10 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

que rie s the sam e e m ploye e 's pa st salary history (which is store d in the Salary table ).
Anothe r que stion you m ay ask is, why doe s the ExecuteSQL m e thod tak e only the SQ L
state m e nt as param e te r? This re fle cts m y pe rsonal pre fe re nce in writing code to acce ss
database s. If I want to do pa ram e te rize d que ry, I will construct the SQ L state m e nt
using code sim ila r to the following:
String GetData(XYDB oDB, String sParam, int nParam)
{
String sSQL = "select * from MyTable where Col_1 =
'"+sParam.replaceAll("'","''")+"' and Col_2="+nParam;
return oDB.ExecuteSQL(sSQL);
}

Howe ve r, the re is a nothe r ve rsion of the ExecuteSQL m e thod and the CallProc
m e thod in this cla ss tha t can be use d to pass an array of para m e te rs to your SQ L
state m e nt.
Database Connection and Connection Pool
Be fore conne cting to the da taba se , you ne e d to load the corre sponding JDBC drive r.
The following sta te m e nts load Sun's jdbc-odbc bridge a nd Microsoft's JDBC Drive r for
SQ L Se rve r 2000. The static m e thod LoadDriver will re turn true if succe ssful and
false if the drive r class cannot be found.
if(XYDB.LoadDriver("sun.jdbc.odbc.JdbcOdbcDriver")==false)
throw new Exception("Failed to load jdbc-odbc bridge");
if(XYDB.LoadDriver("com.microsoft.jdbc.sqlserver.SQLServerDriver")==false)
throw new Exception("Failed to load JDBC Driver for SQL Server 2000");

Each XYDB obje ct is a physica l conne ction to a data base . The static m e thod GetDB
will re turn an XYDB obje ct for a da taba se conne ction re pre se nte d by the sDBURL
string pa ram e te r, in ca se of failure , it will re turn null .
The form at of the sDBURL param e te r de pe nds on the corre sponding JDBC drive r.
sDBURL is typically m a de up of protocol na m e , com pany nam e, se rve r nam e , port
num be r, data base or data source nam e , use r, and password. To le arn the databa se
UR L form at and JDBC in ge ne ral, I re com m e nd a little book "JDBC Pock e t R e fe re nce "
by Donald Ba le s (publishe d by O 'R e illy), the author should de finite ly write a "How to
write sm all and use ful book s" a rticle on The C ode Proje ct.
He re is an e x a m ple of ge tting a databa se conne ction. If conne ction to the data base
cannot be e sta blishe d, GetDB will re turn null .
XYDB oDB = XYDB.GetDB("jdbc:odbc:MyODBCDataSource;user=MyUser;password=MyPassword");
if(oDB==null) throw new Exception("Failed to connect to database via jdbc-odbc bridge");

Afte r ge tting the XYDB obje ct, you can call its ExecuteSQL m e thod to do que ry or

11 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

update . If you no longe r ne e d the data base conne ction, you can call the CloseDB
m e thod or the ReleaseDB m e thod. CloseDB will close the database conne ction.
ReleaseDB will re turn the conne ction to an inte rnal pool so that it ca n be re use d late r.
That is, GetDB only re turns a brand ne w XYDB obje ct whe n the re is no unuse d
conne ction with the sam e sDBURL param e te r in the inte rnal pool. If you de cide to tak e
advanta ge of the conne ction pool, you should always call ReleaseDB inste ad of
CloseDB .
W e are only talk ing a bout conne ction pooling within the sam e application proce ss he re .
If you want to sha re and re use data base conne ctions am ong diffe re nt applications,
the n you ne e d to build a m ultithre a de d se rve r using this class. O the r applications can
se nd database re que sts to your se rve r via HTTP or soap or TC P protocols. Your se rve r
will que ry and upda te the database and se nd the re sults back to the othe r applications.
This way you ce ntralize d data base acce ss in your serve r and m ade it possible for othe r
applications to share the sam e pool of conne ctions.
Anothe r fe ature I ne e d to m e ntion is that whe ne ve r a data base e rror occurs, XYDB will
close the unde rlying conne ction. And it will a utom atically re conne ct to the database the
ne x t tim e the sam e obje ct is use d. This fe ature does have an im plication whe n you
want to do e x plicit da ta base transaction in your code . I will e x plain it be low.
Simple Database Transactions
If you want to e x e cute a ba tch of SQ L state m e nts in a transaction, you can do one of
the following:
1. Include the SQ L state m e nts in a store d proce dure and use the ExecuteSQL
m e thod to invok e the store d proce dure .
2. Use the ExecuteSQLTransaction m e thod, the re turn data form at is the sam e
as that of ExecuteSQL ( null is re turne d for fa ilure ).
3. C all BeginTrans , ExecuteSQL (one or m ore tim e s), CommitTrans or
RollbackTrans m a nua lly in your code .
Ple ase note that it is ve ry im porta nt to che ck for failure (indicate d by false or null
re turn value s) of the BeginTrans m e thod a nd the ExecuteSQL m e thod if you are
choosing approa ch #3 above . This is be ca use if a data base e rror occurs, the conne ction
will be close d and the transaction will be lost. If you k e e p calling ExecuteSQL
re ga rdle ss of the failure a nd without starting from BeginTrans , the da tabase
conne ction will be re -e sta blishe d and this tim e the SQ L state m e nt will be e x e cute d
outside of any transa ction!
The BeginTrans , CommitTrans , and RollbackTrans m e thods re turn true or false
to indicate succe ss or failure . The y do not support ne ste d transactions.
Error Handling
The XYDB class use s the XYTrace class de scribe d in the first part of the article to log
e rror m e ssa ge s. You ne e d to call the XYTrace.SetTraceOptions m e thod if you don't

12 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

want log file s to be writte n to the curre nt work ing dire ctory of the application proce ss. By
de fault, log file s will be k e pt for 3 days be fore the y are de le te d autom atically. Be side s
basic e rror inform ation (e x ce ption m e ssage and stack trace ), all JDBC da tabase UR L
string s a nd all SQ L state m e nts will be writte n to the log file to he lp in ide ntifying
proble m s.
You m ay have notice d that all m e thods of the XYDB class do not throw any e x ce ption.
The sam e is true for the XYTrace class. Use rs do ne e d to che ck the re turn value to
le arn whe the r a m e thod call has faile d or not. The y also ne e d to look at the log file if
the y want to k now m ore a bout spe cific da tabase e rrors. I think this is be tte r than
throwing e x ce ptions, e spe cially custom e x ce ptions de rive d from the Java Ex ce ption
class. W he n you throw a custom e x ce ption, you put a big burde n on the use rs.
Typically, the re is not m uch the use r can do be sides log the e rror, fail the curre nt
ope ration or ignore the e rror a nd k e e p trying. The y can do the sam e without catching
e x ce ptions. Just in ca se som e use rs want to handle e x ce ptions in the ir code , the
GetLastError m e thod is the re to re turn the last e x ce ption that happe ne d within the
curre nt conne ction.

Final Note
The code include d in this article is writte n with JDK 1.5.0. No sam ple code is provide d to
use the se two classe s. If you cannot figure out how to use it, the n the article or the
code is not we ll-writte n. Ple ase sugge st im prove m e nt ide as. Thank s.

License
This article , along with any a ssociate d source code and file s, is lice nse d unde r The C ode
Proje ct O pe n Lice nse (C PO L)

About the Author


Xiangyang Liu
Location:

United States

Discussions and Feedback


28 messages have be e n poste d for this article . Visit http://java.codeproject.com

13 de 14

03-09-2008 21:04

JavaProject: How to Write Small and Useful Progra...

http://java.codeproject.com/KB/java/HowToSmallUs...

/KB/java/HowToSmallUseful.aspx to post and vie w com m e nts on this article , or click


here to ge t a print vie w with m e ssage s.
PermaLink | Privacy | Terms of Use
Last Updated: 13 Sep 2005
Editor: Deeksha Shenoy

14 de 14

Copyright 2005 by Xiangyang Liu


Everything else Copyright CodeProject, 1999-2008
Java | Advertise on the Code Project

03-09-2008 21:04

You might also like