Step 1: Open Command Prompt
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot -p
Step 2:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hibernatetutorial |
...
The above command shows all the existing databases.
Step 3:
Create new MySQL user
CREATE USER 'sark'@'localhost' IDENTIFIED BY 'sark';
Step 4:
Grant Permissions.
GRANT ALL PRIVILEGES ON *.* TO 'sark'@'localhost' IDENTIFIED BY 'sark' WITH GRANT OPTION;
Step 5:
To check the existing users.
mysql> select User,Host from mysql.user;
+-----------+--------------+
| User | Host |
+-----------+--------------+
| root | % |
| sark | localhost |
+-----------+--------------+
Step 6: To check the Permissions/privileges.
mysql> show grants for sark@localhost;
+-------------------------------------------------------------------------------
-------------------------------------------------------+
| Grants for sark@localhost
|
+-------------------------------------------------------------------------------
-------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'sark'@'localhost' IDENTIFIED B
Y PASSWORD '*A231ED0CF53E6EF33A1A79930EB2A82DB89812F2' |
+-------------------------------------------------------------------------------
-------------------------------------------------------+
Step 6:
Exit from root user and login as 'sark' user;
mysql> exit;
Bye
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -usark -psark
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 43 to server version: 5.0.24-community-nt
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
Step 7:
Create database 'sarkDB'
mysql> CREATE DATABASE sarkDB;
Step 8:
Use Database
mysql> use sarkDB;
Database changed
Step 9:
Create table demo_people.
mysql> CREATE TABLE `demo_people` (
`pid` int(11) NOT NULL,
`name` varchar(20) default NULL,
`phone` int(11) default NULL,
PRIMARY KEY (`pid`)
);
Query OK, 0 rows affected (0.23 sec)
mysql>
Thursday, November 6, 2008
Friday, October 31, 2008
Apache Versus Tomcat
This is a pretty popular question judging from the results on google,so I just wanted to consolidate whatever information I found on the web,which helped me decide.
Apache Http Server comes with other features like Modules configuration, SSL, SSO capabilities etc .
If you use Apache Tomcat,you are restricted to serving jsp's and servlet's.
Clustering: By using Apache as a front end you can let Apache act as a front door to your content to multiple Tomcat instances.so handling the failure of one Tomcat is easier.But you could always use Tomcats Clustering capabilities and a hardware load balancer.Apart from loadbalancing.
Clustering/Security: You can also use Apache as a front door to different Tomcats for different URL namespaces (/app1/, /app2/, /app3/, or virtual hosts). The Tomcats can then be each in a protected area and from a security point of view, you only need to worry about the Apache server. Essentially, Apache becomes a smart proxy server. 2/ (i.e. the capability of reverse proxying, allowing you to 'plug in' one or more web applications running on one or more Tomcat instances in one URL space.)
Security. This topic can sway one either way. Java has the security manager while Apache has a larger mindshare and more tricks with respect to security. But also keep in mind, if you run Apache with Tomcat - you have two systems to defend, not one.
Add-ons. Adding on CGI, perl, PHP is very natural to Apache. Its slower and more of a kludge for Tomcat. Apache also has hundreds of modules that can be plugged in at will.
With Apache in front of Tomcat, you can perform any number of decorators that Tomcat doesn't support or doesn't have the immediate code support.
Speed. Apache is faster at serving static content than Tomcat. But unless you have a high traffic site, this point is useless. But in some scenarios, tomcat can be faster than apache. So benchmark YOUR site. Socket handling/system stability. Apache has better socket handling with respect to error conditions than Tomcat. The main reason is Tomcat must perform all its socket handling via the JVM which needs to be cross platform. The problem is socket optimization is a platform specific ordeal. Most of the time the java code is fine, but when you are also bombarded with dropped connections, invalid packets, invalid requests from invalid IP's, Apache does a better job at dropping these error conditions than JVM based program
Apache Http Server comes with other features like Modules configuration, SSL, SSO capabilities etc .
If you use Apache Tomcat,you are restricted to serving jsp's and servlet's.
Clustering: By using Apache as a front end you can let Apache act as a front door to your content to multiple Tomcat instances.so handling the failure of one Tomcat is easier.But you could always use Tomcats Clustering capabilities and a hardware load balancer.Apart from loadbalancing.
Clustering/Security: You can also use Apache as a front door to different Tomcats for different URL namespaces (/app1/, /app2/, /app3/, or virtual hosts). The Tomcats can then be each in a protected area and from a security point of view, you only need to worry about the Apache server. Essentially, Apache becomes a smart proxy server. 2/ (i.e. the capability of reverse proxying, allowing you to 'plug in' one or more web applications running on one or more Tomcat instances in one URL space.)
Security. This topic can sway one either way. Java has the security manager while Apache has a larger mindshare and more tricks with respect to security. But also keep in mind, if you run Apache with Tomcat - you have two systems to defend, not one.
Add-ons. Adding on CGI, perl, PHP is very natural to Apache. Its slower and more of a kludge for Tomcat. Apache also has hundreds of modules that can be plugged in at will.
With Apache in front of Tomcat, you can perform any number of decorators that Tomcat doesn't support or doesn't have the immediate code support.
Speed. Apache is faster at serving static content than Tomcat. But unless you have a high traffic site, this point is useless. But in some scenarios, tomcat can be faster than apache. So benchmark YOUR site. Socket handling/system stability. Apache has better socket handling with respect to error conditions than Tomcat. The main reason is Tomcat must perform all its socket handling via the JVM which needs to be cross platform. The problem is socket optimization is a platform specific ordeal. Most of the time the java code is fine, but when you are also bombarded with dropped connections, invalid packets, invalid requests from invalid IP's, Apache does a better job at dropping these error conditions than JVM based program
WebServers And Containers Basics
Apache Webserver versus Apache Tomcat is a popular question,and being on the brink of choosing between the two,I started googling,but before I blog what i found,I just wanted to go over the bare basics of webservers,containers and HTTP.For the experienced ones,skip this and go directly to the differences :Apache Versus Tomcat
HTTP
Hypertext Transfer Protocol (HTTP) is a communications protocol used to transfer information on the web. HTTP is a request/response protocol between a client and a server. The client i.e. a web browser or some other end-user tool makes an HTTP request(called the User Agent)(http://www.google.com/ .The responding server which stores or creates resources such as HTML files and images—is called the origin server understands this request and returns the html content specified by the URL. There can be proxies, gateways and tunnels in between the client and the server, but ultimately the server receives and understands the request and sends the requested resources to the client.The server can return pure HTML content/HTML content with scripts embedded within which are understood by the client's web browser and executed on the client appropriately/files.
Typically, an HTTP client initiates a request by establishing a Transmission Control Protocol (TCP) connection to a particular port .An HTTP server listening on that port waits for the client to send a request message.
Upon receiving the request, the server sends back a status line, such as "HTTP/1.1 200 OK", and a message of its own, the body of which is perhaps the requested file, an error message, or some other information.
Resources to be accessed by HTTP are identified using Uniform Resource Identifiers (URIs) or Uniform Resource Locators (URL).
Web Server
A webserver is a piece of software that understands these HTTP requests,and is able to locate the resource that was requested,or atleast some component that will handle the request and return the resource.This is the basic functionality provided by any webserver.But on top of this,the webserver can also provide some services like: Authentication,handling static content and dynamic content(CGI,JSP,PHP,ASP e.t.c),HTTPS support(SSL or TLS) to allow secure encrypted connections to the server on the port 443 instead of 80,Content Compression,Virtual Hosting(Serve many websites using one IP address),Large File Support,Bandwidth throttling.
A basic HTTP webserver only understands HTTP,If we are programming in JSP's and servlets,we need something that understands Servlets and JSP's,the job of a Servlet Container is just that.Consider Apache HTTP Server and Apache Tomcat.The Apache HTTP Server like the name suggests acts as a webserver,Apache Tomcat acts as a webserver and can also understands servlets(A servlet container).So in order to use the Apache Webserver and let it serve jsp's and servlet's we can plug the Apache Tomcat Container into the Apache HTTP Server.
HTTP
Hypertext Transfer Protocol (HTTP) is a communications protocol used to transfer information on the web. HTTP is a request/response protocol between a client and a server. The client i.e. a web browser or some other end-user tool makes an HTTP request(called the User Agent)(http://www.google.com/ .The responding server which stores or creates resources such as HTML files and images—is called the origin server understands this request and returns the html content specified by the URL. There can be proxies, gateways and tunnels in between the client and the server, but ultimately the server receives and understands the request and sends the requested resources to the client.The server can return pure HTML content/HTML content with scripts embedded within which are understood by the client's web browser and executed on the client appropriately/files.
Typically, an HTTP client initiates a request by establishing a Transmission Control Protocol (TCP) connection to a particular port .An HTTP server listening on that port waits for the client to send a request message.
Upon receiving the request, the server sends back a status line, such as "HTTP/1.1 200 OK", and a message of its own, the body of which is perhaps the requested file, an error message, or some other information.
Resources to be accessed by HTTP are identified using Uniform Resource Identifiers (URIs) or Uniform Resource Locators (URL).
Web Server
A webserver is a piece of software that understands these HTTP requests,and is able to locate the resource that was requested,or atleast some component that will handle the request and return the resource.This is the basic functionality provided by any webserver.But on top of this,the webserver can also provide some services like: Authentication,handling static content and dynamic content(CGI,JSP,PHP,ASP e.t.c),HTTPS support(SSL or TLS) to allow secure encrypted connections to the server on the port 443 instead of 80,Content Compression,Virtual Hosting(Serve many websites using one IP address),Large File Support,Bandwidth throttling.
A basic HTTP webserver only understands HTTP,If we are programming in JSP's and servlets,we need something that understands Servlets and JSP's,the job of a Servlet Container is just that.Consider Apache HTTP Server and Apache Tomcat.The Apache HTTP Server like the name suggests acts as a webserver,Apache Tomcat acts as a webserver and can also understands servlets(A servlet container).So in order to use the Apache Webserver and let it serve jsp's and servlet's we can plug the Apache Tomcat Container into the Apache HTTP Server.
Monday, September 22, 2008
Compiling and Running Java Source Files Using EditPlus Tools
There is a way to compile and run your Java source code files without using the command prompt! You can set up some menu options in EditPlus that allow you to quickly compile and run your Java programs. You might want to print these instructions so you can follow these steps. Later we will add a tool or two to this group, so make sure you keep or bookmark these instructions.
Setting up the Tools
Open up EditPlus. It doesn't matter if you have a new/existing document open or not.
To follow these instructions, you need to know the drive and path where you installed your Java SDK. If you followed the default settings, this is probably c:\jdk1.5.0 or c:\Program Files\jdk1.5.0. If you have a different version of the Java SDK, then the folder name might vary slightly. It doesn't matter what it's called, as long as it contains the "bin" folder with all the SDK utilities. In the instructions, this folder will be referred to as the Java SDK folder.
1.Select "Configure User Tools" from the "Tools" menu.
2. You'll see "Groups and Tool Items" in the middle of the dialog box. Tool groups allow you to organize the different tools you want to create and maintain in EditPlus. We are going to create a tool group called "Java Tools".

a.You should see a dialog box like the image shown here. The default group name will probably be "Group 1". To change it, click on the Group Name button.
b. In the New Name text box, type Java Tools
c. Click OK.
d. You should now see "Java Tools" in the pull-down box under the caption "Groups and Tool Items"
3.Now you need to add some tools to your tool group. We'll start with a tool used to compile Java Source code files. If you don't have the Configure User Tools dialog box open, follow step 1 above.
a.Click the Add Tool>>> button and select Program from the pop-up menu.
b.In the Menu Text field, type "Compile Java Source". This is the text you will see in the menu for this tool.
c.Select the program that will run when you select the "Compile Java Source" menu item: Click the small button to the right of the "Command" field.
d.Browse to your Java SDK folder and go into the "bin" subfolder. Find and select the file called JAVAC.EXE. Make sure you select the right file - there are a lot of files in this folder and they have similar names. When you're sure you have the right file, click Open. You should see the path and file information in the "Command" field. Of course you could type this in by hand instead of using the Browse button if you wanted to.
e.When you run the Java compiler, you always give it the name of the source file as an argument. We can set this up for this tool: Click the button to the right of the "Argument" field and select File Name. You should see $(FileName) appear in the field.
f.If you are using Java SDK 1.5 or higher, type -Xlint, followed by a space, in front of $(FileName).
g.Click the button beside the "Initial Directory" field and select File Directory. You should see $(FileDir) appear in the field. This ensures that your compiler runs as if it were in the same folder as your Java source file.
h.Lastly, check off the box for Capture Output. This will show the output to your compile in a small window at the bottom of the screen. If you prefer that the output i.Click the Apply button to save your tool changes

4.The next tool we need to add is for running our Java class files. Again, if you aren't in the configure user tools dialog box, follow step 1 above.
a.Click the Add Tool>>> button and select Program from the pop-up menu.
b.In the Menu Text field, type Run Java Class. This is the text you will see in the menu for this tool.
c.Select the program that will run when you select the "Run Java Class" menu item: Click the small button to the right of the "Command" field.
d.Browse to your Java SDK's /bin folder and select the file called JAVA.EXE. Double check to make sure you have the right file selected, then click Open. You should see the path and file information in the "Command" field.
e.When you use the JAVA command to run a Java class file, you always specify the name of the class file without the extension. We can set this up for this tool: Click the button to the right of the "Argument" field and select File Name without Extension. You should see $(FileNameNoExt) appear in the field.
f.Click the button beside the "Initial Directory" field and select File Directory. You should see $(FileDir) appear in the field. This ensures that the java command interpreter runs as if it were in the same folder as your Java class file.
g.Lastly, check off the box for Capture Output. This will show the output of your program (if any) in the same output window where you see the output to the compile process. If you would rather see the output in a command-prompt window, leave this option unchecked.
h.Click the Apply button to save your tool changes.
To run a program using command-line arguments, set up a new tool menu just like the one in step 3, but make sure you check off the box labeled "Prompt for Arguments". This will cause a dialog box to appear where you can type your command-line arguments (in the exact same format you would type them at the Dos prompt).
You could also check off this box in the tool menu item you created in step 3, and when you run a program that does not require arguments, click the "Skip" button in the arguments dialog.

Dialog box with Run with Arguments settings

Using the Tools
To compile, go to the EditPlus window with the source file you want to compile and select "Compile Java Source" from the Tools menu. If you prefer using the keyboard, you can also compile the current program by pressing the Ctrl-1 keys.
To run a class file, go to the EditPlus window with the source file you want to run (rather, the source file that is associated with the class file you want to run), and select "Run Java Class" from the Tools menu. If you prefer using the keyboard, you can also run the class file by pressing the Ctrl-2 keys.
Note that the keyboard shortcuts may vary if you have already created user tools. You can see what shortcut keys are associated with your tools by looking at your tool menu items in the Tools menu.
Setting up the Tools
Open up EditPlus. It doesn't matter if you have a new/existing document open or not.
To follow these instructions, you need to know the drive and path where you installed your Java SDK. If you followed the default settings, this is probably c:\jdk1.5.0 or c:\Program Files\jdk1.5.0. If you have a different version of the Java SDK, then the folder name might vary slightly. It doesn't matter what it's called, as long as it contains the "bin" folder with all the SDK utilities. In the instructions, this folder will be referred to as the Java SDK folder.
1.Select "Configure User Tools" from the "Tools" menu.
2. You'll see "Groups and Tool Items" in the middle of the dialog box. Tool groups allow you to organize the different tools you want to create and maintain in EditPlus. We are going to create a tool group called "Java Tools".

a.You should see a dialog box like the image shown here. The default group name will probably be "Group 1". To change it, click on the Group Name button.
b. In the New Name text box, type Java Tools
c. Click OK.
d. You should now see "Java Tools" in the pull-down box under the caption "Groups and Tool Items"
3.Now you need to add some tools to your tool group. We'll start with a tool used to compile Java Source code files. If you don't have the Configure User Tools dialog box open, follow step 1 above.
a.Click the Add Tool>>> button and select Program from the pop-up menu.
b.In the Menu Text field, type "Compile Java Source". This is the text you will see in the menu for this tool.
c.Select the program that will run when you select the "Compile Java Source" menu item: Click the small button to the right of the "Command" field.
d.Browse to your Java SDK folder and go into the "bin" subfolder. Find and select the file called JAVAC.EXE. Make sure you select the right file - there are a lot of files in this folder and they have similar names. When you're sure you have the right file, click Open. You should see the path and file information in the "Command" field. Of course you could type this in by hand instead of using the Browse button if you wanted to.
e.When you run the Java compiler, you always give it the name of the source file as an argument. We can set this up for this tool: Click the button to the right of the "Argument" field and select File Name. You should see $(FileName) appear in the field.
f.If you are using Java SDK 1.5 or higher, type -Xlint, followed by a space, in front of $(FileName).
g.Click the button beside the "Initial Directory" field and select File Directory. You should see $(FileDir) appear in the field. This ensures that your compiler runs as if it were in the same folder as your Java source file.
h.Lastly, check off the box for Capture Output. This will show the output to your compile in a small window at the bottom of the screen. If you prefer that the output i.Click the Apply button to save your tool changes

4.The next tool we need to add is for running our Java class files. Again, if you aren't in the configure user tools dialog box, follow step 1 above.
a.Click the Add Tool>>> button and select Program from the pop-up menu.
b.In the Menu Text field, type Run Java Class. This is the text you will see in the menu for this tool.
c.Select the program that will run when you select the "Run Java Class" menu item: Click the small button to the right of the "Command" field.
d.Browse to your Java SDK's /bin folder and select the file called JAVA.EXE. Double check to make sure you have the right file selected, then click Open. You should see the path and file information in the "Command" field.
e.When you use the JAVA command to run a Java class file, you always specify the name of the class file without the extension. We can set this up for this tool: Click the button to the right of the "Argument" field and select File Name without Extension. You should see $(FileNameNoExt) appear in the field.
f.Click the button beside the "Initial Directory" field and select File Directory. You should see $(FileDir) appear in the field. This ensures that the java command interpreter runs as if it were in the same folder as your Java class file.
g.Lastly, check off the box for Capture Output. This will show the output of your program (if any) in the same output window where you see the output to the compile process. If you would rather see the output in a command-prompt window, leave this option unchecked.
h.Click the Apply button to save your tool changes.
To run a program using command-line arguments, set up a new tool menu just like the one in step 3, but make sure you check off the box labeled "Prompt for Arguments". This will cause a dialog box to appear where you can type your command-line arguments (in the exact same format you would type them at the Dos prompt).
You could also check off this box in the tool menu item you created in step 3, and when you run a program that does not require arguments, click the "Skip" button in the arguments dialog.

Dialog box with Run with Arguments settings

Using the Tools
To compile, go to the EditPlus window with the source file you want to compile and select "Compile Java Source" from the Tools menu. If you prefer using the keyboard, you can also compile the current program by pressing the Ctrl-1 keys.
To run a class file, go to the EditPlus window with the source file you want to run (rather, the source file that is associated with the class file you want to run), and select "Run Java Class" from the Tools menu. If you prefer using the keyboard, you can also run the class file by pressing the Ctrl-2 keys.
Note that the keyboard shortcuts may vary if you have already created user tools. You can see what shortcut keys are associated with your tools by looking at your tool menu items in the Tools menu.
Thursday, September 11, 2008
Primitive data types in java
2.4. Primitive Data Types
Java supports eight basic data types known as primitive types. In addition, it supports classes and arrays as composite data types, or reference types. Classes and arrays are documented later in this chapter. The primitive types are: a boolean type, a character type, four integer types, and two floating-point types. The four integer types and the two floating-point types differ in the number of bits that represent them, and therefore in the range of numbers they can represent. Table 2-2 summarizes these primitive data types.
Table 2-2. Java Primitive Data Types
Type Contains Default Size Range
boolean true or false false 1 bit NA
char Unicode character \u0000 16 bits \u0000 to \uFFFF
byte Signed integer 0 8 bits -128 to 127
short Signed integer 0 16 bits -32768 to 32767
int Signed integer 0 32 bits -2147483648 to 2147483647
long Signed integer 0 64 bits -9223372036854775808 to 9223372036854775807
float IEEE 754 floating point
0.0 32 bits ±1.4E-45 to ±3.4028235E+38
double IEEE 754 floating point
0.0 64 bits ±4.9E-324 to ±1.7976931348623157E+308
2.4.1. The boolean Type
The boolean type represents a truth value. There are only two possible values of this type, representing the two boolean states: on or off, yes or no, true or false. Java reserves the words true and false to represent these two boolean values.
C and C++ programmers should note that Java is quite strict about its boolean type: boolean values can never be converted to or from other data types. In particular, a boolean is not an integral type, and integer values cannot be used in place of a boolean. In other words, you cannot take shortcuts such as the following in Java:
if (o) {
while(i) {
}
}Instead, Java forces you to write cleaner code by explicitly stating the comparisons you want:
if (o != null) {
while(i != 0) {
}
}2.4.2. The char Type
The char type represents Unicode characters. It surprises many experienced programmers to learn that Java char values are 16 bits long, but in practice this fact is totally transparent. To include a character literal in a Java program, simply place it between single quotes (apostrophes):
char c = 'A';You can, of course, use any Unicode character as a character literal, and you can use the \u Unicode escape sequence. In addition, Java supports a number of other escape sequences that make it easy both to represent commonly used nonprinting ASCII characters such as newline and to escape certain punctuation characters that have special meaning in Java. For example:
char tab = '\t', apostrophe = '\'', nul = '\000', aleph='\u05D0';Table 2-3 lists the escape characters that can be used in char literals. These characters can also be used in string literals, which are covered later in this chapter.
Table 2-3. Java Escape Characters
Escape Sequence Character Value
\b Backspace
\t Horizontal tab
\n Newline
\f Form feed
\r Carriage return
\" Double quote
\' Single quote
\\ Backslash
\xxx The Latin-1 character with the encoding xxx, where xxx is an octal (base 8) number between 000 and 377. The forms \x and \xx are also legal, as in '\0', but are not recommended because they can cause difficulties in string constants where the escape sequence is followed by a regular digit.
\uxxxx The Unicode character with encoding xxxx, where xxxx is four hexadecimal digits. Unicode escapes can appear anywhere in a Java program, not only in character and string literals.
char values can be converted to and from the various integral types. Unlike byte, short, int, and long, however, char is an unsigned type. The Character class defines a number of useful static methods for working with characters, including isDigit(), isJavaLetter(), isLowerCase(), and toUpperCase().
2.4.3. Integer Types
The integer types in Java are byte, short, int, and long. As shown in Table 2-2, these four types differ only in the number of bits and, therefore, in the range of numbers each type can represent. All integral types represent signed numbers; there is no unsigned keyword as there is in C and C++.
Literals for each of these types are written exactly as you would expect: as a string of decimal digits. Although it is not technically part of the literal syntax, any integer literal can be preceded by the unary minus operator to indicate a negative number. Here are some legal integer literals:
0
1
123
-42000Integer literals can also be expressed in hexadecimal or octal notation. A literal that begins with 0x or 0X is taken as a hexadecimal number, using the letters A to F (or a to f) as the additional digits required for base-16 numbers. Integer literals beginning with a leading 0 are taken to be octal (base-8) numbers and cannot include the digits 8 or 9. Java does not allow integer literals to be expressed in binary (base-2) notation. Legal hexadecimal and octal literals include:
0xff // Decimal 255, expressed in hexadecimal
0377 // The same number, expressed in octal (base 8)
0xCAFEBABE // A magic number used to identify Java class filesInteger literals are 32-bit int values unless they end with the character L or l, in which case they are 64-bit long values:
1234 // An int value
1234L // A long value
0xffL // Another long valueInteger arithmetic in Java is modular, which means that it never produces an overflow or an underflow when you exceed the range of a given integer type. Instead, numbers just wrap around. For example:
byte b1 = 127, b2 = 1; // Largest byte is 127
byte sum = b1 + b2; // Sum wraps to -128, which is the smallest byteNeither the Java compiler nor the Java interpreter warns you in any way when this occurs. When doing integer arithmetic, you simply must ensure that the type you are using has a sufficient range for the purposes you intend. Integer division by zero and modulo by zero are illegal and cause an ArithmeticException to be thrown.
Each integer type has a corresponding wrapper class: Byte, Short, Integer, and Long. Each of these classes defines MIN_VALUE and MAX_VALUE constants that describe the range of the type. The classes also define useful static methods, such as Byte.parseByte() and Integer.parseInt(), for converting strings to integer values.
2.4.4. Floating-Point Types
Real numbers in Java are represented with the float and double data types. As shown in Table 2-3, float is a 32-bit, single-precision floating-point value, and double is a 64-bit, double-precision floating-point value. Both types adhere to the IEEE 754-1985 standard, which specifies both the format of the numbers and the behavior of arithmetic for the numbers.
Floating-point values can be included literally in a Java program as an optional string of digits, followed by a decimal point and another string of digits. Here are some examples:
123.45
0.0
.01Floating-point literals can also use exponential, or scientific, notation, in which a number is followed by the letter e or E (for exponent) and another number. This second number represents the power of ten by which the first number is multiplied. For example:
1.2345E02 // 1.2345 * 10^2, or 123.45
1e-6 // 1 * 10^-6, or 0.000001
6.02e23 // Avagadro's Number: 6.02 * 10^23Floating-point literals are double values by default. To include a float value literally in a program, follow the number by the character f or F:
double d = 6.02E23;
float f = 6.02e23f;Floating-point literals cannot be expressed in hexadecimal or octal notation.
Most real numbers, by their very nature, cannot be represented exactly in any finite number of bits. Thus, it is important to remember that float and double values are only approximations of the numbers they are meant to represent. A float is a 32-bit approximation, which results in at least 6 significant decimal digits, and a double is a 64-bit approximation, which results in at least 15 significant digits. In practice, these data types are suitable for most real-number computations.
In addition to representing ordinary numbers, the float and double types can also represent four special values: positive and negative infinity, zero, and NaN. The infinity values result when a floating-point computation produces a value that overflows the representable range of a float or double. When a floating-point computation underflows the representable range of a float or a double, a zero value results. The Java floating-point types make a distinction between positive zero and negative zero, depending on the direction from which the underflow occurred. In practice, positive and negative zero behave pretty much the same. Finally, the last special floating-point value is NaN, which stands for not-a-number. The NaN value results when an illegal floating-point operation, such as 0/0, is performed. Here are examples of statements that result in these special values:
double inf = 1/0; // Infinity
double neginf = -1/0; // -Infinity
double negzero = -1/inf; // Negative zero
double NaN = 0/0; // NaNBecause the Java floating-point types can handle overflow to infinity and underflow to zero and have a special NaN value, floating-point arithmetic never throws exceptions, even when performing illegal operations, like dividing zero by zero or taking the square root of a negative number.
The float and double primitive types have corresponding classes, named Float and Double. Each of these classes defines the following useful constants: MIN_VALUE, MAX_VALUE, NEGATIVE_INFINITY, POSITIVE_INFINITY, and NaN.
The infinite floating-point values behave as you would expect. Adding or subtracting anything to or from infinity, for example, yields infinity. Negative zero behaves almost identically to positive zero, and, in fact, the = = equality operator reports that negative zero is equal to positive zero. The only way to distinguish negative zero from positive, or regular, zero is to divide by it. 1/0 yields positive infinity, but 1 divided by negative zero yields negative infinity. Finally, since NaN is not-a-number, the = = operator says that it is not equal to any other number, including itself ! To check whether a float or double value is NaN, you must use the Float.isNan() and Double.isNan() methods.
2.4.5. Strings
In addition to the boolean, character, integer, and floating-point data types, Java also has a data type for working with strings of text (usually simply called strings). The String type is a class, however, and is not one of the primitive types of the language. Because strings are so commonly used, though, Java does have a syntax for including string values literally in a program. A String literal consists of arbitrary text within double quotes. For example:
"Hello, world"
"'This' is a string!"String literals can contain any of the escape sequences that can appear as char literals (see Table 2-3). Use the \" sequence to include a double-quote within a String literal. Strings and string literals are discussed in more detail later in this chapter. Chapter 4, "The Java Platform", demonstrates some of the ways you can work with String objects in Java.
2.4.6. Type Conversions
Java allows conversions between integer values and floating-point values. In addition, because every character corresponds to a number in the Unicode encoding, char types can be converted to and from the integer and floating-point types. In fact, boolean is the only primitive type that cannot be converted to or from another primitive type in Java.
There are two basic types of conversions. A widening conversion occurs when a value of one type is converted to a wider type--one that is represented with more bits and therefore has a wider range of legal values. A narrowing conversion occurs when a value is converted to a type that is represented with fewer bits. Java performs widening conversions automatically when, for example, you assign an int literal to a double variable or a char literal to an int variable.
Narrowing conversions are another matter, however, and are not always safe. It is reasonable to convert the integer value 13 to a byte, for example, but it is not reasonable to convert 13000 to a byte, since byte can only hold numbers between -128 and 127. Because you can lose data in a narrowing conversion, the Java compiler complains when you attempt any narrowing conversion, even if the value being converted would in fact fit in the narrower range of the specified type:
int i = 13;
byte b = i; // The compiler does not allow thisThe one exception to this rule is that you can assign an integer literal (an int value) to a byte or short variable, if the literal falls within the range of the variable.
If you need to perform a narrowing conversion and are confident you can do so without losing data or precision, you can force Java to perform the conversion using a language construct known as a cast. Perform a cast by placing the name of the desired type in parentheses before the value to be converted. For example:
int i = 13;
byte b = (byte) i; // Force the int to be converted to a byte
i = (int) 13.456; // Force this double literal to the int 13Casts of primitive types are most often used to convert floating-point values to integers. When you do this, the fractional part of the floating-point value is simply truncated (i.e., the floating-point value is rounded towards zero, not towards the nearest integer). The methods Math.round(), Math.floor(), and Math.ceil() perform other types of rounding.
The char type acts like an integer type in most ways, so a char value can be used anywhere an int or long value is required. Recall, however, that the char type is unsigned, so it behaves differently than the short type, even though both of them are 16 bits wide:
short s = (short) 0xffff; // These bits represent the number -1
char c = '\uffff'; // The same bits, representing a Unicode character
int i1 = s; // Converting the short to an int yields -1
int i2 = c; // Converting the char to an int yields 65535
Table 2-4 is a grid that shows which primitive types can be converted to which other types and how the conversion is performed. The letter N in the table means that the conversion cannot be performed. The letter Y means that the conversion is a widening conversion and is therefore performed automatically and implicitly by Java. The letter C means that the conversion is a narrowing conversion and requires an explicit cast. Finally, the notation Y* means that the conversion is an automatic widening conversion, but that some of the least significant digits of the value may be lost by the conversion. This can happen when converting an int or long to a float or double. The floating-point types have a larger range than the integer types, so any int or long can be represented by a float or double. However, the floating-point types are approximations of numbers and cannot always hold as many significant digits as the integer types.
Table 2-4. Java Primitive Type Conversions
Convert Convert To:
From: boolean byte short char int long float double
boolean - N N N N N N N
byte N - Y C Y Y Y Y
short N C - C Y Y Y Y
char N C C - Y Y Y Y
int N C C C - Y Y* Y
long N C C C C - Y* Y*
float N C C C C C - Y
double N C C C C C C -
2.4.7. Reference Types
In addition to its eight primitive types, Java defines two additional categories of data types: classes and arrays. Java programs consist of class definitions; each class defines a new data type that can be manipulated by Java programs. For example, a program might define a class named Point and use it to store and manipulate X,Y points in a Cartesian coordinate system. This makes Point a new data type in that program. An array type represents a list of values of some other type. char is a data type, and an array of char values is another data type, written char[]. An array of Point objects is a data type, written Point[]. And an array of Point arrays is yet another type, written Point[][].
As you can see, there are an infinite number of possible class and array data types. Collectively, these data types are known as reference types. The reason for this name will become clear later in this chapter. For now, however, what is important to understand is that class and array types differ significantly from primitive types, in that they are compound, or composite, types. A primitive data type holds exactly one value. Classes and arrays are aggregate types that contain multiple values. The Point type, for example, holds two double values representing the X and Y coordinates of the point. And char[] is obviously a compound type because it represents a list of characters. By their very nature, class and array types are more complicated than the primitive data types. We'll discuss classes and arrays in detail later in this chapter and examine classes in even more detail in Chapter 3, "Object-Oriented Programming in Java".
Java supports eight basic data types known as primitive types. In addition, it supports classes and arrays as composite data types, or reference types. Classes and arrays are documented later in this chapter. The primitive types are: a boolean type, a character type, four integer types, and two floating-point types. The four integer types and the two floating-point types differ in the number of bits that represent them, and therefore in the range of numbers they can represent. Table 2-2 summarizes these primitive data types.
Table 2-2. Java Primitive Data Types
Type Contains Default Size Range
boolean true or false false 1 bit NA
char Unicode character \u0000 16 bits \u0000 to \uFFFF
byte Signed integer 0 8 bits -128 to 127
short Signed integer 0 16 bits -32768 to 32767
int Signed integer 0 32 bits -2147483648 to 2147483647
long Signed integer 0 64 bits -9223372036854775808 to 9223372036854775807
float IEEE 754 floating point
0.0 32 bits ±1.4E-45 to ±3.4028235E+38
double IEEE 754 floating point
0.0 64 bits ±4.9E-324 to ±1.7976931348623157E+308
2.4.1. The boolean Type
The boolean type represents a truth value. There are only two possible values of this type, representing the two boolean states: on or off, yes or no, true or false. Java reserves the words true and false to represent these two boolean values.
C and C++ programmers should note that Java is quite strict about its boolean type: boolean values can never be converted to or from other data types. In particular, a boolean is not an integral type, and integer values cannot be used in place of a boolean. In other words, you cannot take shortcuts such as the following in Java:
if (o) {
while(i) {
}
}Instead, Java forces you to write cleaner code by explicitly stating the comparisons you want:
if (o != null) {
while(i != 0) {
}
}2.4.2. The char Type
The char type represents Unicode characters. It surprises many experienced programmers to learn that Java char values are 16 bits long, but in practice this fact is totally transparent. To include a character literal in a Java program, simply place it between single quotes (apostrophes):
char c = 'A';You can, of course, use any Unicode character as a character literal, and you can use the \u Unicode escape sequence. In addition, Java supports a number of other escape sequences that make it easy both to represent commonly used nonprinting ASCII characters such as newline and to escape certain punctuation characters that have special meaning in Java. For example:
char tab = '\t', apostrophe = '\'', nul = '\000', aleph='\u05D0';Table 2-3 lists the escape characters that can be used in char literals. These characters can also be used in string literals, which are covered later in this chapter.
Table 2-3. Java Escape Characters
Escape Sequence Character Value
\b Backspace
\t Horizontal tab
\n Newline
\f Form feed
\r Carriage return
\" Double quote
\' Single quote
\\ Backslash
\xxx The Latin-1 character with the encoding xxx, where xxx is an octal (base 8) number between 000 and 377. The forms \x and \xx are also legal, as in '\0', but are not recommended because they can cause difficulties in string constants where the escape sequence is followed by a regular digit.
\uxxxx The Unicode character with encoding xxxx, where xxxx is four hexadecimal digits. Unicode escapes can appear anywhere in a Java program, not only in character and string literals.
char values can be converted to and from the various integral types. Unlike byte, short, int, and long, however, char is an unsigned type. The Character class defines a number of useful static methods for working with characters, including isDigit(), isJavaLetter(), isLowerCase(), and toUpperCase().
2.4.3. Integer Types
The integer types in Java are byte, short, int, and long. As shown in Table 2-2, these four types differ only in the number of bits and, therefore, in the range of numbers each type can represent. All integral types represent signed numbers; there is no unsigned keyword as there is in C and C++.
Literals for each of these types are written exactly as you would expect: as a string of decimal digits. Although it is not technically part of the literal syntax, any integer literal can be preceded by the unary minus operator to indicate a negative number. Here are some legal integer literals:
0
1
123
-42000Integer literals can also be expressed in hexadecimal or octal notation. A literal that begins with 0x or 0X is taken as a hexadecimal number, using the letters A to F (or a to f) as the additional digits required for base-16 numbers. Integer literals beginning with a leading 0 are taken to be octal (base-8) numbers and cannot include the digits 8 or 9. Java does not allow integer literals to be expressed in binary (base-2) notation. Legal hexadecimal and octal literals include:
0xff // Decimal 255, expressed in hexadecimal
0377 // The same number, expressed in octal (base 8)
0xCAFEBABE // A magic number used to identify Java class filesInteger literals are 32-bit int values unless they end with the character L or l, in which case they are 64-bit long values:
1234 // An int value
1234L // A long value
0xffL // Another long valueInteger arithmetic in Java is modular, which means that it never produces an overflow or an underflow when you exceed the range of a given integer type. Instead, numbers just wrap around. For example:
byte b1 = 127, b2 = 1; // Largest byte is 127
byte sum = b1 + b2; // Sum wraps to -128, which is the smallest byteNeither the Java compiler nor the Java interpreter warns you in any way when this occurs. When doing integer arithmetic, you simply must ensure that the type you are using has a sufficient range for the purposes you intend. Integer division by zero and modulo by zero are illegal and cause an ArithmeticException to be thrown.
Each integer type has a corresponding wrapper class: Byte, Short, Integer, and Long. Each of these classes defines MIN_VALUE and MAX_VALUE constants that describe the range of the type. The classes also define useful static methods, such as Byte.parseByte() and Integer.parseInt(), for converting strings to integer values.
2.4.4. Floating-Point Types
Real numbers in Java are represented with the float and double data types. As shown in Table 2-3, float is a 32-bit, single-precision floating-point value, and double is a 64-bit, double-precision floating-point value. Both types adhere to the IEEE 754-1985 standard, which specifies both the format of the numbers and the behavior of arithmetic for the numbers.
Floating-point values can be included literally in a Java program as an optional string of digits, followed by a decimal point and another string of digits. Here are some examples:
123.45
0.0
.01Floating-point literals can also use exponential, or scientific, notation, in which a number is followed by the letter e or E (for exponent) and another number. This second number represents the power of ten by which the first number is multiplied. For example:
1.2345E02 // 1.2345 * 10^2, or 123.45
1e-6 // 1 * 10^-6, or 0.000001
6.02e23 // Avagadro's Number: 6.02 * 10^23Floating-point literals are double values by default. To include a float value literally in a program, follow the number by the character f or F:
double d = 6.02E23;
float f = 6.02e23f;Floating-point literals cannot be expressed in hexadecimal or octal notation.
Most real numbers, by their very nature, cannot be represented exactly in any finite number of bits. Thus, it is important to remember that float and double values are only approximations of the numbers they are meant to represent. A float is a 32-bit approximation, which results in at least 6 significant decimal digits, and a double is a 64-bit approximation, which results in at least 15 significant digits. In practice, these data types are suitable for most real-number computations.
In addition to representing ordinary numbers, the float and double types can also represent four special values: positive and negative infinity, zero, and NaN. The infinity values result when a floating-point computation produces a value that overflows the representable range of a float or double. When a floating-point computation underflows the representable range of a float or a double, a zero value results. The Java floating-point types make a distinction between positive zero and negative zero, depending on the direction from which the underflow occurred. In practice, positive and negative zero behave pretty much the same. Finally, the last special floating-point value is NaN, which stands for not-a-number. The NaN value results when an illegal floating-point operation, such as 0/0, is performed. Here are examples of statements that result in these special values:
double inf = 1/0; // Infinity
double neginf = -1/0; // -Infinity
double negzero = -1/inf; // Negative zero
double NaN = 0/0; // NaNBecause the Java floating-point types can handle overflow to infinity and underflow to zero and have a special NaN value, floating-point arithmetic never throws exceptions, even when performing illegal operations, like dividing zero by zero or taking the square root of a negative number.
The float and double primitive types have corresponding classes, named Float and Double. Each of these classes defines the following useful constants: MIN_VALUE, MAX_VALUE, NEGATIVE_INFINITY, POSITIVE_INFINITY, and NaN.
The infinite floating-point values behave as you would expect. Adding or subtracting anything to or from infinity, for example, yields infinity. Negative zero behaves almost identically to positive zero, and, in fact, the = = equality operator reports that negative zero is equal to positive zero. The only way to distinguish negative zero from positive, or regular, zero is to divide by it. 1/0 yields positive infinity, but 1 divided by negative zero yields negative infinity. Finally, since NaN is not-a-number, the = = operator says that it is not equal to any other number, including itself ! To check whether a float or double value is NaN, you must use the Float.isNan() and Double.isNan() methods.
2.4.5. Strings
In addition to the boolean, character, integer, and floating-point data types, Java also has a data type for working with strings of text (usually simply called strings). The String type is a class, however, and is not one of the primitive types of the language. Because strings are so commonly used, though, Java does have a syntax for including string values literally in a program. A String literal consists of arbitrary text within double quotes. For example:
"Hello, world"
"'This' is a string!"String literals can contain any of the escape sequences that can appear as char literals (see Table 2-3). Use the \" sequence to include a double-quote within a String literal. Strings and string literals are discussed in more detail later in this chapter. Chapter 4, "The Java Platform", demonstrates some of the ways you can work with String objects in Java.
2.4.6. Type Conversions
Java allows conversions between integer values and floating-point values. In addition, because every character corresponds to a number in the Unicode encoding, char types can be converted to and from the integer and floating-point types. In fact, boolean is the only primitive type that cannot be converted to or from another primitive type in Java.
There are two basic types of conversions. A widening conversion occurs when a value of one type is converted to a wider type--one that is represented with more bits and therefore has a wider range of legal values. A narrowing conversion occurs when a value is converted to a type that is represented with fewer bits. Java performs widening conversions automatically when, for example, you assign an int literal to a double variable or a char literal to an int variable.
Narrowing conversions are another matter, however, and are not always safe. It is reasonable to convert the integer value 13 to a byte, for example, but it is not reasonable to convert 13000 to a byte, since byte can only hold numbers between -128 and 127. Because you can lose data in a narrowing conversion, the Java compiler complains when you attempt any narrowing conversion, even if the value being converted would in fact fit in the narrower range of the specified type:
int i = 13;
byte b = i; // The compiler does not allow thisThe one exception to this rule is that you can assign an integer literal (an int value) to a byte or short variable, if the literal falls within the range of the variable.
If you need to perform a narrowing conversion and are confident you can do so without losing data or precision, you can force Java to perform the conversion using a language construct known as a cast. Perform a cast by placing the name of the desired type in parentheses before the value to be converted. For example:
int i = 13;
byte b = (byte) i; // Force the int to be converted to a byte
i = (int) 13.456; // Force this double literal to the int 13Casts of primitive types are most often used to convert floating-point values to integers. When you do this, the fractional part of the floating-point value is simply truncated (i.e., the floating-point value is rounded towards zero, not towards the nearest integer). The methods Math.round(), Math.floor(), and Math.ceil() perform other types of rounding.
The char type acts like an integer type in most ways, so a char value can be used anywhere an int or long value is required. Recall, however, that the char type is unsigned, so it behaves differently than the short type, even though both of them are 16 bits wide:
short s = (short) 0xffff; // These bits represent the number -1
char c = '\uffff'; // The same bits, representing a Unicode character
int i1 = s; // Converting the short to an int yields -1
int i2 = c; // Converting the char to an int yields 65535
Table 2-4 is a grid that shows which primitive types can be converted to which other types and how the conversion is performed. The letter N in the table means that the conversion cannot be performed. The letter Y means that the conversion is a widening conversion and is therefore performed automatically and implicitly by Java. The letter C means that the conversion is a narrowing conversion and requires an explicit cast. Finally, the notation Y* means that the conversion is an automatic widening conversion, but that some of the least significant digits of the value may be lost by the conversion. This can happen when converting an int or long to a float or double. The floating-point types have a larger range than the integer types, so any int or long can be represented by a float or double. However, the floating-point types are approximations of numbers and cannot always hold as many significant digits as the integer types.
Table 2-4. Java Primitive Type Conversions
Convert Convert To:
From: boolean byte short char int long float double
boolean - N N N N N N N
byte N - Y C Y Y Y Y
short N C - C Y Y Y Y
char N C C - Y Y Y Y
int N C C C - Y Y* Y
long N C C C C - Y* Y*
float N C C C C C - Y
double N C C C C C C -
2.4.7. Reference Types
In addition to its eight primitive types, Java defines two additional categories of data types: classes and arrays. Java programs consist of class definitions; each class defines a new data type that can be manipulated by Java programs. For example, a program might define a class named Point and use it to store and manipulate X,Y points in a Cartesian coordinate system. This makes Point a new data type in that program. An array type represents a list of values of some other type. char is a data type, and an array of char values is another data type, written char[]. An array of Point objects is a data type, written Point[]. And an array of Point arrays is yet another type, written Point[][].
As you can see, there are an infinite number of possible class and array data types. Collectively, these data types are known as reference types. The reason for this name will become clear later in this chapter. For now, however, what is important to understand is that class and array types differ significantly from primitive types, in that they are compound, or composite, types. A primitive data type holds exactly one value. Classes and arrays are aggregate types that contain multiple values. The Point type, for example, holds two double values representing the X and Y coordinates of the point. And char[] is obviously a compound type because it represents a list of characters. By their very nature, class and array types are more complicated than the primitive data types. We'll discuss classes and arrays in detail later in this chapter and examine classes in even more detail in Chapter 3, "Object-Oriented Programming in Java".
Tuesday, July 22, 2008
Core J2EE Patterns - Data Access Object
Context
Access to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (relational databases, object-oriented databases, flat files, and so forth) and the vendor implementation.
Problem
Many real-world Java 2 Platform, Enterprise Edition (J2EE) applications need to use persistent data at some point. For many applications, persistent storage is implemented with different mechanisms, and there are marked differences in the APIs used to access these different persistent storage mechanisms. Other applications may need to access data that resides on separate systems. For example, the data may reside in mainframe systems, Lightweight Directory Access Protocol (LDAP) repositories, and so forth. Another example is where data is provided by services through external systems such as business-to-business (B2B) integration systems, credit card bureau service, and so forth.
Typically, applications use shared distributed components such as entity beans to represent persistent data. An application is considered to employ bean-managed persistence (BMP) for its entity beans when these entity beans explicitly access the persistent storage-the entity bean includes code to directly access the persistent storage. An application with simpler requirements may forego using entity beans and instead use session beans or servlets to directly access the persistent storage to retrieve and modify the data. Or, the application could use entity beans with container-managed persistence, and thus let the container handle the transaction and persistent details.
Applications can use the JDBC API to access data residing in a relational database management system (RDBMS). The JDBC API enables standard access and manipulation of data in persistent storage, such as a relational database. The JDBC API enables J2EE applications to use SQL statements, which are the standard means for accessing RDBMS tables. However, even within an RDBMS environment, the actual syntax and format of the SQL statements may vary depending on the particular database product.
There is even greater variation with different types of persistent storage. Access mechanisms, supported APIs, and features vary between different types of persistent stores such as RDBMS, object-oriented databases, flat files, and so forth. Applications that need to access data from a legacy or disparate system (such as a mainframe, or B2B service) are often required to use APIs that may be proprietary. Such disparate data sources offer challenges to the application and can potentially create a direct dependency between application code and data access code. When business components-entity beans, session beans, and even presentation components like servlets and helper objects for JavaServer Pages (JSP) pages --need to access a data source, they can use the appropriate API to achieve connectivity and manipulate the data source. But including the connectivity and data access code within these components introduces a tight coupling between the components and the data source implementation. Such code dependencies in components make it difficult and tedious to migrate the application from one type of data source to another. When the data source changes, the components need to be changed to handle the new type of data source.
Forces
Components such as bean-managed entity beans, session beans, servlets, and other objects like helpers for JSP pages need to retrieve and store information from persistent stores and other data sources like legacy systems, B2B, LDAP, and so forth.
Persistent storage APIs vary depending on the product vendor. Other data sources may have APIs that are nonstandard and/or proprietary. These APIs and their capabilities also vary depending on the type of storage-RDBMS, object-oriented database management system (OODBMS), XML documents, flat files, and so forth. There is a lack of uniform APIs to address the requirements to access such disparate systems.
Components typically use proprietary APIs to access external and/or legacy systems to retrieve and store data.
Portability of the components is directly affected when specific access mechanisms and APIs are included in the components.
Components need to be transparent to the actual persistent store or data source implementation to provide easy migration to different vendor products, different storage types, and different data source types.
Solution
Use a Data Access Object (DAO) to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data.
The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets. The business component that relies on the DAO uses the simpler interface exposed by the DAO for its clients. The DAO completely hides the data source implementation details from its clients. Because the interface exposed by the DAO to clients does not change when the underlying data source implementation changes, this pattern allows the DAO to adapt to different storage schemes without affecting its clients or business components. Essentially, the DAO acts as an adapter between the component and the data source.
Structure
Figure 9.1 shows the class diagram representing the relationships for the DAO pattern.

Figure 9.1 Data Access Object
Participants and Responsibilities
Figure 9.2 contains the sequence diagram that shows the interaction between the various participants in this pattern.

Figure 9.2 Data Access Object sequence diagram
BusinessObject
The BusinessObject represents the data client. It is the object that requires access to the data source to obtain and store data. A BusinessObject may be implemented as a session bean, entity bean, or some other Java object, in addition to a servlet or helper bean that accesses the data source.
DataAccessObject
The DataAccessObject is the primary object of this pattern. The DataAccessObject abstracts the underlying data access implementation for the BusinessObject to enable transparent access to the data source. The BusinessObject also delegates data load and store operations to the DataAccessObject.
DataSource
This represents a data source implementation. A data source could be a database such as an RDBMS, OODBMS, XML repository, flat file system, and so forth. A data source can also be another system (legacy/mainframe), service (B2B service or credit card bureau), or some kind of repository (LDAP).
TransferObject
This represents a Transfer Object used as a data carrier. The DataAccessObject may use a Transfer Object to return data to the client. The DataAccessObject may also receive the data from the client in a Transfer Object to update the data in the data source.
Strategies
Automatic DAO Code Generation Strategy
Since each BusinessObject corresponds to a specific DAO, it is possible to establish relationships between the BusinessObject, DAO, and underlying implementations (such as the tables in an RDBMS). Once the relationships are established, it is possible to write a simple application-specific code-generation utility that generates the code for all DAOs required by the application. The metadata to generate the DAO can come from a developer-defined descriptor file. Alternatively, the code generator can automatically introspect the database and provide the necessary DAOs to access the database. If the requirements for DAOs are sufficiently complex, consider using third-party tools that provide object-to-relational mapping for RDBMS databases. These tools typically include GUI tools to map the business objects to the persistent storage objects and thereby define the intermediary DAOs. The tools automatically generate the code once the mapping is complete, and may provide other value-added features such as results caching, query caching, integration with application servers, integration with other third-party products (e.g., distributed caching), and so forth.
Factory for Data Access Objects Strategy
The DAO pattern can be made highly flexible by adopting the Abstract Factory [GoF] and the Factory Method [GoF] patterns (see "Related Patterns" in this chapter).
When the underlying storage is not subject to change from one implementation to another, this strategy can be implemented using the Factory Method pattern to produce a number of DAOs needed by the application. The class diagram for this case is shown in Figure 9.3.

Figure 9.3 Factory for Data Access Object strategy using Factory Method
When the underlying storage is subject to change from one implementation to another, this strategy may be implemented using the Abstract Factory pattern. The Abstract Factory can in turn build on and use the Factory Method implementation, as suggested in Design Patterns: Elements of Reusable Object-Oriented Software [GoF]. In this case, this strategy provides an abstract DAO factory object (Abstract Factory) that can construct various types of concrete DAO factories, each factory supporting a different type of persistent storage implementation. Once you obtain the concrete DAO factory for a specific implementation, you use it to produce DAOs supported and implemented in that implementation.
The class diagram for this strategy is shown in Figure 9.4. This class diagram shows a base DAO factory, which is an abstract class that is inherited and implemented by different concrete DAO factories to support storage implementation-specific access. The client can obtain a concrete DAO factory implementation such as RdbDAOFactory and use it to obtain concrete DAOs that work with that specific storage implementation. For example, the data client can obtain an RdbDAOFactory and use it to get specific DAOs such as RdbCustomerDAO, RdbAccountDAO, and so forth. The DAOs can extend and implement a generic base class (shown as DAO1 and DAO2) that specifically describe the DAO requirements for the business object it supports. Each concrete DAO is responsible for connecting to the data source and obtaining and manipulating data for the business object it supports.
The sample implementation for the DAO pattern and its strategies is shown in the "Sample Code" section of this chapter.
Figure 9.4 Factory for Data Access Object strategy using Abstract Factory
The sequence diagram describing the interactions for this strategy is shown in Figure 9.5.
Figure 9.5 Factory for Data Access Objects using Abstract Factory sequence diagram
Consequences
Enables Transparency
Business objects can use the data source without knowing the specific details of the data source's implementation. Access is transparent because the implementation details are hidden inside the DAO.
Enables Easier Migration
A layer of DAOs makes it easier for an application to migrate to a different database implementation. The business objects have no knowledge of the underlying data implementation. Thus, the migration involves changes only to the DAO layer. Further, if employing a factory strategy, it is possible to provide a concrete factory implementation for each underlying storage implementation. In this case, migrating to a different storage implementation means providing a new factory implementation to the application.
Reduces Code Complexity in Business ObjectsBecause the DAOs manage all the data access complexities, it simplifies the code in the business objects and other data clients that use the DAOs. All implementation-related code (such as SQL statements) is contained in the DAO and not in the business object. This improves code readability and development productivity.
Centralizes All Data Access into a Separate Layer
Because all data access operations are now delegated to the DAOs, the separate data access layer can be viewed as the layer that can isolate the rest of the application from the data access implementation. This centralization makes the application easier to maintain and manage.
Not Useful for Container-Managed Persistence
Because the EJB container manages entity beans with container-managed persistence (CMP), the container automatically services all persistent storage access. Applications using container-managed entity beans do not need a DAO layer, since the application server transparently provides this functionality. However, DAOs are still useful when a combination of CMP (for entity beans) and BMP (for session beans, servlets) is required.
Adds Extra Layer
The DAOs create an additional layer of objects between the data client and the data source that need to be designed and implemented to leverage the benefits of this pattern. But the benefit realized by choosing this approach pays off for the additional effort.
Needs Class Hierarchy Design
When using a factory strategy, the hierarchy of concrete factories and the hierarchy of concrete products produced by the factories need to be designed and implemented. This additional effort needs to be considered if there is sufficient justification warranting such flexibility. This increases the complexity of the design. However, you can choose to implement the factory strategy starting with the Factory Method pattern first, and then move towards the Abstract Factory if necessary.
Sample Code
Implementing Data Access Object pattern
An example DAO code for a persistent object that represents Customer information is shown in Example 9.4. The CloudscapeCustomerDAO creates a Customer Transfer Object when the findCustomer() method is invoked.
The sample code to use the DAO is shown in Example 9.6. The class diagram for this example is shown in Figure 9.6.
Figure 9.6 Implementing the DAO pattern
Implementing Factory for Data Access Objects Strategy
Using Factory Method Pattern
Consider an example where we are implementing this strategy in which a DAO factory produces many DAOs for a single database implementation (e.g., Oracle). The factory produces DAOs such as CustomerDAO, AccountDAO, OrderDAO, and so forth. The class diagram for this example is shown in Figure 9.7.
Figure 9.7 Implementing the Factory for DAO strategy using Factory Method
The example code for the DAO factory (CloudscapeDAOFactory) is listed in Example 9.2.
Using Abstract Factory Pattern
Consider an example where we are considering implementing this strategy for three different databases. In this case, the Abstract Factory pattern can be employed. The class diagram for this example is shown in Figure 9.8. The sample code in Example 9.1 shows code excerpt for the abstract DAOFactory class. This factory produces DAOs such as CustomerDAO, AccountDAO, OrderDAO, and so forth. This strategy uses the Factory Method implementation in the factories produced by the Abstract Factory.
Figure 9.8 Implementing the Factory for DAO strategy using Abstract Factory Example 9.1 Abstract DAOFactory Class
// Abstract class DAO Factory
public abstract class DAOFactory {
// List of DAO types supported by the factory
public static final int CLOUDSCAPE = 1;
public static final int ORACLE = 2;
public static final int SYBASE = 3;
...
// There will be a method for each DAO that can be
// created. The concrete factories will have to
// implement these methods.
public abstract CustomerDAO getCustomerDAO();
public abstract AccountDAO getAccountDAO();
public abstract OrderDAO getOrderDAO();
...
public static DAOFactory getDAOFactory(
int whichFactory) {
switch (whichFactory) {
case CLOUDSCAPE:
return new CloudscapeDAOFactory();
case ORACLE :
return new OracleDAOFactory();
case SYBASE :
return new SybaseDAOFactory();
...
default :
return null;
}
}
}
The sample code for CloudscapeDAOFactory is shown in Example 9.2. The implementation for OracleDAOFactory and SybaseDAOFactory are similar except for specifics of each implementation, such as JDBC driver, database URL, and differences in SQL syntax, if any.
Example 9.2 Concrete DAOFactory Implementation for Cloudscape
// Cloudscape concrete DAO Factory implementation
import java.sql.*;
public class CloudscapeDAOFactory extends DAOFactory {
public static final String DRIVER=
"COM.cloudscape.core.RmiJdbcDriver";
public static final String DBURL=
"jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB";
// method to create Cloudscape connections
public static Connection createConnection() {
// Use DRIVER and DBURL to create a connection
// Recommend connection pool implementation/usage
}
public CustomerDAO getCustomerDAO() {
// CloudscapeCustomerDAO implements CustomerDAO
return new CloudscapeCustomerDAO();
}
public AccountDAO getAccountDAO() {
// CloudscapeAccountDAO implements AccountDAO
return new CloudscapeAccountDAO();
}
public OrderDAO getOrderDAO() {
// CloudscapeOrderDAO implements OrderDAO
return new CloudscapeOrderDAO();
}
...
}
The CustomerDAO interface shown in Example 9.3 defines the DAO methods for Customer persistent object that are implemented by all concrete DAO implementations, such as CloudscapeCustomerDAO, OracleCustomerDAO, and SybaseCustomerDAO. Similar, but not listed here, are AccountDAO and OrderDAO interfaces that define the DAO methods for Account and Order business objects respectively.
Example 9.3 Base DAO Interface for Customer
// Interface that all CustomerDAOs must support
public interface CustomerDAO {
public int insertCustomer(...);
public boolean deleteCustomer(...);
public Customer findCustomer(...);
public boolean updateCustomer(...);
public RowSet selectCustomersRS(...);
public Collection selectCustomersTO(...);
...
}
The CloudscapeCustomerDAO implements the CustomerDAO as shown in Example 9.4. The implementation of other DAOs, such as CloudscapeAccountDAO, CloudscapeOrderDAO, OracleCustomerDAO, OracleAccountDAO, and so forth, are similar.
Example 9.4 Cloudscape DAO Implementation for Customer
// CloudscapeCustomerDAO implementation of the
// CustomerDAO interface. This class can contain all
// Cloudscape specific code and SQL statements.
// The client is thus shielded from knowing
// these implementation details.
import java.sql.*;
public class CloudscapeCustomerDAO implements
CustomerDAO {
public CloudscapeCustomerDAO() {
// initialization
}
// The following methods can use
// CloudscapeDAOFactory.createConnection()
// to get a connection as required
public int insertCustomer(...) {
// Implement insert customer here.
// Return newly created customer number
// or a -1 on error
}
public boolean deleteCustomer(...) {
// Implement delete customer here
// Return true on success, false on failure
}
public Customer findCustomer(...) {
// Implement find a customer here using supplied
// argument values as search criteria
// Return a Transfer Object if found,
// return null on error or if not found
}
public boolean updateCustomer(...) {
// implement update record here using data
// from the customerData Transfer Object
// Return true on success, false on failure or
// error
}
public RowSet selectCustomersRS(...) {
// implement search customers here using the
// supplied criteria.
// Return a RowSet.
}
public Collection selectCustomersTO(...) {
// implement search customers here using the
// supplied criteria.
// Alternatively, implement to return a Collection
// of Transfer Objects.
}
...
}
The Customer Transfer Object class is shown in Example 9.5. This is used by the DAOs to send and receive data from the clients. The usage of Transfer Objects is discussed in detail in the Transfer Object pattern.
Example 9.5 Customer Transfer Object
public class Customer implements java.io.Serializable {
// member variables
int CustomerNumber;
String name;
String streetAddress;
String city;
...
// getter and setter methods...
...
}
Example 9.6 shows the usage of the DAO factory and the DAO. If the implementation changes from Cloudscape to another product, the only required change is the getDAOFactory() method call to the DAO factory to obtain a different factory.
Example 9.6 Using a DAO and DAO Factory - Client Code
...
// create the required DAO Factory
DAOFactory cloudscapeFactory =
DAOFactory.getDAOFactory(DAOFactory.DAOCLOUDSCAPE);
// Create a DAO
CustomerDAO custDAO =
cloudscapeFactory.getCustomerDAO();
// create a new customer
int newCustNo = custDAO.insertCustomer(...);
// Find a customer object. Get the Transfer Object.
Customer cust = custDAO.findCustomer(...);
// modify the values in the Transfer Object.
cust.setAddress(...);
cust.setEmail(...);
// update the customer object using the DAO
custDAO.updateCustomer(cust);
// delete a customer object
custDAO.deleteCustomer(...);
// select all customers in the same city
Customer criteria=new Customer();
criteria.setCity("New York");
Collection customersList =
custDAO.selectCustomersTO(criteria);
// returns customersList - collection of Customer
// Transfer Objects. iterate through this collection to
// get values.
Access to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (relational databases, object-oriented databases, flat files, and so forth) and the vendor implementation.
Problem
Many real-world Java 2 Platform, Enterprise Edition (J2EE) applications need to use persistent data at some point. For many applications, persistent storage is implemented with different mechanisms, and there are marked differences in the APIs used to access these different persistent storage mechanisms. Other applications may need to access data that resides on separate systems. For example, the data may reside in mainframe systems, Lightweight Directory Access Protocol (LDAP) repositories, and so forth. Another example is where data is provided by services through external systems such as business-to-business (B2B) integration systems, credit card bureau service, and so forth.
Typically, applications use shared distributed components such as entity beans to represent persistent data. An application is considered to employ bean-managed persistence (BMP) for its entity beans when these entity beans explicitly access the persistent storage-the entity bean includes code to directly access the persistent storage. An application with simpler requirements may forego using entity beans and instead use session beans or servlets to directly access the persistent storage to retrieve and modify the data. Or, the application could use entity beans with container-managed persistence, and thus let the container handle the transaction and persistent details.
Applications can use the JDBC API to access data residing in a relational database management system (RDBMS). The JDBC API enables standard access and manipulation of data in persistent storage, such as a relational database. The JDBC API enables J2EE applications to use SQL statements, which are the standard means for accessing RDBMS tables. However, even within an RDBMS environment, the actual syntax and format of the SQL statements may vary depending on the particular database product.
There is even greater variation with different types of persistent storage. Access mechanisms, supported APIs, and features vary between different types of persistent stores such as RDBMS, object-oriented databases, flat files, and so forth. Applications that need to access data from a legacy or disparate system (such as a mainframe, or B2B service) are often required to use APIs that may be proprietary. Such disparate data sources offer challenges to the application and can potentially create a direct dependency between application code and data access code. When business components-entity beans, session beans, and even presentation components like servlets and helper objects for JavaServer Pages (JSP) pages --need to access a data source, they can use the appropriate API to achieve connectivity and manipulate the data source. But including the connectivity and data access code within these components introduces a tight coupling between the components and the data source implementation. Such code dependencies in components make it difficult and tedious to migrate the application from one type of data source to another. When the data source changes, the components need to be changed to handle the new type of data source.
Forces
Components such as bean-managed entity beans, session beans, servlets, and other objects like helpers for JSP pages need to retrieve and store information from persistent stores and other data sources like legacy systems, B2B, LDAP, and so forth.
Persistent storage APIs vary depending on the product vendor. Other data sources may have APIs that are nonstandard and/or proprietary. These APIs and their capabilities also vary depending on the type of storage-RDBMS, object-oriented database management system (OODBMS), XML documents, flat files, and so forth. There is a lack of uniform APIs to address the requirements to access such disparate systems.
Components typically use proprietary APIs to access external and/or legacy systems to retrieve and store data.
Portability of the components is directly affected when specific access mechanisms and APIs are included in the components.
Components need to be transparent to the actual persistent store or data source implementation to provide easy migration to different vendor products, different storage types, and different data source types.
Solution
Use a Data Access Object (DAO) to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data.
The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets. The business component that relies on the DAO uses the simpler interface exposed by the DAO for its clients. The DAO completely hides the data source implementation details from its clients. Because the interface exposed by the DAO to clients does not change when the underlying data source implementation changes, this pattern allows the DAO to adapt to different storage schemes without affecting its clients or business components. Essentially, the DAO acts as an adapter between the component and the data source.
Structure
Figure 9.1 shows the class diagram representing the relationships for the DAO pattern.

Figure 9.1 Data Access Object
Participants and Responsibilities
Figure 9.2 contains the sequence diagram that shows the interaction between the various participants in this pattern.
Figure 9.2 Data Access Object sequence diagram
BusinessObject
The BusinessObject represents the data client. It is the object that requires access to the data source to obtain and store data. A BusinessObject may be implemented as a session bean, entity bean, or some other Java object, in addition to a servlet or helper bean that accesses the data source.
DataAccessObject
The DataAccessObject is the primary object of this pattern. The DataAccessObject abstracts the underlying data access implementation for the BusinessObject to enable transparent access to the data source. The BusinessObject also delegates data load and store operations to the DataAccessObject.
DataSource
This represents a data source implementation. A data source could be a database such as an RDBMS, OODBMS, XML repository, flat file system, and so forth. A data source can also be another system (legacy/mainframe), service (B2B service or credit card bureau), or some kind of repository (LDAP).
TransferObject
This represents a Transfer Object used as a data carrier. The DataAccessObject may use a Transfer Object to return data to the client. The DataAccessObject may also receive the data from the client in a Transfer Object to update the data in the data source.
Strategies
Automatic DAO Code Generation Strategy
Since each BusinessObject corresponds to a specific DAO, it is possible to establish relationships between the BusinessObject, DAO, and underlying implementations (such as the tables in an RDBMS). Once the relationships are established, it is possible to write a simple application-specific code-generation utility that generates the code for all DAOs required by the application. The metadata to generate the DAO can come from a developer-defined descriptor file. Alternatively, the code generator can automatically introspect the database and provide the necessary DAOs to access the database. If the requirements for DAOs are sufficiently complex, consider using third-party tools that provide object-to-relational mapping for RDBMS databases. These tools typically include GUI tools to map the business objects to the persistent storage objects and thereby define the intermediary DAOs. The tools automatically generate the code once the mapping is complete, and may provide other value-added features such as results caching, query caching, integration with application servers, integration with other third-party products (e.g., distributed caching), and so forth.
Factory for Data Access Objects Strategy
The DAO pattern can be made highly flexible by adopting the Abstract Factory [GoF] and the Factory Method [GoF] patterns (see "Related Patterns" in this chapter).
When the underlying storage is not subject to change from one implementation to another, this strategy can be implemented using the Factory Method pattern to produce a number of DAOs needed by the application. The class diagram for this case is shown in Figure 9.3.
Figure 9.3 Factory for Data Access Object strategy using Factory Method
When the underlying storage is subject to change from one implementation to another, this strategy may be implemented using the Abstract Factory pattern. The Abstract Factory can in turn build on and use the Factory Method implementation, as suggested in Design Patterns: Elements of Reusable Object-Oriented Software [GoF]. In this case, this strategy provides an abstract DAO factory object (Abstract Factory) that can construct various types of concrete DAO factories, each factory supporting a different type of persistent storage implementation. Once you obtain the concrete DAO factory for a specific implementation, you use it to produce DAOs supported and implemented in that implementation.
The class diagram for this strategy is shown in Figure 9.4. This class diagram shows a base DAO factory, which is an abstract class that is inherited and implemented by different concrete DAO factories to support storage implementation-specific access. The client can obtain a concrete DAO factory implementation such as RdbDAOFactory and use it to obtain concrete DAOs that work with that specific storage implementation. For example, the data client can obtain an RdbDAOFactory and use it to get specific DAOs such as RdbCustomerDAO, RdbAccountDAO, and so forth. The DAOs can extend and implement a generic base class (shown as DAO1 and DAO2) that specifically describe the DAO requirements for the business object it supports. Each concrete DAO is responsible for connecting to the data source and obtaining and manipulating data for the business object it supports.
The sample implementation for the DAO pattern and its strategies is shown in the "Sample Code" section of this chapter.
Figure 9.4 Factory for Data Access Object strategy using Abstract Factory
The sequence diagram describing the interactions for this strategy is shown in Figure 9.5.
Figure 9.5 Factory for Data Access Objects using Abstract Factory sequence diagram
Consequences
Enables Transparency
Business objects can use the data source without knowing the specific details of the data source's implementation. Access is transparent because the implementation details are hidden inside the DAO.
Enables Easier Migration
A layer of DAOs makes it easier for an application to migrate to a different database implementation. The business objects have no knowledge of the underlying data implementation. Thus, the migration involves changes only to the DAO layer. Further, if employing a factory strategy, it is possible to provide a concrete factory implementation for each underlying storage implementation. In this case, migrating to a different storage implementation means providing a new factory implementation to the application.
Reduces Code Complexity in Business ObjectsBecause the DAOs manage all the data access complexities, it simplifies the code in the business objects and other data clients that use the DAOs. All implementation-related code (such as SQL statements) is contained in the DAO and not in the business object. This improves code readability and development productivity.
Centralizes All Data Access into a Separate Layer
Because all data access operations are now delegated to the DAOs, the separate data access layer can be viewed as the layer that can isolate the rest of the application from the data access implementation. This centralization makes the application easier to maintain and manage.
Not Useful for Container-Managed Persistence
Because the EJB container manages entity beans with container-managed persistence (CMP), the container automatically services all persistent storage access. Applications using container-managed entity beans do not need a DAO layer, since the application server transparently provides this functionality. However, DAOs are still useful when a combination of CMP (for entity beans) and BMP (for session beans, servlets) is required.
Adds Extra Layer
The DAOs create an additional layer of objects between the data client and the data source that need to be designed and implemented to leverage the benefits of this pattern. But the benefit realized by choosing this approach pays off for the additional effort.
Needs Class Hierarchy Design
When using a factory strategy, the hierarchy of concrete factories and the hierarchy of concrete products produced by the factories need to be designed and implemented. This additional effort needs to be considered if there is sufficient justification warranting such flexibility. This increases the complexity of the design. However, you can choose to implement the factory strategy starting with the Factory Method pattern first, and then move towards the Abstract Factory if necessary.
Sample Code
Implementing Data Access Object pattern
An example DAO code for a persistent object that represents Customer information is shown in Example 9.4. The CloudscapeCustomerDAO creates a Customer Transfer Object when the findCustomer() method is invoked.
The sample code to use the DAO is shown in Example 9.6. The class diagram for this example is shown in Figure 9.6.
Figure 9.6 Implementing the DAO pattern
Implementing Factory for Data Access Objects Strategy
Using Factory Method Pattern
Consider an example where we are implementing this strategy in which a DAO factory produces many DAOs for a single database implementation (e.g., Oracle). The factory produces DAOs such as CustomerDAO, AccountDAO, OrderDAO, and so forth. The class diagram for this example is shown in Figure 9.7.
Figure 9.7 Implementing the Factory for DAO strategy using Factory Method
The example code for the DAO factory (CloudscapeDAOFactory) is listed in Example 9.2.
Using Abstract Factory Pattern
Consider an example where we are considering implementing this strategy for three different databases. In this case, the Abstract Factory pattern can be employed. The class diagram for this example is shown in Figure 9.8. The sample code in Example 9.1 shows code excerpt for the abstract DAOFactory class. This factory produces DAOs such as CustomerDAO, AccountDAO, OrderDAO, and so forth. This strategy uses the Factory Method implementation in the factories produced by the Abstract Factory.
Figure 9.8 Implementing the Factory for DAO strategy using Abstract Factory Example 9.1 Abstract DAOFactory Class
// Abstract class DAO Factory
public abstract class DAOFactory {
// List of DAO types supported by the factory
public static final int CLOUDSCAPE = 1;
public static final int ORACLE = 2;
public static final int SYBASE = 3;
...
// There will be a method for each DAO that can be
// created. The concrete factories will have to
// implement these methods.
public abstract CustomerDAO getCustomerDAO();
public abstract AccountDAO getAccountDAO();
public abstract OrderDAO getOrderDAO();
...
public static DAOFactory getDAOFactory(
int whichFactory) {
switch (whichFactory) {
case CLOUDSCAPE:
return new CloudscapeDAOFactory();
case ORACLE :
return new OracleDAOFactory();
case SYBASE :
return new SybaseDAOFactory();
...
default :
return null;
}
}
}
The sample code for CloudscapeDAOFactory is shown in Example 9.2. The implementation for OracleDAOFactory and SybaseDAOFactory are similar except for specifics of each implementation, such as JDBC driver, database URL, and differences in SQL syntax, if any.
Example 9.2 Concrete DAOFactory Implementation for Cloudscape
// Cloudscape concrete DAO Factory implementation
import java.sql.*;
public class CloudscapeDAOFactory extends DAOFactory {
public static final String DRIVER=
"COM.cloudscape.core.RmiJdbcDriver";
public static final String DBURL=
"jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB";
// method to create Cloudscape connections
public static Connection createConnection() {
// Use DRIVER and DBURL to create a connection
// Recommend connection pool implementation/usage
}
public CustomerDAO getCustomerDAO() {
// CloudscapeCustomerDAO implements CustomerDAO
return new CloudscapeCustomerDAO();
}
public AccountDAO getAccountDAO() {
// CloudscapeAccountDAO implements AccountDAO
return new CloudscapeAccountDAO();
}
public OrderDAO getOrderDAO() {
// CloudscapeOrderDAO implements OrderDAO
return new CloudscapeOrderDAO();
}
...
}
The CustomerDAO interface shown in Example 9.3 defines the DAO methods for Customer persistent object that are implemented by all concrete DAO implementations, such as CloudscapeCustomerDAO, OracleCustomerDAO, and SybaseCustomerDAO. Similar, but not listed here, are AccountDAO and OrderDAO interfaces that define the DAO methods for Account and Order business objects respectively.
Example 9.3 Base DAO Interface for Customer
// Interface that all CustomerDAOs must support
public interface CustomerDAO {
public int insertCustomer(...);
public boolean deleteCustomer(...);
public Customer findCustomer(...);
public boolean updateCustomer(...);
public RowSet selectCustomersRS(...);
public Collection selectCustomersTO(...);
...
}
The CloudscapeCustomerDAO implements the CustomerDAO as shown in Example 9.4. The implementation of other DAOs, such as CloudscapeAccountDAO, CloudscapeOrderDAO, OracleCustomerDAO, OracleAccountDAO, and so forth, are similar.
Example 9.4 Cloudscape DAO Implementation for Customer
// CloudscapeCustomerDAO implementation of the
// CustomerDAO interface. This class can contain all
// Cloudscape specific code and SQL statements.
// The client is thus shielded from knowing
// these implementation details.
import java.sql.*;
public class CloudscapeCustomerDAO implements
CustomerDAO {
public CloudscapeCustomerDAO() {
// initialization
}
// The following methods can use
// CloudscapeDAOFactory.createConnection()
// to get a connection as required
public int insertCustomer(...) {
// Implement insert customer here.
// Return newly created customer number
// or a -1 on error
}
public boolean deleteCustomer(...) {
// Implement delete customer here
// Return true on success, false on failure
}
public Customer findCustomer(...) {
// Implement find a customer here using supplied
// argument values as search criteria
// Return a Transfer Object if found,
// return null on error or if not found
}
public boolean updateCustomer(...) {
// implement update record here using data
// from the customerData Transfer Object
// Return true on success, false on failure or
// error
}
public RowSet selectCustomersRS(...) {
// implement search customers here using the
// supplied criteria.
// Return a RowSet.
}
public Collection selectCustomersTO(...) {
// implement search customers here using the
// supplied criteria.
// Alternatively, implement to return a Collection
// of Transfer Objects.
}
...
}
The Customer Transfer Object class is shown in Example 9.5. This is used by the DAOs to send and receive data from the clients. The usage of Transfer Objects is discussed in detail in the Transfer Object pattern.
Example 9.5 Customer Transfer Object
public class Customer implements java.io.Serializable {
// member variables
int CustomerNumber;
String name;
String streetAddress;
String city;
...
// getter and setter methods...
...
}
Example 9.6 shows the usage of the DAO factory and the DAO. If the implementation changes from Cloudscape to another product, the only required change is the getDAOFactory() method call to the DAO factory to obtain a different factory.
Example 9.6 Using a DAO and DAO Factory - Client Code
...
// create the required DAO Factory
DAOFactory cloudscapeFactory =
DAOFactory.getDAOFactory(DAOFactory.DAOCLOUDSCAPE);
// Create a DAO
CustomerDAO custDAO =
cloudscapeFactory.getCustomerDAO();
// create a new customer
int newCustNo = custDAO.insertCustomer(...);
// Find a customer object. Get the Transfer Object.
Customer cust = custDAO.findCustomer(...);
// modify the values in the Transfer Object.
cust.setAddress(...);
cust.setEmail(...);
// update the customer object using the DAO
custDAO.updateCustomer(cust);
// delete a customer object
custDAO.deleteCustomer(...);
// select all customers in the same city
Customer criteria=new Customer();
criteria.setCity("New York");
Collection customersList =
custDAO.selectCustomersTO(criteria);
// returns customersList - collection of Customer
// Transfer Objects. iterate through this collection to
// get values.
Thursday, July 17, 2008
Useful SQL Queries
Create USER in mysql:
mysql> CREATE USER 'exampledb'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.05 sec)
mysql> select User,Host from mysql.user;
+-----------+-----------+
| User | Host |
+-----------+-----------+
| exampledb | localhost |
| exampledb2 | localhost |
+-----------+-----------+
2 rows in set (0.00 sec)
Assigning Privileges:
mysql> GRANT CREATE,SELECT,INSERT,UPDATE,DELETE,DROP ON snappsapi.* TO 'exampledb'@'localhost';
Query OK, 0 rows affected (0.00 sec)
To show the users in a MySQL database, first login as an administrative user, then run this query:
SELECT * from mysql.user;
Drop User in mysql:
mysql> drop user exampledb@localhost;
Query OK, 0 rows affected (0.00 sec)
To know Privileges in myslq
mysql> show grants;
+-------------------------------------------------------------+
| Grants for root@% |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uUSERNAME -pPASSWORD
mysql> CREATE USER 'exampledb'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.05 sec)
mysql> select User,Host from mysql.user;
+-----------+-----------+
| User | Host |
+-----------+-----------+
| exampledb | localhost |
| exampledb2 | localhost |
+-----------+-----------+
2 rows in set (0.00 sec)
Assigning Privileges:
mysql> GRANT CREATE,SELECT,INSERT,UPDATE,DELETE,DROP ON snappsapi.* TO 'exampledb'@'localhost';
Query OK, 0 rows affected (0.00 sec)
To show the users in a MySQL database, first login as an administrative user, then run this query:
SELECT * from mysql.user;
Drop User in mysql:
mysql> drop user exampledb@localhost;
Query OK, 0 rows affected (0.00 sec)
To know Privileges in myslq
mysql> show grants;
+-------------------------------------------------------------+
| Grants for root@% |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uUSERNAME -pPASSWORD
Sunday, July 6, 2008
AJAX Introduction
AJAX = Asynchronous JavaScript and XML
AJAX is not a new programming language, but a technique for creating better, faster, and more interactive web applications.
With AJAX, your JavaScript can communicate directly with the server, using the JavaScript XMLHttpRequest object. With this object, your JavaScript can trade data with a web server, without reloading the page.
AJAX uses asynchronous data transfer (HTTP requests) between the browser and the web server, allowing web pages to request small bits of information from the server instead of whole pages.
The AJAX technique makes Internet applications smaller, faster and more user-friendly.
AJAX is a browser technology independent of web server software.
AJAX is Based on Web Standards
AJAX is based on the following web standards:
JavaScript
XML
HTML
CSS
The web standards used in AJAX are well defined, and supported by all major browsers. AJAX applications are browser and platform independent.
AJAX is About Better Internet Applications
Web applications have many benefits over desktop applications; they can reach a larger audience, they are easier to install and support, and easier to develop.
However, Internet applications are not always as "rich" and user-friendly as traditional desktop applications.
With AJAX, Internet applications can be made richer and more user-friendly.
AJAX Uses HTTP Requests
In traditional JavaScript coding, if you want to get any information from a database or a file on the server, or send user information to a server, you will have to make an HTML form and GET or POST data to the server. The user will have to click the "Submit" button to send/get the information, wait for the server to respond, then a new page will load with the results.
Because the server returns a new page each time the user submits input, traditional web applications can run slowly and tend to be less user-friendly.
With AJAX, your JavaScript communicates directly with the server, through the JavaScript XMLHttpRequest object
With an HTTP request, a web page can make a request to, and get a response from a web server - without reloading the page. The user will stay on the same page, and he or she will not notice that scripts request pages, or send data to a server in the background.
The XMLHttpRequest Object
By using the XMLHttpRequest object, a web developer can update a page with data from the server after the page has loaded!
AJAX was made popular in 2005 by Google (with Google Suggest).
Google Suggest is using the XMLHttpRequest object to create a very dynamic web interface: When you start typing in Google's search box, a JavaScript sends the letters off to a server and the server returns a list of suggestions.
The XMLHttpRequest object is supported in Internet Explorer 5.0+, Safari 1.2, Mozilla 1.0 / Firefox, Opera 8+, and Netscape 7.
Your First AJAX Application
To understand how AJAX works, we will create a small AJAX application.
First, we are going to create a standard HTML form with two text fields: username and time. The username field will be filled in by the user and the time field will be filled in using AJAX.
The HTML file will be named "testAjax.htm", and it looks like this (notice that the HTML form below has no submit button!):
AJAX - Browser Support
The keystone of AJAX is the XMLHttpRequest object.
Different browsers use different methods to create the XMLHttpRequest object.
Internet Explorer uses an ActiveXObject, while other browsers uses the built-in JavaScript object called XMLHttpRequest.
To create this object, and deal with different browsers, we are going to use a "try and catch" statement. You can read more about the try and catch statement in our JavaScript tutorial.
Let's update our "testAjax.htm" file with the JavaScript that creates the XMLHttpRequest object:
Example explained: First create a variable xmlHttp to hold the XMLHttpRequest object.
Then try to create the object with XMLHttp=new XMLHttpRequest(). This is for the Firefox, Opera, and Safari browsers. If that fails, try xmlHttp=new ActiveXObject("Msxml2.XMLHTTP") which is for Internet Explorer 6.0+, if that also fails, try xmlHttp=new ActiveXObject("Microsoft.XMLHTTP") which is for Internet Explorer 5.5+
If none of the three methods work, the user has a very outdated browser, and he or she will get an alert stating that the browser doesn't support AJAX.
Note: The browser-specific code above is long and quite complex. However, this is the code you can use every time you need to create an XMLHttpRequest object, so you can just copy and paste it whenever you need it. The code above is compatible with all the popular browsers: Internet Explorer, Opera, Firefox, and Safari.
The next chapter shows how to use the XMLHttpRequest object to communicate with the server.
AJAX - More About the XMLHttpRequest Object
Before sending data to the server, we have to explain three important properties of the XMLHttpRequest object.
The onreadystatechange Property
After a request to the server, we need a function that can receive the data that is returned by the server.
The onreadystatechange property stores the function that will process the response from a server. The following code defines an empty function and sets the onreadystatechange property at the same time:
The readyState Property
The readyState property holds the status of the server's response. Each time the readyState changes, the onreadystatechange function will be executed.
Here are the possible values for the readyState property:
State Description
0 The request is not initialized
1 The request has been set up
2 The request has been sent
3 The request is in process
4 The request is complete
We are going to add an If statement to the onreadystatechange function to test if our response is complete (this means that we can get our data):
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
// Get the data from the server's response
}
}
The responseText Property
The data sent back from the server can be retrieved with the responseText property.
In our code, we will set the value of our "time" input field equal to responseText:
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
document.myForm.time.value=xmlHttp.responseText;
}
}
AJAX - Sending a Request to the Server
To send off a request to the server, we use the open() method and the send() method.
The open() method takes three arguments. The first argument defines which method to use when sending the request (GET or POST). The second argument specifies the URL of the server-side script. The third argument specifies that the request should be handled asynchronously. The send() method sends the request off to the server. If we assume that the HTML and ASP file are in the same directory, the code would be:
xmlHttp.open("GET","time.asp",true);
xmlHttp.send(null);
Now we must decide when the AJAX function should be executed. We will let the function run "behind the scenes" when the user types something in the username text field:
Our updated AJAX-ready "testAjax.htm" file now looks like this:
AJAX - The Server-Side ASP Script
Now we are going to create the script that displays the current server time.
The responseText property (explained in the previous chapter) will store the data returned from the server. Here we want to send back the current time. The code in "time.asp" looks like this:
<%
response.expires=-1
response.write(time)
%>
Note: The Expires property sets how long (in minutes) a page will be cached on a browser before it expires. If a user returns to the same page before it expires, the cached version is displayed. Response.Expires=-1 indicates that the page will never be cached.
AJAX is not a new programming language, but a technique for creating better, faster, and more interactive web applications.
With AJAX, your JavaScript can communicate directly with the server, using the JavaScript XMLHttpRequest object. With this object, your JavaScript can trade data with a web server, without reloading the page.
AJAX uses asynchronous data transfer (HTTP requests) between the browser and the web server, allowing web pages to request small bits of information from the server instead of whole pages.
The AJAX technique makes Internet applications smaller, faster and more user-friendly.
AJAX is a browser technology independent of web server software.
AJAX is Based on Web Standards
AJAX is based on the following web standards:
JavaScript
XML
HTML
CSS
The web standards used in AJAX are well defined, and supported by all major browsers. AJAX applications are browser and platform independent.
AJAX is About Better Internet Applications
Web applications have many benefits over desktop applications; they can reach a larger audience, they are easier to install and support, and easier to develop.
However, Internet applications are not always as "rich" and user-friendly as traditional desktop applications.
With AJAX, Internet applications can be made richer and more user-friendly.
AJAX Uses HTTP Requests
In traditional JavaScript coding, if you want to get any information from a database or a file on the server, or send user information to a server, you will have to make an HTML form and GET or POST data to the server. The user will have to click the "Submit" button to send/get the information, wait for the server to respond, then a new page will load with the results.
Because the server returns a new page each time the user submits input, traditional web applications can run slowly and tend to be less user-friendly.
With AJAX, your JavaScript communicates directly with the server, through the JavaScript XMLHttpRequest object
With an HTTP request, a web page can make a request to, and get a response from a web server - without reloading the page. The user will stay on the same page, and he or she will not notice that scripts request pages, or send data to a server in the background.
The XMLHttpRequest Object
By using the XMLHttpRequest object, a web developer can update a page with data from the server after the page has loaded!
AJAX was made popular in 2005 by Google (with Google Suggest).
Google Suggest is using the XMLHttpRequest object to create a very dynamic web interface: When you start typing in Google's search box, a JavaScript sends the letters off to a server and the server returns a list of suggestions.
The XMLHttpRequest object is supported in Internet Explorer 5.0+, Safari 1.2, Mozilla 1.0 / Firefox, Opera 8+, and Netscape 7.
Your First AJAX Application
To understand how AJAX works, we will create a small AJAX application.
First, we are going to create a standard HTML form with two text fields: username and time. The username field will be filled in by the user and the time field will be filled in using AJAX.
The HTML file will be named "testAjax.htm", and it looks like this (notice that the HTML form below has no submit button!):
AJAX - Browser Support
The keystone of AJAX is the XMLHttpRequest object.
Different browsers use different methods to create the XMLHttpRequest object.
Internet Explorer uses an ActiveXObject, while other browsers uses the built-in JavaScript object called XMLHttpRequest.
To create this object, and deal with different browsers, we are going to use a "try and catch" statement. You can read more about the try and catch statement in our JavaScript tutorial.
Let's update our "testAjax.htm" file with the JavaScript that creates the XMLHttpRequest object:
Example explained: First create a variable xmlHttp to hold the XMLHttpRequest object.
Then try to create the object with XMLHttp=new XMLHttpRequest(). This is for the Firefox, Opera, and Safari browsers. If that fails, try xmlHttp=new ActiveXObject("Msxml2.XMLHTTP") which is for Internet Explorer 6.0+, if that also fails, try xmlHttp=new ActiveXObject("Microsoft.XMLHTTP") which is for Internet Explorer 5.5+
If none of the three methods work, the user has a very outdated browser, and he or she will get an alert stating that the browser doesn't support AJAX.
Note: The browser-specific code above is long and quite complex. However, this is the code you can use every time you need to create an XMLHttpRequest object, so you can just copy and paste it whenever you need it. The code above is compatible with all the popular browsers: Internet Explorer, Opera, Firefox, and Safari.
The next chapter shows how to use the XMLHttpRequest object to communicate with the server.
AJAX - More About the XMLHttpRequest Object
Before sending data to the server, we have to explain three important properties of the XMLHttpRequest object.
The onreadystatechange Property
After a request to the server, we need a function that can receive the data that is returned by the server.
The onreadystatechange property stores the function that will process the response from a server. The following code defines an empty function and sets the onreadystatechange property at the same time:
The readyState Property
The readyState property holds the status of the server's response. Each time the readyState changes, the onreadystatechange function will be executed.
Here are the possible values for the readyState property:
State Description
0 The request is not initialized
1 The request has been set up
2 The request has been sent
3 The request is in process
4 The request is complete
We are going to add an If statement to the onreadystatechange function to test if our response is complete (this means that we can get our data):
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
// Get the data from the server's response
}
}
The responseText Property
The data sent back from the server can be retrieved with the responseText property.
In our code, we will set the value of our "time" input field equal to responseText:
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
document.myForm.time.value=xmlHttp.responseText;
}
}
AJAX - Sending a Request to the Server
To send off a request to the server, we use the open() method and the send() method.
The open() method takes three arguments. The first argument defines which method to use when sending the request (GET or POST). The second argument specifies the URL of the server-side script. The third argument specifies that the request should be handled asynchronously. The send() method sends the request off to the server. If we assume that the HTML and ASP file are in the same directory, the code would be:
xmlHttp.open("GET","time.asp",true);
xmlHttp.send(null);
Now we must decide when the AJAX function should be executed. We will let the function run "behind the scenes" when the user types something in the username text field:
Our updated AJAX-ready "testAjax.htm" file now looks like this:
AJAX - The Server-Side ASP Script
Now we are going to create the script that displays the current server time.
The responseText property (explained in the previous chapter) will store the data returned from the server. Here we want to send back the current time. The code in "time.asp" looks like this:
<%
response.expires=-1
response.write(time)
%>
Note: The Expires property sets how long (in minutes) a page will be cached on a browser before it expires. If a user returns to the same page before it expires, the cached version is displayed. Response.Expires=-1 indicates that the page will never be cached.
Monday, January 21, 2008
MySQL - LEFT JOIN and RIGHT JOIN, INNER JOIN and OUTER JOIN
First, some sample data:
Mr Brown, Person number 1, has a phone number 01225 708225
Miss Smith, Person number 2, has a phone number 01225 899360
Mr Pullen, Person number 3, has a phone number 01380 724040
and also:
Person number 1 is selling property number 1 - Old House Farm
Person number 3 is selling property number 2 - The Willows
Person number 3 is (also) selling property number 3 - Tall Trees
Person number 3 is (also) selling property number 4 - The Melksham Florist
Person number 4 is selling property number 5 - Dun Roamin.
mysql> select * from demo_people;
+------------+--------------+------+
| name | phone | pid |
+------------+--------------+------+
| Mr Brown | 01225 708225 | 1 |
| Miss Smith | 01225 899360 | 2 |
| Mr Pullen | 01380 724040 | 3 |
+------------+--------------+------+
3 rows in set (0.00 sec)
mysql> select * from demo_property;
+------+------+----------------------+
| pid | spid | selling |
+------+------+----------------------+
| 1 | 1 | Old House Farm |
| 3 | 2 | The Willows |
| 3 | 3 | Tall Trees |
| 3 | 4 | The Melksham Florist |
| 4 | 5 | Dun Roamin |
+------+------+----------------------+
5 rows in set (0.00 sec)
mysql>
If I do a regular JOIN (with none of the keywords INNER, OUTER, LEFT or RIGHT), then I get all records that match in the appropriate way in the two tables, and records in both incoming tables that do not match are not reported:
mysql> select name, phone, selling
from demo_people join demo_property
on demo_people.pid = demo_property.pid;
+-----------+--------------+----------------------+
| name | phone | selling |
+-----------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+-----------+--------------+----------------------+
4 rows in set (0.01 sec)
mysql>
If I do a LEFT JOIN, I get all records that match in the same way and IN ADDITION I get an extra record for each unmatched record in the left table of the join - thus ensuring (in my example) that every PERSON gets a mention:
mysql> select name, phone, selling
from demo_people left join demo_property
on demo_people.pid = demo_property.pid;
+------------+--------------+----------------------+
| name | phone | selling |
+------------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Miss Smith | 01225 899360 | NULL |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+------------+--------------+----------------------+
5 rows in set (0.00 sec)
mysql>
If I do a RIGHT JOIN, I get all the records that match and IN ADDITION I get an extra record for each unmatched record in the right table of the join - im my example, that means that each property gets a mention even if we don't have seller details:
mysql> select name, phone, selling
from demo_people right join demo_property
on demo_people.pid = demo_property.pid;
+-----------+--------------+----------------------+
| name | phone | selling |
+-----------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
| NULL | NULL | Dun Roamin |
+-----------+--------------+----------------------+
5 rows in set (0.00 sec)
mysql>
An INNER JOIN does a full join, just like the first example, and the word OUTER may be added after the word LEFT or RIGHT in the last two examples - it's provided for ODBC compatability and doesn't add an extra capabilities.
Mr Brown, Person number 1, has a phone number 01225 708225
Miss Smith, Person number 2, has a phone number 01225 899360
Mr Pullen, Person number 3, has a phone number 01380 724040
and also:
Person number 1 is selling property number 1 - Old House Farm
Person number 3 is selling property number 2 - The Willows
Person number 3 is (also) selling property number 3 - Tall Trees
Person number 3 is (also) selling property number 4 - The Melksham Florist
Person number 4 is selling property number 5 - Dun Roamin.
mysql> select * from demo_people;
+------------+--------------+------+
| name | phone | pid |
+------------+--------------+------+
| Mr Brown | 01225 708225 | 1 |
| Miss Smith | 01225 899360 | 2 |
| Mr Pullen | 01380 724040 | 3 |
+------------+--------------+------+
3 rows in set (0.00 sec)
mysql> select * from demo_property;
+------+------+----------------------+
| pid | spid | selling |
+------+------+----------------------+
| 1 | 1 | Old House Farm |
| 3 | 2 | The Willows |
| 3 | 3 | Tall Trees |
| 3 | 4 | The Melksham Florist |
| 4 | 5 | Dun Roamin |
+------+------+----------------------+
5 rows in set (0.00 sec)
mysql>
If I do a regular JOIN (with none of the keywords INNER, OUTER, LEFT or RIGHT), then I get all records that match in the appropriate way in the two tables, and records in both incoming tables that do not match are not reported:
mysql> select name, phone, selling
from demo_people join demo_property
on demo_people.pid = demo_property.pid;
+-----------+--------------+----------------------+
| name | phone | selling |
+-----------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+-----------+--------------+----------------------+
4 rows in set (0.01 sec)
mysql>
If I do a LEFT JOIN, I get all records that match in the same way and IN ADDITION I get an extra record for each unmatched record in the left table of the join - thus ensuring (in my example) that every PERSON gets a mention:
mysql> select name, phone, selling
from demo_people left join demo_property
on demo_people.pid = demo_property.pid;
+------------+--------------+----------------------+
| name | phone | selling |
+------------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Miss Smith | 01225 899360 | NULL |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+------------+--------------+----------------------+
5 rows in set (0.00 sec)
mysql>
If I do a RIGHT JOIN, I get all the records that match and IN ADDITION I get an extra record for each unmatched record in the right table of the join - im my example, that means that each property gets a mention even if we don't have seller details:
mysql> select name, phone, selling
from demo_people right join demo_property
on demo_people.pid = demo_property.pid;
+-----------+--------------+----------------------+
| name | phone | selling |
+-----------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
| NULL | NULL | Dun Roamin |
+-----------+--------------+----------------------+
5 rows in set (0.00 sec)
mysql>
An INNER JOIN does a full join, just like the first example, and the word OUTER may be added after the word LEFT or RIGHT in the last two examples - it's provided for ODBC compatability and doesn't add an extra capabilities.
Tuesday, January 1, 2008
Java API for XML Processing
The Java API for XML Processing (JAXP) is for processing XML data using applications written in the Java programming language. JAXP leverages the parser standards Simple API for XML Parsing (SAX) and Document Object Model (DOM) so that you can choose to parse your data as a stream of events or to build an object representation of it. JAXP also supports the Extensible Stylesheet Language Transformations (XSLT) standard, giving you control over the presentation of the data and enabling you to convert the data to other XML documents or to other formats, such as HTML. JAXP also provides namespace support, allowing you to work with DTDs that might otherwise have naming conflicts.
Designed to be flexible, JAXP allows you to use any XML-compliant parser from within your application. It does this with what is called a pluggability layer, which lets you plug in an implementation of the SAX or DOM API. The pluggability layer also allows you to plug in an XSL processor, letting you control how your XML data is displayed.
The basic outline of the SAX parsing APIs are shown in Figure 4-1. To start the process, an instance of the SAXParserFactory class is used to generate an instance of the parser.
The main JAXP APIs are defined in the javax.xml.parsers package. That package contains vendor-neutral factory classes--SAXParserFactory, DocumentBuilderFactory, and TransformerFactory--which give you a SAXParser, a DocumentBuilder, and an XSLT transformer, respectively. DocumentBuilder, in turn, creates a DOM-compliant Document object.
The factory APIs let you plug in an XML implementation offered by another vendor without changing your source code. The implementation you get depends on the setting of the javax.xml.parsers.SAXParserFactory, javax.xml.parsers.DocumentBuilderFactory, and javax.xml.transform.TransformerFactory system properties, using System.setProperties() in the code, in an Ant build script, or -DpropertyName="..." on the command line. The default values (unless overridden at runtime on the command line or in the code) point to Sun's implementation.
The SAX and DOM APIs are defined by the XML-DEV group and by the W3C, respectively. The libraries that define those APIs are as follows:
javax.xml.parsers: The JAXP APIs, which provide a common interface for different vendors' SAX and DOM parsers
org.w3c.dom: Defines the Document class (a DOM) as well as classes for all the components of a DOM
org.xml.sax: Defines the basic SAX APIs
javax.xml.transform: Defines the XSLT APIs that let you transform XML into other forms
The Simple API for XML (SAX) is the event-driven, serial-access mechanism that does element-by-element processing. The API for this level reads and writes XML to a data repository or the web. For server-side and high-performance applications, you will want to fully understand this level. But for many applications, a minimal understanding will suffice.
The DOM API is generally an easier API to use. It provides a familiar tree structure of objects. You can use the DOM API to manipulate the hierarchy of application objects it encapsulates. The DOM API is ideal for interactive applications because the entire object model is present in memory, where it can be accessed and manipulated by the user.
On the other hand, constructing the DOM requires reading the entire XML structure and holding the object tree in memory, so it is much more CPU- and memory-intensive. For that reason, the SAX API tends to be preferred for server-side applications and data filters that do not require an in-memory representation of the data.
Finally, the XSLT APIs defined in javax.xml.transform let you write XML data to a file or convert it into other forms. And, as you'll see in the XSLT section of this tutorial, you can even use it in conjunction with the SAX APIs to convert legacy data to XML.

