 |
 |
15) Informatique distribuée |
|
 |
|
Texte original |
 |
Traducteur :
Jean-Pierre Vidal, Alban Peignier |
|
 |
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
If the load statement is wrong,
you’ll get an exception at this point. To test whether your driver load
statement is working correctly, comment out the code after the statement and up
to the catch clause; if the program throws no exceptions it means that
the driver is loading properly.
|
 |
Si l'instruction de chargement est incorrecte, on récupérera une exception
à ce moment-là. Pour tester si l'instruction de chargement du driver fonctionne correctement,
mettez en commentaire le code après l'instruction jusqu'à la clause catch ;
si le programme ne lance pas d'exceptions cela signifie que le driver est correctement
chargé.
|
 |
 |
 |
Step 2: Configure the database
|
 |
Étape 2 : Configurer la base de données
|
 |
 |
 |
Again, this is specific to 32-bit
Windows; you might need to do some research to figure it out for your own
platform.
|
 |
Ici aussi, ceci est spécifique à Windows 32-bits ; vous devrez sans
doute rechercher quelque peu pour savoir comment faire sur votre propre plate-forme.
|
 |
 |
 |
First, open the control panel. You might
find two icons that say “ODBC.” You must use the one that says
“32bit ODBC,” since the other one is for backward compatibility with
16-bit ODBC software and will produce no results for JDBC. When you open the
“32bit ODBC” icon, you’ll see a tabbed dialog with a number of
tabs, including “User DSN,” “System DSN,” “File
DSN,” etc., in which “DSN” means “Data Source
Name.” It turns out that for the JDBC-ODBC bridge, the only place where
it’s important to set up your database is “System DSN,” but
you’ll also want to test your configuration and create queries, and for
that you’ll also need to set up your database in “File DSN.”
This will allow the Microsoft Query tool (that comes with Microsoft Office) to
find the database. Note that other query tools are also available from other
vendors.
|
 |
