JDBC Sample
/
Mitrovic Ivan, August 1997. /
This sample was written as an example for my article "JDBC" written for the most popular Yugoslav computer magazine PC Press.
1. Model explanation
JDBC is a part of the Java Enterprise API, and is
the first cross platform, cross database approach to databases access from
Java program. JDBC supports both the two - tier
and three - tier Client / Server system tiers. Two - tier
system involves GUI and business logic which are on the client system,
and the database can be on the client or on a Server.
Three - tier system strategy is determined
by three levels. GUI is based on the client system,
which is first level, middle tier is application based on a Server
(second level), which is connected to aspecified database (third level).
As a sample of three - tier
system I developed simple Java Client / Server system which is connected
to MS Access97 database based on Server.
MS Access97 database, which represents virtual classroom,
consists of three tables:
Students StudentsCourses Courses
ID - AutoNumber (primary key)
StudentID - Number (long Integer)
ID - Number (long Integer)
Name - Text
CourseID - Number (long Integer)
Title - Text
Sex - Text
Age - Number (long Integer)
Email - Text
As You can see, whenever particular Student
selects a course to attend, Student's ID
and Course's ID are inserted into
StudentsCourses Table. So, we can say that Students
Table and Courses Table are related over the StudentsCourses
Table.
As a first operation, Student can fill
her data into the Students Table. In order to do
it, press ' Add to Student's Database '
button. Fill in requested informations about
Yourself, and press 'Add to database' button. You
will see the generated SQL
INSERT sentence which is, via sockets, delivered
to Java Server application and sent to MSAccess97 database.
You can't
change SQL sentence, it is automaticly generated
by a client. Server takes the response from databse
via JDBC - ODBC
bridge, and pass it to client.You can see the Server
generated report in TextArea control labelled as 'Report'.
If the sentence
was executed succesfully, You will see the message
'SQL sentence succesfully executed. Rows affected: 1'. If something
went wrong, You will see the Error message in Report
TextArea control.
When Student wants to apply on a particular Course,
she will choose the second option (press 'Apply to a Course'
button on the main menu). By choosing
this option, Frame with two Choice controls will
appear. You can see that the first
Choice control contains all records from Students table (columns
ID and Name), and the second Choice control contains
Course ID and Title. Whenever this option is selected,
Choice controls are automaticly updated.
Client sends SQL SELECT sentence to
Server ( SELECT ID, Name FROM Students, SELECT ID, Title
FROM Courses ) and, after the
database 'treatmant', selected records are automaticly
added to Choice controls. In order to check this, go back to
first option, insert new student, go on second option and You will see
the students Name and ID as the last Choice Item.
When 'Apply to a course' button is
pressed the client generates SQL INSERT sentence in order to insert
records in the StudentsCourses Table.
Third option, 'Explore the Database' is
the most powerfull. You can send Your own
SQL querries to database
as well as querries generated by little querry
builder. Querry builder builds
the SQL SELECT sentence
based on selected options. Simply
check the Columns You want to see in Report, insert conditions,
orders and press ' Make Querry ' button. You will
see the generated SQL sentence in the TextArea labelled as 'SQL sentence
sent to a database'. If You want to
execute that sentence press ' Execute
Querry ' button, or You can simply
type Your own SQL sentence and press
'Execute Querry' button. You can even send 'UPDATE' and 'DELETE' SQL sentences.
The sentence, for example, can be:
INSERT INTO Courses
(Title) VALUES ('New Course Title'); This
will insert new course Titled as 'New Course Title'
in Table Courses or SELECT COUNT (*) FROM Students
WHERE Sex = 'Female', which will retrive
how many female Students are in the Students Table, etc. Use
the Querry builder first to see the SQL syntax, and You
will be able to make Your own Querrys
easy. Especcialy be aware of the indexes. If You want
to make reports with records from b
oth Students and Courses Table, don't forget to include 'WHERE Students.ID
= StudentsCourses.StudentID AND Course.ID =
StudentsCourses.CourseID', because those two Tables
are related via StudentsCourses Table. If You,
for example, want to
see what Courses female Students attend and
You want Querry builder to generate
SQL sentence, check Name, Title, in WHERE
clause select radio button Female, select ORDER BY if You want, press 'Make
Querry' button and when sentence is
generated, press 'Execute Querry' button. You will see the results in Report
TextArea control. Or, for example, if You want to set the right age for
all ladies, simply type UPDATE Students SET Age = 70 WHERE Sex = 'Female';
NOTE:
You are restricted to create new tables
('CREATE' sentence) or drop existing tables
('DROP' sentence). Server checks
SQL sentence and doesn't execute 'CREATE' and 'DROP'
sentences.
2. How does this thing work?
Java Server application, which is based on server
establishes socket connection on port 9000. Server accepts clients
and adds each client to Vector of Channels, which is
class that extends Thread. The code is simply straightforward,
and if You have ever made, for example, Java Chat system, You
will easilly understand it. But, there are two things that need
to be e xplained. First, the Server
response is not sent to all clients (like, for example in Chat system)
but only to a particular client that sent the request
to Server. The code which do this:
int position = vektor.indexOf (this);
// finding the position of particular client in Vector vektor
Channel c = (Channel) vektor.elementAt (position);
// extracting the particular client
try {
synchronized (c.dos) {
c.dos.writeUTF (msg1);
// writing to DataOutputStream
}
c.dos.flush ();
}
...
This is, for example, analogous to sending the
private messages in Chat systems.
Second, the Server application doesn't know which
SQL statement will be sent from client. If the statement
is, for example,
INSERT or UPDATE, number of affected rows will be
returned as a response . If number is 0, that means that no rows
were affected or that 'CREATE' or 'DROP' statement was executed. In this
example, Server enables executing of 'CREATE' and
'DROP' sentences. As we don't know what kind of SQL sentence will be sent
from client, we can't use executeUpdate (which stands for ' INSERT ' and
' UPDATE ' sentences ) or executeQuerry method ( which is used for
' SELECT ' statements ). In order to accomplish this we will use
the execute method which, as result can retreive int
( for ' INSERT ' and ' UPDATE ' ),
which gives the number of rows affected by
the statement, or can retreive ResultSet if sentence was ' SELECT ' type.
So, we
will check what kind of response is retrieved after
the SQL sentence execution. If it is int, we will send
appropriate message and if it is a ResulSet, we will
extract result columns using the ResultSetMetaData
and send them to client. Code
which accomplishes that responsible task:
try {
// executing of SQL sentence which is contained in
String msg
stmt.execute (msg);
}
catch (Exception e) {
e.printStackTrace ();
msg1 = "Error! Check the SQL Sentence!"
+ "\n" + e.toString() +
"\nServer message: end";
send ();
return;
}
try {
int rows = stmt.getUpdateCount ();
msg1 = "";
// if it was 'INSERT' or 'UPDATE'
if (rows >= 0) {
msg1 = "The sentence was
succesfully executed. Rows affected: " + rows +
"\nServer message: end";
}
ResultSet result = stmt.getResultSet ();
// if it was 'SELECT'
if (result != null) {
try {
ResultSetMetaData rsmd =
result.getMetaData ();
int cols = rsmd.getColumnCount
();
while (result.next ()) {
for (int i = 1;
i <= cols; i ++) {
if (i > 1)
msg1 = msg1 + " , ";
msg1 = msg1
+ result.getString (i);
}
// sending resulted row to client
send ();
pass = true;
}
msg1 = "Server message:
end";
...
Source code of Server.java.
Client , SQLclient.class which extends Applet establishes
connection with Serveron 9000 port, receives user's GUI actions,
generates SQL sentences and send them to Server application. The code is
straightforward and only interesting thing can be
creating of Choice controls which contain database
data.
// String select can be SELECT ID, Name FROM Students
or
// SELECT ID, Title FROM Courses
public Choice makeChoice (String select) {
Choice ch;
ch = new Choice ();
try {
//sending SQL sentence to Server
dos.writeUTF (select);
dos.flush ();
}
catch (IOException e) {
getAppletContext ().showStatus (e.toString
());
}
String line = "";
try {
while (!line.endsWith ("Server message: end")) {
//reading the Server response, line by line
//adding line to Choice until Server response ends
line = dis.readUTF ();
if (!line.endsWith ("Server
message: end"))
ch.addItem (line);
}
}
catch (IOException e) {
getAppletContext ().showStatus (e.toString
());
}
return ch;
}
...
Source code: SQLclient.java,
InputFrame.java, ImageButton.java
3. Well...
JDBC gives Java enormus power in approach of databases
access. Java application can connect several databases on several hosts.
Just imagine enterprise whose clients and employees can
access databases on enterprise's host across
Internet or intranet.
Sample above shows only the basics of JDBC. It uses
old fashion Socket connection to a Server. The best approach would
be to communicate via ORB, where client can access particular method in
Server application and vice versa. But,
for sake of simplicity, I didn't consider that approach.
There are more powerful posibilities JDBC provides,
such as Prepared Statements or
Callable Statements, Transactions etc. It is up to You
to experiment with the particular database.
JDBC has some handycaps. It doesn't support Bookmarks
and Cursor functions which are very important, for example,
for
"scrolling" through the resulted rows (You
can make improvisation like adding resulted rows to vector
or array and scrooll through it.)
NOTE: CODE WAS COMPILED WITH JDK 1.1.3 BUT DEPRECATED EVENT HANDLING IS USED IN ORDER TO BE SUPPORTED BY BROWSERS THAT DON'T SUPPORT JDK 1.1
3. ...let's see it
.
.