The parser wraps a SAXReader object. When the parser's parse() method is invoked, the reader invokes one of several callback methods implemented in the application. Those methods are defined by the interfaces ContentHandler, ErrorHandler, DTDHandler, and EntityResolver.
Here is a summary of the key SAX APIs:
SAXParserFactory
A SAXParserFactory object creates an instance of the parser determined by the system property, javax.xml.parsers.SAXParserFactory.
SAXParser
The SAXParser interface defines several kinds of parse() methods. In general, you pass an XML data source and a DefaultHandler object to the parser, which processes the XML and invokes the appropriate methods in the handler object.
SAXReader
The SAXParser wraps a SAXReader. Typically, you don't care about that, but every once in a while you need to get hold of it using SAXParser's getXMLReader() so that you can configure it. It is the SAXReader that carries on the conversation with the SAX event handlers you define.
DefaultHandler
Not shown in the diagram, a DefaultHandler implements the ContentHandler, ErrorHandler, DTDHandler, and EntityResolver interfaces (with null methods), so you can override only the ones you're interested in.
ContentHandler
Methods such as startDocument, endDocument, startElement, and endElement are invoked when an XML tag is recognized. This interface also defines the methods characters and processingInstruction, which are invoked when the parser encounters the text in an XML element or an inline processing instruction, respectively.
ErrorHandler
Methods error, fatalError, and warning are invoked in response to various parsing errors. The default error handler throws an exception for fatal errors and ignores other errors (including validation errors). That's one reason you need to know something about the SAX parser, even if you are using the DOM. Sometimes, the application may be able to recover from a validation error. Other times, it may need to generate an exception. To ensure the correct handling, you'll need to supply your own error handler to the parser.
DTDHandler
Defines methods you will generally never be called upon to use. Used when processing a DTD to recognize and act on declarations for an unparsed entity.
EntityResolver
The resolveEntity method is invoked when the parser must identify data identified by a URI. In most cases, a URI is simply a URL, which specifies the location of a document, but in some cases the document may be identified by a URN--a public identifier, or name, that is unique in the web space. The public identifier may be specified in addition to the URL. The EntityResolver can then use the public identifier instead of the URL to find the document--for example, to access a local copy of the document if one exists.
A typical application implements most of the ContentHandler methods, at a minimum. Because the default implementations of the interfaces ignore all inputs except for fatal errors, a robust implementation may also want to implement the ErrorHandler methods.
The SAX Packages
The SAX parser is defined in the packages listed in Table 4-1.
Table 4-1 SAX Packages Package Description
org.xml.sax Defines the SAX interfaces. The name org.xml is the package prefix that was settled on by the group that defined the SAX API.
org.xml.sax.ext Defines SAX extensions that are used for doing more sophisticated SAX processing--for example, to process a document type definition (DTD) or to see the detailed syntax for a file.
org.xml.sax.helpers Contains helper classes that make it easier to use SAX--for example, by defining a default handler that has null methods for all the interfaces, so that you only need to override the ones you actually want to implement.
javax.xml.parsers Defines the SAXParserFactory class, which returns the SAXParser. Also defines exception classes for reporting errors.
The Document Object Model APIs
Figure 4-2 shows the DOM APIs in action.

You use the javax.xml.parsers.DocumentBuilderFactory class to get a DocumentBuilder instance, and you use that instance to produce a Document object that conforms to the DOM specification. The builder you get, in fact, is determined by the system property javax.xml.parsers.DocumentBuilderFactory, which selects the factory implementation that is used to produce the builder. (The platform's default value can be overridden from the command line.)
You can also use the DocumentBuilder newDocument() method to create an empty Document that implements the org.w3c.dom.Document interface. Alternatively, you can use one of the builder's parse methods to create a Document from existing XML data. The result is a DOM tree like that shown in Figure 4-2.
--------------------------------------------------------------------------------
Note: Although they are called objects, the entries in the DOM tree are actually fairly low-level data structures. For example, consider this structure:blue . There is an element node for the color tag, and under that there is a text node that contains the data, blue! This issue will be explored at length in the DOM section of the tutorial, but developers who are expecting objects are usually surprised to find that invoking getNodeValue() on the element node returns nothing! For a truly object-oriented tree, see the JDOM API at http://www.jdom.org.
--------------------------------------------------------------------------------
The DOM Packages
The Document Object Model implementation is defined in the packages listed in Table 4-2.
Table 4-2 DOM Packages Package Description
org.w3c.dom Defines the DOM programming interfaces for XML (and, optionally, HTML) documents, as specified by the W3C.
javax.xml.parsers Defines the DocumentBuilderFactory class and the DocumentBuilder class, which returns an object that implements the W3C Document interface. The factory that is used to create the builder is determined by the javax.xml.parsers system property, which can be set from the command line or overridden when invoking the new Instance method. This package also defines the ParserConfigurationException class for reporting errors.
The Extensible Stylesheet Language Transformations APIs
Figure 4-3 shows the XSLT APIs in action.
A TransformerFactory object is instantiated and used to create a Transformer. The source object is the input to the transformation process. A source object can be created from a SAX reader, from a DOM, or from an input stream.
Similarly, the result object is the result of the transformation process. That object can be a SAX event handler, a DOM, or an output stream.
When the transformer is created, it can be created from a set of transformation instructions, in which case the specified transformations are carried out. If it is created without any specific instructions, then the transformer object simply copies the source to the result.
The XSLT Packages
The XSLT APIs are defined in the packages shown in Table 4-3.

Table 4-3 XSLT Packages Package Description
javax.xml.transform Defines the TransformerFactory and Transformer classes, which you use to get an object capable of doing transformations. After creating a transformer object, you invoke its transform() method, providing it with an input (source) and output (result).
javax.xml.transform.dom Classes to create input (source) and output (result) objects from a DOM.
javax.xml.transform.sax Classes to create input (source) objects from a SAX parser and output (result) objects from a SAX event handler.
javax.xml.transform.stream Classes to create input (source) objects and output (result) objects from an I/O stream.
Simple API for XML (SAX), an event-driven, serial-access mechanism for accessing XML documents. This protocol is frequently used by servlets and network-oriented programs that need to transmit and receive XML documents, because it's the fastest and least memory-intensive mechanism that is currently available for dealing with XML documents, other than StAX.
SAX is an event-driven model (you provide the callback methods, and the parser invokes them as it reads the XML data), and that makes it harder to visualize. Finally, you can't "back up" to an earlier part of the document, or rearrange it, any more than you can back up a serial data stream or rearrange characters you have read from that stream.
For those reasons, developers who are writing a user-oriented application that displays an XML document and possibly modifies it will want to use the DOM mechanism
even if you plan to build DOM applications exclusively, there are several important reasons for familiarizing yourself with the SAX model:
Same Error Handling: The same kinds of exceptions are generated by the SAX and DOM APIs, so the error handling code is virtually identical.
Handling Validation Errors: By default, the specifications require that validation errors (which you'll learn more about in this part of the tutorial) are ignored. If you want to throw an exception in the event of a validation error (and you probably do), then you need to understand how SAX error handling works.
Converting Existing Data: There is a mechanism we can use to convert an existing data set to XML. However, taking advantage of that mechanism requires an understanding of the SAX model.
SAX is fast and efficient, but its event model makes it most useful for such state-independent filtering. For example, a SAX parser calls one method in your application when an element tag is encountered and calls a different method when text is found. If the processing you're doing is state-independent (meaning that it does not depend on the elements have come before), then SAX works fine.
On the other hand, for state-dependent processing, where the program needs to do one thing with the data under element A but something different with the data under element B, then a pull parser such as the Streaming API for XML (StAX) would be a better choice. With a pull parser, you get the next node, whatever it happens to be, at any point in the code that you ask for it. So it's easy to vary the way you process text (for example), because you can process it multiple places in the program.
SAX requires much less memory than DOM, because SAX does not construct an internal representation (tree structure) of the XML data, as a DOM does. Instead, SAX simply sends data to the application as it is read; your application can then do whatever it wants to do with the data it sees.
Pull parsers and the SAX API both act like a serial I/O stream. You see the data as it streams in, but you can't go back to an earlier position or leap ahead to a different position. In general, such parsers work well when you simply want to read data and have the application act on it.
But when you need to modify an XML structure--especially when you need to modify it interactively--an in-memory structure makes more sense. DOM is one such model.
Designed to be flexible, JAXP allows you to use any XML-compliant parser from within your application. It does this with what is called a pluggability layer, which lets you plug in an implementation of the SAX or DOM API. The pluggability layer also allows you to plug in an XSL processor, letting you control how your XML data is displayed.
The basic outline of the SAX parsing APIs are shown in Figure 4-1. To start the process, an instance of the SAXParserFactory class is used to generate an instance of the parser.
The main JAXP APIs are defined in the javax.xml.parsers package. That package contains vendor-neutral factory classes--SAXParserFactory, DocumentBuilderFactory, and TransformerFactory--which give you a SAXParser, a DocumentBuilder, and an XSLT transformer, respectively. DocumentBuilder, in turn, creates a DOM-compliant Document object.
The factory APIs let you plug in an XML implementation offered by another vendor without changing your source code. The implementation you get depends on the setting of the javax.xml.parsers.SAXParserFactory, javax.xml.parsers.DocumentBuilderFactory, and javax.xml.transform.TransformerFactory system properties, using System.setProperties() in the code,
The SAX and DOM APIs are defined by the XML-DEV group and by the W3C, respectively. The libraries that define those APIs are as follows:
javax.xml.parsers: The JAXP APIs, which provide a common interface for different vendors' SAX and DOM parsers
org.w3c.dom: Defines the Document class (a DOM) as well as classes for all the components of a DOM
org.xml.sax: Defines the basic SAX APIs
javax.xml.transform: Defines the XSLT APIs that let you transform XML into other forms
The Simple API for XML (SAX) is the event-driven, serial-access mechanism that does element-by-element processing. The API for this level reads and writes XML to a data repository or the web. For server-side and high-performance applications, you will want to fully understand this level. But for many applications, a minimal understanding will suffice.
The DOM API is generally an easier API to use. It provides a familiar tree structure of objects. You can use the DOM API to manipulate the hierarchy of application objects it encapsulates. The DOM API is ideal for interactive applications because the entire object model is present in memory, where it can be accessed and manipulated by the user.
On the other hand, constructing the DOM requires reading the entire XML structure and holding the object tree in memory, so it is much more CPU- and memory-intensive. For that reason, the SAX API tends to be preferred for server-side applications and data filters that do not require an in-memory representation of the data.
Finally, the XSLT APIs defined in javax.xml.transform let you write XML data to a file or convert it into other forms. And, as you'll see in the XSLT section of this tutorial, you can even use it in conjunction with the SAX APIs to convert legacy data to XML.

The parser wraps a SAXReader object. When the parser's parse() method is invoked, the reader invokes one of several callback methods implemented in the application. Those methods are defined by the interfaces ContentHandler, ErrorHandler, DTDHandler, and EntityResolver.
Here is a summary of the key SAX APIs:
SAXParserFactory
A SAXParserFactory object creates an instance of the parser determined by the system property, javax.xml.parsers.SAXParserFactory.
SAXParser
The SAXParser interface defines several kinds of parse() methods. In general, you pass an XML data source and a DefaultHandler object to the parser, which processes the XML and invokes the appropriate methods in the handler object.
SAXReader
The SAXParser wraps a SAXReader. Typically, you don't care about that, but every once in a while you need to get hold of it using SAXParser's getXMLReader() so that you can configure it. It is the SAXReader that carries on the conversation with the SAX event handlers you define.
DefaultHandler
Not shown in the diagram, a DefaultHandler implements the ContentHandler, ErrorHandler, DTDHandler, and EntityResolver interfaces (with null methods), so you can override only the ones you're interested in.
ContentHandler
Methods such as startDocument, endDocument, startElement, and endElement are invoked when an XML tag is recognized. This interface also defines the methods characters and processingInstruction, which are invoked when the parser encounters the text in an XML element or an inline processing instruction, respectively.
ErrorHandler
Methods error, fatalError, and warning are invoked in response to various parsing errors. The default error handler throws an exception for fatal errors and ignores other errors (including validation errors). That's one reason you need to know something about the SAX parser, even if you are using the DOM. Sometimes, the application may be able to recover from a validation error. Other times, it may need to generate an exception. To ensure the correct handling, you'll need to supply your own error handler to the parser.
DTDHandler
Defines methods you will generally never be called upon to use. Used when processing a DTD to recognize and act on declarations for an unparsed entity.
EntityResolver
The resolveEntity method is invoked when the parser must identify data identified by a URI. In most cases, a URI is simply a URL, which specifies the location of a document, but in some cases the document may be identified by a URN--a public identifier, or name, that is unique in the web space. The public identifier may be specified in addition to the URL. The EntityResolver can then use the public identifier instead of the URL to find the document--for example, to access a local copy of the document if one exists.
A typical application implements most of the ContentHandler methods, at a minimum. Because the default implementations of the interfaces ignore all inputs except for fatal errors, a robust implementation may also want to implement the ErrorHandler methods.
The SAX Packages
The SAX parser is defined in the packages listed in Table 4-1.
Table 4-1 SAX Packages Package Description
org.xml.sax Defines the SAX interfaces. The name org.xml is the package prefix that was settled on by the group that defined the SAX API.
org.xml.sax.ext Defines SAX extensions that are used for doing more sophisticated SAX processing--for example, to process a document type definition (DTD) or to see the detailed syntax for a file.
org.xml.sax.helpers Contains helper classes that make it easier to use SAX--for example, by defining a default handler that has null methods for all the interfaces, so that you only need to override the ones you actually want to implement.
javax.xml.parsers Defines the SAXParserFactory class, which returns the SAXParser. Also defines exception classes for reporting errors.
The Document Object Model APIs
Figure 4-2 shows the DOM APIs in action.

You use the javax.xml.parsers.DocumentBuilderFactory class to get a DocumentBuilder instance, and you use that instance to produce a Document object that conforms to the DOM specification. The builder you get, in fact, is determined by the system property javax.xml.parsers.DocumentBuilderFactory, which selects the factory implementation that is used to produce the builder. (The platform's default value can be overridden from the command line.)
You can also use the DocumentBuilder newDocument() method to create an empty Document that implements the org.w3c.dom.Document interface. Alternatively, you can use one of the builder's parse methods to create a Document from existing XML data. The result is a DOM tree like that shown in Figure 4-2.
--------------------------------------------------------------------------------
Note: Although they are called objects, the entries in the DOM tree are actually fairly low-level data structures. For example, consider this structure:
--------------------------------------------------------------------------------
The DOM Packages
The Document Object Model implementation is defined in the packages listed in Table 4-2.
Table 4-2 DOM Packages Package Description
org.w3c.dom Defines the DOM programming interfaces for XML (and, optionally, HTML) documents, as specified by the W3C.
javax.xml.parsers Defines the DocumentBuilderFactory class and the DocumentBuilder class, which returns an object that implements the W3C Document interface. The factory that is used to create the builder is determined by the javax.xml.parsers system property, which can be set from the command line or overridden when invoking the new Instance method. This package also defines the ParserConfigurationException class for reporting errors.
The Extensible Stylesheet Language Transformations APIs
Figure 4-3 shows the XSLT APIs in action.
A TransformerFactory object is instantiated and used to create a Transformer. The source object is the input to the transformation process. A source object can be created from a SAX reader, from a DOM, or from an input stream.
Similarly, the result object is the result of the transformation process. That object can be a SAX event handler, a DOM, or an output stream.
When the transformer is created, it can be created from a set of transformation instructions, in which case the specified transformations are carried out. If it is created without any specific instructions, then the transformer object simply copies the source to the result.
The XSLT Packages
The XSLT APIs are defined in the packages shown in Table 4-3.

Table 4-3 XSLT Packages Package Description
javax.xml.transform Defines the TransformerFactory and Transformer classes, which you use to get an object capable of doing transformations. After creating a transformer object, you invoke its transform() method, providing it with an input (source) and output (result).
javax.xml.transform.dom Classes to create input (source) and output (result) objects from a DOM.
javax.xml.transform.sax Classes to create input (source) objects from a SAX parser and output (result) objects from a SAX event handler.
javax.xml.transform.stream Classes to create input (source) objects and output (result) objects from an I/O stream.
Simple API for XML (SAX), an event-driven, serial-access mechanism for accessing XML documents. This protocol is frequently used by servlets and network-oriented programs that need to transmit and receive XML documents, because it's the fastest and least memory-intensive mechanism that is currently available for dealing with XML documents, other than StAX.
SAX is an event-driven model (you provide the callback methods, and the parser invokes them as it reads the XML data), and that makes it harder to visualize. Finally, you can't "back up" to an earlier part of the document, or rearrange it, any more than you can back up a serial data stream or rearrange characters you have read from that stream.
For those reasons, developers who are writing a user-oriented application that displays an XML document and possibly modifies it will want to use the DOM mechanism
even if you plan to build DOM applications exclusively, there are several important reasons for familiarizing yourself with the SAX model:
Same Error Handling: The same kinds of exceptions are generated by the SAX and DOM APIs, so the error handling code is virtually identical.
Handling Validation Errors: By default, the specifications require that validation errors (which you'll learn more about in this part of the tutorial) are ignored. If you want to throw an exception in the event of a validation error (and you probably do), then you need to understand how SAX error handling works.
Converting Existing Data: There is a mechanism we can use to convert an existing data set to XML. However, taking advantage of that mechanism requires an understanding of the SAX model.
SAX is fast and efficient, but its event model makes it most useful for such state-independent filtering. For example, a SAX parser calls one method in your application when an element tag is encountered and calls a different method when text is found. If the processing you're doing is state-independent (meaning that it does not depend on the elements have come before), then SAX works fine.
On the other hand, for state-dependent processing, where the program needs to do one thing with the data under element A but something different with the data under element B, then a pull parser such as the Streaming API for XML (StAX) would be a better choice. With a pull parser, you get the next node, whatever it happens to be, at any point in the code that you ask for it. So it's easy to vary the way you process text (for example), because you can process it multiple places in the program.
SAX requires much less memory than DOM, because SAX does not construct an internal representation (tree structure) of the XML data, as a DOM does. Instead, SAX simply sends data to the application as it is read; your application can then do whatever it wants to do with the data it sees.
Pull parsers and the SAX API both act like a serial I/O stream. You see the data as it streams in, but you can't go back to an earlier position or leap ahead to a different position. In general, such parsers work well when you simply want to read data and have the application act on it.
But when you need to modify an XML structure--especially when you need to modify it interactively--an in-memory structure makes more sense. DOM is one such model.
Subscribe to:
Posts (Atom)