Pour commencer, ouvrir le panneau de configuration. Vous devriez trouver
deux icônes traitant de ODBC. « Il faut utiliser celle qui parle de ODBC 32-bits, l'autre n'étant
là que pour la compatibilité ascendante avec le software ODBC 16-bits, et ne serait d'aucune
utilité pour JDBC. En ouvrant l'icône ODBC 32-bits, vous allez voir une boîte de dialogue à
onglets, parmi lesquels User DSN, » System DSN,[ File DSN, « etc., DSN signifiant » Data Source
Name. Il apparaît que pour la passerelle JDBC-ODBC, le seul endroit important pour créer votre base
de données est System DSN, mais vous devez également tester votre configuration et créer des
demandes, et pour cela vous devez également créer votre base dans File DSN. Ceci permet à l'outil
Microsoft Query (qui fait partie de Microsoft Office) de trouver la base. Remarquez que d'autres
outils de demande sont disponibles chez d'autres vendeurs.
|
 |
 |
 |
The most interesting database is one that
you’re already using. Standard ODBC supports a number of different file
formats including such venerable workhorses as DBase. However, it also includes
the simple “comma-separated ASCII” format, which virtually every
data tool has the ability to write. In my case, I just took my
“people” database that I’ve been maintaining for years using
various contact-management tools and exported it as a comma-separated ASCII file
(these typically have an extension of .csv). In the “System
DSN” section I chose “Add,” chose the text driver to handle my
comma-separated ASCII file, and then un-checked “use current
directory” to allow me to specify the directory where I exported the data
file.
|
 |
La base de données la plus intéressante est l'une de celles que vous
utilisez déjà. Le standard ODBC supporte différents formats de fichier y compris les vénérables
chevaux de labour tels que DBase. Cependant, il inclut aussi le format « ASCII, champs séparés
par des virgules », que n'importe quel outil de données est capable de créer. En ce qui me
concerne, j'ai simplement pris ma base de données « people » « que j'ai maintenue depuis
des années au moyen de divers outils de gestion d'adresse et que j'ai exportée en tant que fichier
« ASCII à champs séparés par des virgules » (ils ont généralement une extension
.csv). Dans la section » System DSN « j'ai choisi [Add, « puis le driver texte
pour mon fichier ASCII csv, puis dé-coché « [use current directory » « pour me permettre
de spécifier le répertoire où j'avais exporté mon fichier de données.
|
 |
 |
 |
You’ll notice when you do this that
you don’t actually specify a file, only a directory. That’s because
a database is typically represented as a collection of files under a single
directory (although it could be represented in other forms as well). Each file
usually contains a single table, and the SQL statements can produce results that
are culled from multiple tables in the database (this is called a
join). A database that
contains only a single table (like my “people” database) is usually
called a
flat-file
database. Most problems that go beyond the simple storage and retrieval of
data generally require multiple tables that must be related by joins to produce
the desired results, and these are called
relational
databases.
|
 |
Remarquez bien qu'en faisant cela vous ne spécifiez pas réellement un
fichier, mais seulement un répertoire. Ceci parce qu'une base de données se trouve souvent sous la
forme d'un ensemble de fichiers situés dans un même répertoire (bien qu'elle puisse aussi bien se
trouver sous d'autres formes). Chaque fichier contient généralement une seule table, et une
instruction SQL peut produire des résultats issus de plusieurs tables de la base (on appelle ceci
une relation). Une base contenant une seule table (comme ma base « [people »)
est généralement appelée flat-file database. La plupart des problèmes qui vont au-delà du
simple stockage et déstockage de données nécessitent des tables multiples mises en relation par des
relationsafin de fournir les résultats voulus, on les appelle bases de données
relationnelles.
|
 |
 |
 |
Step 3: Test the configuration
|
 |
Étape 3 : Tester la configuration
|
 |
 |
 |
To test the configuration you’ll
need a way to discover whether the database is visible from a program that
queries it. Of course, you can simply run the JDBC program example above, up to
and including the statement:
|
 |
Pour tester la configuration il faut trouver un moyen de savoir si la base
est visible depuis un programme qui l'interrogerait. Bien entendu, on peut tout simplement lancer
le programme exemple JDBC ci-dessus, en incluant l'instruction :
|
 |
 |
 |
Connection c = DriverManager.getConnection(
dbUrl, user, password);
|
 |
Connection c = DriverManager.getConnection( dbUrl, user, password);
|
 |
 |
 |
If an exception is thrown, your
configuration was incorrect.
|
 |
Si une exception est lancée, c'est que la configuration était
incorrecte.
|
 |
 |
 |
However, it’s useful to get a
query-generation tool involved at this point. I used Microsoft Query that came
with Microsoft Office, but you might prefer something else. The query tool must
know where the database is, and Microsoft Query required that I go to the ODBC
Administrator’s “File DSN” tab and add a new entry there,
again specifying the text driver and the directory where my database lives. You
can name the entry anything you want, but it’s helpful to use the same
name you used in “System DSN.”
|
 |
Cependant, à ce point, il est très utile d'utiliser un outil de génération
de requêtes. J'ai utilisé Microsoft Query qui est livré avec Microsoft Office, mais vous pourriez
préférer un autre outil. L'outil de requête doit connaître l'emplacement de la base, et Microsoft
Query exigeait que j'ouvre l'onglet administrateur ODBC » File DSN « et que j'ajoute une nouvelle
entrée, en spécifiant à nouveau le driver texte et le répertoire contenant ma base de données. On
peut donner n'importe quel nom à cette entrée, mais il est préférable d'utiliser le nom déjà fourni
dans l'onglet » System DSN.]
|
 |
 |
 |
Once you’ve done this, you will see
that your database is available when you create a new query using your query
tool.
|
 |
Ceci fait, vous saurez si votre base est disponible en créant une nouvelle
requête au moyen de votre générateur de requêtes.
|
 |
 |
 |
Step 4: Generate your SQL query
|
 |
Étape 4 : Générer votre requête SQL
|
 |
 |
 |
The query that I created using Microsoft
Query not only showed me that my database was there and in good order, but it
also automatically created the SQL code that I needed to insert into my Java
program. I wanted a query that would search for records that had the last name
that was typed on the command line when starting the Java program. So as a
starting point, I searched for a specific last name, “Eckel.” I also
wanted to display only those names that had email addresses associated with
them. The steps I took to create this query were:
|
 |
La requête créée avec Microsoft Query m'a montré que ma base de données
était là et prête à fonctionner, mais a aussi généré automatiquement le code SQL dont j'avais
besoin pour l'insérer dans mon programme Java. Je voulais une requête qui recherche les
enregistrements contenant le même nom que celui qui était fourni sur la ligne de commande d'appel
du programme. Ainsi pour commencer, j'ai cherché un nom particulier, [Eckel. ]Je voulais également
n'afficher que ceux qui avaient une adresse email associée. Voici les étapes que j'ai suivi pour
créer cette requête :
|
 |
 |
 |
- Start a new query and use
the Query Wizard. Select the “people” database. (This is the
equivalent of opening the database connection using the appropriate database
URL.)
- Select the
“people” table within the database. From within the table, choose
the columns FIRST, LAST, and
EMAIL.
- Under
“Filter Data,” choose LAST and select “equals” with an
argument of “Eckel.” Click the “And” radio
button.
- Choose EMAIL
and select “Is not
Null.”
- Under
“Sort By,” choose
FIRST.
|
 |
- Ouvrir une nouvelle requête au moyen du Query Wizard. Sélectionner la base
« [people » (ceci est équivalent à ouvrir la connexion avec la base au moyen de l'URL de
base de données appropriée).
- Dans la base, sélectionner la table « people ». Dans la table,
choisir les colonnes FIRST, LAST, et EMAIL.
- Sous « Filter Data », choisir LAST et sélectionner
« equals » avec comme argument « Eckel ». Cliquer sur le bouton radio
« And ».
- Choisir EMAIL et sélectionner « Is not Null ».]
- Sous « Sort By », « choisir FIRST.
|
 |
 |
 |
The result of this
query will show you whether you’re getting what you want.
|
 |
Le résultat de cette requête vous montrera si vous obtenez ce que vous
vouliez.
|
 |
 |
 |
Now you can press the SQL button and
without any research on your part, up will pop the correct SQL code, ready for
you to cut and paste. For this query, it looked like this:
|
 |
Maintenant cliquez sur le bouton SQL et sans aucun effort de votre part
vous verrez apparaître le code SQL correct, prêt pour un copier-coller. Le voici pour cette
requête :
|
 |
 |
 |
SELECT people.FIRST, people.LAST, people.EMAIL
FROM people.csv people
WHERE (people.LAST='Eckel') AND
(people.EMAIL Is Not Null)
ORDER BY people.FIRST
|
 |
SELECT people.FIRST, people.LAST, people.EMAIL FROM people.csv people WHERE (people.LAST='Eckel') AND (people.EMAIL Is Not Null) ORDER BY people.FIRST
|
 |
 |
 |
Especially with more complicated queries
it’s easy to get things wrong, but by using a query tool you can
interactively test your queries and automatically generate the correct code.
It’s hard to argue the case for doing this by hand.
|
 |
Il serait très facile de se tromper dans le cas de requêtes plus
compliquées, mais en utilisant un générateur de requêtes vous pouvez tester votre requête
interactivement et générer automatiquement le code correct. Il serait difficile d'affirmer qu'il
est préférable de réaliser cela manuellement.
|
 |
 |
 |
Step 5: Modify and paste in your query
|
 |
Étape 5 : Modifier et insérer votre requête
|
 |
 |
 |
You’ll notice that the code above
looks different from what’s used in the program. That’s because the
query tool uses full qualification for all of the names, even when there’s
only one table involved. (When more than one table is involved, the
qualification prevents collisions between columns from different tables that
have the same names.) Since this query involves only one table, you can
optionally remove the “people” qualifier from most of the names,
like this:
|
 |
Remarquons que le code ci-dessus ne ressemble pas à celui qui est utilisé
dans le programme. Ceci est dû au fait que le générateur de requêtes utilise des noms complètement
qualifiés, même lorsqu'une seule table est en jeu (lorsqu'on utilise plus d'une table, la
qualification empêche les collisions entre colonnes de même nom appartenant à des tables
différentes). Puisque cette requête ne concerne qu'une seule table, on peut
- optionnellement - supprimer le qualificateur « people » dans la plupart des
noms, de cette manière :
|
 |
 |
 |
SELECT FIRST, LAST, EMAIL
FROM people.csv people
WHERE (LAST='Eckel') AND
(EMAIL Is Not Null)
ORDER BY FIRST
|
 |
SELECT FIRST, LAST, EMAIL FROM people.csv people WHERE (LAST='Eckel') AND (EMAIL Is Not Null) ORDER BY FIRST
|
 |
 |
 |
In addition, you don’t want this
program to be hard coded to look for only one name. Instead, it should hunt for
the name given as the command-line argument. Making these changes and turning
the SQL statement into a dynamically-created String
produces:
|
 |
En outre, on ne va pas coder en dur le nom à rechercher. Au lieu de cela,
il sera créé à partir du nom fourni en argument sur la ligne de commande d'appel du programme. Ces
changements effectués l'instruction SQL générée dynamiquement dans un objet String
devient :
|
 |
 |
 |
"SELECT FIRST, LAST, EMAIL " +
"FROM people.csv people " +
"WHERE " +
"(LAST='" + args[0] + "') " +
" AND (EMAIL Is Not Null) " +
"ORDER BY FIRST");
|
 |
"SELECT FIRST, LAST, EMAIL " + "FROM people.csv people " + "WHERE " + "(LAST='" + args[0 « + "') " + " AND (EMAIL Is Not Null) " + "ORDER BY FIRST");
|
 |
 |
 |
SQL has another way to insert names into
a query called
stored
procedures, which is used for speed. But for much of your database
experimentation and for your first cut, building your own query strings in Java
is fine.
|
 |
SQL possède un autre mécanisme d'insertion de noms dans une requête, appelé
procédures stockées, stored procedures, utilisées pour leur vitesse. Mais pour la plupart
de vos expérimentations sur les bases de données et pour votre apprentissage, il est bon de
construire vos chaînes de requêtes en Java.
|
 |
 |
 |
You can see from this example that by
using the tools currently available—in particular the query-building
tool—database programming with SQL and JDBC can be quite
straightforward.
|
 |
On peut voir à partir de cet exemple que l'utilisation d'outils
généralement disponibles et en particulier le générateur de requêtes simplifie la programmation
avec SQL et JDBC..
|
 |
 |
 |
A GUI version of the lookup program
|
 |
Une version GUI du programme de recherche
|
 |
 |
 |
It’s more useful to leave the
lookup program running all the time and simply switch to it and type in a name
whenever you want to look someone up. The following program creates the lookup
program as an application/applet, and it also adds name completion so the data
will show up without forcing you to type the entire last name:
|
 |
Il serait plus pratique de laisser tourner le programme en permanence et de
basculer vers lui pour taper un nom et entamer une recherche lorsqu'on en a besoin. Le programme
suivant crée le programme de recherche en tant qu'application/applet, et ajoute également une
fonctionnalité de complétion des noms afin qu'on puisse voir les données sans être obligé de taper
le nom complet :
|
 |
 |
 |
//: c15:jdbc:VLookup.java
// GUI version of Lookup.java.
// <applet code=VLookup
// width=500 height=200></applet>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.sql.*;
import com.bruceeckel.swing.*;
public class VLookup extends JApplet {
String dbUrl = "jdbc:odbc:people";
String user = "";
String password = "";
Statement s;
JTextField searchFor = new JTextField(20);
JLabel completion =
new JLabel(" ");
JTextArea results = new JTextArea(40, 20);
public void init() {
searchFor.getDocument().addDocumentListener(
new SearchL());
JPanel p = new JPanel();
p.add(new Label("Last name to search for:"));
p.add(searchFor);
p.add(completion);
Container cp = getContentPane();
cp.add(p, BorderLayout.NORTH);
cp.add(results, BorderLayout.CENTER);
try {
// Load the driver (registers itself)
Class.forName(
"sun.jdbc.odbc.JdbcOdbcDriver");
Connection c = DriverManager.getConnection(
dbUrl, user, password);
s = c.createStatement();
} catch(Exception e) {
results.setText(e.toString());
}
}
class SearchL implements DocumentListener {
public void changedUpdate(DocumentEvent e){}
public void insertUpdate(DocumentEvent e){
textValueChanged();
}
public void removeUpdate(DocumentEvent e){
textValueChanged();
}
}
public void textValueChanged() {
ResultSet r;
if(searchFor.getText().length() == 0) {
completion.setText("");
results.setText("");
return;
}
try {
// Name completion:
r = s.executeQuery(
"SELECT LAST FROM people.csv people " +
"WHERE (LAST Like '" +
searchFor.getText() +
"%') ORDER BY LAST");
if(r.next())
completion.setText(
r.getString("last"));
r = s.executeQuery(
"SELECT FIRST, LAST, EMAIL " +
"FROM people.csv people " +
"WHERE (LAST='" +
completion.getText() +
"') AND (EMAIL Is Not Null) " +
"ORDER BY FIRST");
} catch(Exception e) {
results.setText(
searchFor.getText() + "\n");
results.append(e.toString());
return;
}
results.setText("");
try {
while(r.next()) {
results.append(
r.getString("Last") + ", "
+ r.getString("fIRST") +
": " + r.getString("EMAIL") + "\n");
}
} catch(Exception e) {
results.setText(e.toString());
}
}
public static void main(String[] args) {
Console.run(new VLookup(), 500, 200);
}
} ///:~
|
 |
//: c15:jdbc:VLookup.java // version GUI de Lookup.java. // <applet code=VLookup // width=500 height=200></applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import java.sql.*; import com.bruceeckel.swing.*;
public class VLookup extends JApplet { String dbUrl = "jdbc:odbc:people"; String user = ""; String password = ""; Statement s; JTextField searchFor = new JTextField(20); JLabel completion = new JLabel(" "); JTextArea results = new JTextArea(40, 20); public void init() { searchFor.getDocument().addDocumentListener( new SearchL()); JPanel p = new JPanel(); p.add(new Label("Last name to search for:")); p.add(searchFor); p.add(completion); Container cp = getContentPane(); cp.add(p, BorderLayout.NORTH); cp.add(results, BorderLayout.CENTER); try { // Charger le driver (qui s'enregistrera lui-même) Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver"); Connection c = DriverManager.getConnection( dbUrl, user, password); s = c.createStatement(); } catch(Exception e) { results.setText(e.toString()); } } class SearchL implements DocumentListener { public void changedUpdate(DocumentEvent e){} public void insertUpdate(DocumentEvent e){ textValueChanged(); } public void removeUpdate(DocumentEvent e){ textValueChanged(); } } public void textValueChanged() { ResultSet r; if(searchFor.getText().length() == 0) { completion.setText(""); results.setText(""); return; } try { // compléter automatiquement le nom: r = s.executeQuery( "SELECT LAST FROM people.csv people " + "WHERE (LAST Like '" + searchFor.getText() + "%') ORDER BY LAST"); if(r.next()) completion.setText( r.getString("last")); r = s.executeQuery( "SELECT FIRST, LAST, EMAIL " + "FROM people.csv people " + "WHERE (LAST='" + completion.getText() + "') AND (EMAIL Is Not Null) " + "ORDER BY FIRST"); } catch(Exception e) { results.setText( searchFor.getText() + "\n"); results.append(e.toString()); return; } results.setText(""); try { while(r.next()) { results.append( r.getString("Last") + ", " + r.getString("fIRST") + ": " + r.getString("EMAIL") + "\n"); } } catch(Exception e) { results.setText(e.toString()); } } public static void main(String[ « args) { Console.run(new VLookup(), 500, 200); } } ///:~
|
 |
 |
 |
Much of the database logic is the same,
but you can see that a DocumentListener is added to listen to the
JTextField (see the javax.swing.JTextField entry in the Java HTML
documentation from java.sun.com for details), so that whenever you type a
new character it first tries to do a name completion by looking up the last name
in the database and using the first one that shows up. (It places it in the
completion JLabel, and uses that as the lookup text.) This way, as
soon as you’ve typed enough characters for the program to uniquely find
the name you’re looking for, you can
stop.
|
 |
La logique « base de données » est en gros la même, mais on peut
remarquer qu'un DocumentListener est ajouté pour écouter l'entrée
JTextField (pour plus de détails, voir l'entrée
javax.swing.JTextField dans la documentation HTML Java sur java.sun.com),
afin qu'à chaque nouveau caractère frappé le programme tente de compléter le nom en le cherchant
dans la base et en utilisant le premier qu'il trouve (en le plaçant dans le JLabel
completion, et en l'utilisant comme un texte de recherche). De cette manière, on peut
arrêter de frapper des caractères dès qu'on en a tapé suffisamment pour que le programme puisse
identifier de manière unique le nom qu'on cherche.
|
 |
 |
 |
Why the JDBC API seems so complex
|
 |
Pourquoi l'API JDBC paraît si complexe
|
 |
 |
 |
When you browse the online documentation
for JDBC it can seem daunting. In particular, in the
DatabaseMetaData
interface—which is just huge, contrary to most of the interfaces you see
in Java—there are methods such as
dataDefinitionCausesTransactionCommit( ),
getMaxColumnNameLength( ), getMaxStatementLength( ),
storesMixedCaseQuotedIdentifiers( ),
supportsANSI92IntermediateSQL( ),
supportsLimitedOuterJoins( ), and so on. What’s this all
about?
|
 |
Naviguer dans la documentation en ligne de JDBC semble décourageant. En
particulier, dans l'interface DatabaseMetaData qui est vraiment énorme, à
l'inverse de la plupart des interfaces rencontrées jusque là en Java, on trouve des méthodes telles
que dataDefinitionCausesTransactionCommit( ),
getMaxColumnNameLength( ), getMaxStatementLength( ),
storesMixedCaseQuotedIdentifiers( ),
supportsANSI92IntermediateSQL( ),
supportsLimitedOuterJoins( ), et ainsi de suite. Qu'en est-il de tout
cela ?
|
 |
 |
 |
As mentioned earlier, databases have
seemed from their inception to be in a constant state of turmoil, primarily
because the demand for database applications, and thus database tools, is so
great. Only recently has there been any convergence on the common language of
SQL (and there are plenty of other database languages in common use). But even
with an SQL “standard” there are so many variations on that theme
that JDBC must provide the large DatabaseMetaData interface so that your
code can discover the capabilities of the particular “standard” SQL
database that it’s currently connected to. In short, you can write simple,
transportable SQL, but if you want to optimize speed your coding will multiply
tremendously as you investigate the capabilities of a particular vendor’s
database.
|
 |
Ainsi qu'on l'a dit précédemment, les bases de données semblent être depuis
leur création dans un constant état de bouleversement, principalement à cause de la très grande
demande en applications de base de données, et donc en outils de base de données. Ce n'est que
récemment qu'on a vu une certaine convergence vers le langage commun SQL (et il existe beaucoup
d'autres langages d'utilisation courante de base de données). Mais même le « standard »
SQL possède tellement de variantes que JDBC doit fournir la grande interface
DatabaseMetaData afin que le code puisse utiliser les possibilités de la base SQL
« standard » particulière avec laquelle on est connecté. Bref, il est possible d'écrire
du code SQL simple et portable, mais si on veut optimiser la vitesse le code va se multiplier
terriblement au fur et à mesure qu'on découvre les possibilités d'une base de données d'un vendeur
particulier.
|
 |
 |
 |
This, of course, is not Java’s
fault. The discrepancies between database products are just something that JDBC
tries to help compensate for. But bear in mind that your life will be easier if
you can either write generic queries and not worry quite as much about
performance, or, if you must tune for performance, know the platform
you’re writing for so you don’t need to write all that investigation
code.
|
 |
Bien entendu, ce n'est pas la faute de Java. Ce dernier tente seulement de
nous aider à compenser les disparités entre les divers produits de base de données . Mais gardons à
l'esprit que la vie est plus facile si l'on peut aussi bien écrire des requêtes génériques sans
trop se soucier des performances, ou bien, si l'on veut améliorer les performances, connaître la
plate-forme pour laquelle on écrit afin de ne pas avoir à traîner trop de code
générique.
|
 |
 |
 |
A more sophisticated example
|
 |
Un exemple plus sophistiqué
|
 |
 |
 |
A more interesting
example[73]
involves a multitable database that resides on a server. Here, the database is
meant to provide a repository for community activities and to allow people to
sign up for these events, so it is called the Community Interests Database
(CID). This example will only provide an overview of the database and its
implementation, and is not intended to be an in-depth tutorial on database
development. There are numerous books, seminars, and software packages that will
help you in the design and development of a database.
|
 |
Un exemple plus intéressant [73]
est celui d'une base de données multi-tables résidant sur un serveur. Ici, la
base sert de dépôt pour les activités d'une communauté et doit permettre aux gens de s'inscrire
pour réaliser ces actions, c'est pourquoi on l'appelle une base de données de communauté
d'intérêts, Community Interests Database (CID). Cet exemple fournira seulement une vue
générale de la base et de son implémentation, il n'est en aucun cas un tutoriel complet à propos du
développement des bases de données. De nombreux livres, séminaires, et packages de programmes
existent pour vous aider dans la conception et le développement des bases de données.
|
 |
 |
 |
In addition, this example presumes the
prior installation of an SQL database on a server (although it could also be run
on a local machine), and the interrogation and discovery of an appropriate JDBC
driver for that database. Several free SQL databases are available, and some are
even automatically installed with various flavors of Linux. You are responsible
for making the choice of database and locating the JDBC driver; the example here
is based on an SQL database system called
“Cloudscape.”
|
 |
De plus, cet exemple implique l'installation préalable d'une base SQL sur
un serveur (bien qu'elle puisse aussi bien tourner sur la machine locale), ainsi que la recherche
d'un driver JDBC approprié pour cette base. Il existe plusieurs bases SQL libres, et certaines sont
installées automatiquement avec diverses distributions de Linux. Il est de votre responsabilité de
faire le choix de la base de données et de localiser son driver JDBC ; cet exemple-ci est basé
sur une base SQL nommée « Cloudscape ».
|
 |
 |
 |
To keep changes in the connection
information simple, the database driver, database URL, user name, and password
are placed in a separate class:
|
 |
Afin de simplifier les modifications d'information de connexion, le driver
de la base, son URL, le nom d'utilisateur et son mot de passe sont placés dans une classe
séparée :
|
 |
 |
 |
//: c15:jdbc:CIDConnect.java
// Database connection information for
// the community interests database (CID).
public class CIDConnect {
// All the information specific to CloudScape:
public static String dbDriver =
"COM.cloudscape.core.JDBCDriver";
public static String dbURL =
"jdbc:cloudscape:d:/docs/_work/JSapienDB";
public static String user = "";
public static String password = "";
} ///:~
|
 |
//: c15:jdbc:CIDConnect.java // information de connexion à la base de données pour // la «base de données de communauté d'intérêt» (CID).
public class CIDConnect { // Toutes les informations spécifiques à CloudScape: public static String dbDriver = "COM.cloudscape.core.JDBCDriver"; public static String dbURL = "jdbc:cloudscape:d:/docs/_work/JSapienDB"; public static String user = ""; public static String password = ""; } ///:~
|
 |
 |
 |
In this example, there is no password
protection on the database so the user name and password are empty strings.
|
 |
Dans cet exemple, il n'y a pas de protection de la base par mot de passe,
le nom d'utilisateur et le mot de passe sont des chaînes vides.
|
 |
 |
 |
The database consists of a set of tables
that have a structure as shown here:
|
 |
La base de données comprend un ensemble de tables dont voici la
structure :
|
 |
 |
 |
|
 |
border="0" alt="Image">
|
 |
 |
 |
“Members” contains community
member information, “Events” and “Locations” contain
information about the activities and where they take place, and
“Evtmems” connects events and members that would like to attend that
event. You can see that a data member in one table produces a key in another
table.
|
 |
« Members » contient les informations sur les membres de la
communauté, « Events » et « Locations » des informations à propos des activités
et où on peut les trouver, et « Evtmems » connecte les événements et les membres qui
veulent suivre ces événements. On peut constater qu'à une donnée « membre » d'une table
correspond une clef dans une autre table.
|
 |
 |
 |
The following class contains the SQL
strings that will create these database tables (refer to an SQL guide for an
explanation of the SQL code):
|
 |
La classe suivante contient les chaînes SQL qui vont créer les tables de
cette base (référez-vous à un guide SQL pour une explication du code SQL) :
|
 |
 |
 |
//: c15:jdbc:CIDSQL.java
// SQL strings to create the tables for the CID.
public class CIDSQL {
public static String[] sql = {
// Create the MEMBERS table:
"drop table MEMBERS",
"create table MEMBERS " +
"(MEM_ID INTEGER primary key, " +
"MEM_UNAME VARCHAR(12) not null unique, "+
"MEM_LNAME VARCHAR(40), " +
"MEM_FNAME VARCHAR(20), " +
"ADDRESS VARCHAR(40), " +
"CITY VARCHAR(20), " +
"STATE CHAR(4), " +
"ZIP CHAR(5), " +
"PHONE CHAR(12), " +
"EMAIL VARCHAR(30))",
"create unique index " +
"LNAME_IDX on MEMBERS(MEM_LNAME)",
// Create the EVENTS table
"drop table EVENTS",
"create table EVENTS " +
"(EVT_ID INTEGER primary key, " +
"EVT_TITLE VARCHAR(30) not null, " +
"EVT_TYPE VARCHAR(20), " +
"LOC_ID INTEGER, " +
"PRICE DECIMAL, " +
"DATETIME TIMESTAMP)",
"create unique index " +
"TITLE_IDX on EVENTS(EVT_TITLE)",
// Create the EVTMEMS table
"drop table EVTMEMS",
"create table EVTMEMS " +
"(MEM_ID INTEGER not null, " +
"EVT_ID INTEGER not null, " +
"MEM_ORD INTEGER)",
"create unique index " +
"EVTMEM_IDX on EVTMEMS(MEM_ID, EVT_ID)",
// Create the LOCATIONS table
"drop table LOCATIONS",
"create table LOCATIONS " +
"(LOC_ID INTEGER primary key, " +
"LOC_NAME VARCHAR(30) not null, " +
"CONTACT VARCHAR(50), " +
"ADDRESS VARCHAR(40), " +
"CITY VARCHAR(20), " +
"STATE VARCHAR(4), " +
"ZIP VARCHAR(5), " +
"PHONE CHAR(12), " +
"DIRECTIONS VARCHAR(4096))",
"create unique index " +
"NAME_IDX on LOCATIONS(LOC_NAME)",
};
} ///:~
|
 |
//: c15:jdbc:CIDSQL.java // chaînes SQL créant les tables pour la CID.
public class CIDSQL { public static String[ « sql = { // Créer la table MEMBERS: "drop table MEMBERS", "create table MEMBERS " + "(MEM_ID INTEGER primary key, " + "MEM_UNAME VARCHAR(12) not null unique, "+ "MEM_LNAME VARCHAR(40), " + "MEM_FNAME VARCHAR(20), " + "ADDRESS VARCHAR(40), " + "CITY VARCHAR(20), " + "STATE CHAR(4), " + "ZIP CHAR(5), " + "PHONE CHAR(12), " + "EMAIL VARCHAR(30))", "create unique index " + "LNAME_IDX on MEMBERS(MEM_LNAME)", // Créer la table EVENTS: "drop table EVENTS", "create table EVENTS " + "(EVT_ID INTEGER primary key, " + "EVT_TITLE VARCHAR(30) not null, " + "EVT_TYPE VARCHAR(20), " + "LOC_ID INTEGER, " + "PRICE DECIMAL, " + "DATETIME TIMESTAMP)", "create unique index " + "TITLE_IDX on EVENTS(EVT_TITLE)", // Créer la table EVTMEMS: "drop table EVTMEMS", "create table EVTMEMS " + "(MEM_ID INTEGER not null, " + "EVT_ID INTEGER not null, " + "MEM_ORD INTEGER)", "create unique index " + "EVTMEM_IDX on EVTMEMS(MEM_ID, EVT_ID)", // Créer la table LOCATIONS: "drop table LOCATIONS", "create table LOCATIONS " + "(LOC_ID INTEGER primary key, " + "LOC_NAME VARCHAR(30) not null, " + "CONTACT VARCHAR(50), " + "ADDRESS VARCHAR(40), " + "CITY VARCHAR(20), " + "STATE VARCHAR(4), " + "ZIP VARCHAR(5), " + "PHONE CHAR(12), " + "DIRECTIONS VARCHAR(4096))", "create unique index " + "NAME_IDX on LOCATIONS(LOC_NAME)", }; } ///:~
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |