|
Niveau : Intermédiaire
Noel Rappin (noelrappin@gmail.com), Senior Software Engineer, Motorola, Inc.
23 Jan 2007
Dans ce second article de la série sur l'utilisation de de la trousse à outils Web de Google (GWT) pour concevoir une application Javascript asynchrone + XML (Ajax), apprenez comment lier la base de données Apache Derby à votre application Web, et l'utiliser avec GWT. La Partie 1 de cette série vous a présenté à GWT et a démontré comment vous pouvez l'employer pour créer un frontal client riche (rich-client front end) dans une application Web. Cette fois, vous irez du côté serveur pour activer votre arrière plan (back end) avec votre base de données et le code employé pour convertir les données en un format que GWT peut employer. Vers la fin de cet article, vous serez prêt pour faire commmuniquer entre eux le front end et back end.
Dans cet article, vous installerez et configurerez votre base de données -- le back end de votre application Web -- créerez un schéma de base de données, et apprendrez quelques outils simples pour remplir les données. La base de données que vous emploierez est Apache Derby, une base de données relationnelle 100% pure de Java™ qui a été à l'origine développée sous le nom de Cloudscape™. Par la suite, le code de Cloudscape a été acquis par IBM®, qui a donné une version open source dans le projet d'Apache. Le même projet est également distribué par Sun Microsystems sous le nom de JavaDB.
J'ai choisi Derby pas simplement parce que j'aime le fait qu'il a trois noms, mais parce qu'il est léger et facile de configurer. À la différence de la plupart des bases de données relationnelles, Derby peut fonctionner dans la même machine virtuelle de Java (JVM) cans le votre code Java côté serveur. (Vous pouvez également l'exécuter dans une JVM séparé si vous préférez.) Cela facilite le développement et le déploiement, et Derby est suffisament rapidement pour être un choix raisonnable pour d'application Web de taille petite à moyenne.
Avant que vous commenciez, quelques notes : D'abord, pour suivre cet article, vous devriez avoir une notion des bases de données relationnelles, du JDBC, et du langage d'interrogation structuré (SQL). En second lieu, cet article présente quelques choses dans le code pour la démonstration qui ne sont pas susceptibles d'être idéale dans un système de production. J'essaye d'expliquer ces points tout au long du tutoriel, mais je ne parle pas de l'optimisation des performances.
Obtenir Derby
If you aren't, you can grab whichever other distribution meets your needs.
One distribution is only the library files, another is the library and
documentation, one distribution is the library with debug information, and
one distribution is just source code. Derby is based exclusively on Java technology
and will run on any JVM version 1.3 or later. The code examples here assume that
you're using Java 1.4.
Derby est disponible en tant qu'élément du projet de DB d'Apache. En date de cette écriture, la version en cours est version 10.1.3.1. Si vous allez travailler dans l'environnement de développement intégré par Eclipse (IDE), c'est suffisant récupérer les deux plugins : derby_core_plugin et derby_ui_plugin . Dans le cas contraire, vous pouvez saisir une autre distribution qui satisfait vos besoins. Il existe plusieur distribution, l'une est seulement les fichiers de la bibliothèque, une autre est la bibliothèque et la documentation, une autre distribution est la bibliothèque avec débugueur, et une dernière distribution est juste le code source. Derby est basé exclusivement sur la technologie de Java et s'executera sur n'importe quelle version 1.3 de JVM ou supérieure. Les exemples de code ici supposent que vous employez Java 1.4.
Activer Derby sans Eclipse
Si vous n'employez pas Eclipse, extraire la distribution que vous avez téléchargée n'importe où cela vous convient. Quand cela est fait, s'assurer que les fichiers lib/derby.jar et lib/derbytools.jar sont dans votre variable classpath . Vous pouvez faire ceci au niveau de système, dans ce cas il pourrait être utile de définir à la variable d'environnement DERBY_INSTALL le dossier dans lequel Derby réside (inclure le dossier de Derby lui-même, comme dans /opt/bin/db-derby-10.1.3.1-bin). Vous pouvez également faire ceci dans votre IDE ou lanceur de script. Si vous voulez employer Derby dans un mode client/serveur aussi bien qu'en mode embarqué, les fichiers lib/derbyclient.jar et lib/derbynet.jar doivent également être dans votre classpath .
Activer Derby avec Eclipse
Si vous employez Eclipse, l'installation pour le développement est un peu plus facile. Pour activer Derby dans Eclipse, accomplissez ces étapes :
- Extraire les deux fichiers plug-in. Chacun a un dossier supérieur appelé plugin.
- Copier le contenu de ce dossier dans votre dossier de connexion plug-in d'Eclipse.
- Ouvrir votre projet dans Eclipse.
- Cliquer Project > Add Apache Derby Nature pour ouvrir l'environement de la qualité de Derby. Ajouter ainsi les quatre fichiers bibliothèques à votre
classpath de projet et obtenez l'accès à ij en ligne message de commande.
La figure 1 montre le menu de Derby après que vous ayez ajouté la nature de Derby.
Figure 1. Le menu Derby dans Eclipse
Même si vous employez l'éclipse pour le développement, vous devez avoir les fichiers JAR appropriés et disponibles quand vous déployez votre application. Je couvrirai ceci plus en détail dans un article utltérieur.
Concevoir votre schéma
Avant que vous commenciez à utiliser votre base de données, prenez une minute pour déterminer ce que la base de données devrait gérer. Je n'ai pas encore discuté des conditions pour l'application de Slicr, ainsi supposons que vous voulez que la base de données puisse stocker les informations basiques du client et de l'ordre de commande.
S'occuper de la base de données dans les premières étapes est pour la maintenir facilement et utiliser quelques fonctionnalités spécifiques de la base de données, même si cela signifie pour commencer d'ajoutert du traitement additionnel dans votre code Java. Une base de données est une grande dépendance tierce, et vous devez vous protéger contre avoir des décisions au sujet de la de base de données qui commanderaient le reste de votre application. Vous voulez réduire au minimum les points de contact entre votre programme et la base de données de sorte que si vous changez en certain point les systèmes, le changement (portage) soit réellement faisable. La rapidité est que la principale des choses qu'il vous suffira pour améliorer l'exécution de base de données tendent à vous attacher à employer un système spécifique, ainsi essayez de reporter cette optimisation jusqu'au dernier moment possible dans le projet.
Le début de votre conception de base de données est franc. Ordres de place de clients. Les ordres se composent d'une ou plusieurs pizzas (pour le moment, ignorer que le restaurant peut vendre d'autre nourriture). Une pizza se compose de zéro garniture ou plus, qui pourraient être sur la moitié de la pizza ou sur toute la pizza.
Créer la table des clients
En ce moment, inquiétez vous seulement qu'il y ait suffisament d'information au sujet du client pour pouvoir le livrer et confirmer les ordres de commande, comme montre la liste 1.
Liste 1. La table du client (customers)
CREATE TABLE customers (
id int generated always as identity constraint cust_pk primary key,
first_name varchar(255),
last_name varchar(255),
phone varchar(15),
address_1 varchar(200),
address_2 varchar(200),
city varchar(100),
state varchar(2),
zip varchar(10)
)
|
Le rapport d'état (statement) CREATE a un bit légèrement non standard de la syntaxe de SQL. Vous créez une colonne ID qui sera incrémentée automatiquement par Derby pour chaque nouvelle enregistrement. La clause pour indiquer que le comportement est :
id int generated always as identity
L'autre option pour une colonne d'identité serait :
generate by default as identity
La différence est que generate by default permet de placer votre propre valeur dans la colonne, tandis que generate always ne le fait pas. Vous avez également identifié la colonne ID comme clef primaire de la table.
Vous voulez toujours avoir un ID dans la base de données qui est complètement sans raccordement à une valeur réelle. Quelqu'un sur votre équipe essayera par la suite de vous convaincre que vous pouvez employer quelque chose comme un nombre de téléphone comme clef, parce qu'elle identifiera également uniquement un client. Ne pas la faire. La dernière chose que vous avez auriez à faire est de mettre à jour votre base de données entière parce que quelqu'un a déplacé et a changé les numéros de téléphone.
Créer la table des ordres de commande
Pour la table d'ordre (voir la liste 2), vous voulez juste l'attacher à un client et à une date et tenir compte d'un escompte. Vous pouvez calculer le reste du prix en code.
Liste 2. La table des ordres de commande (orders)
CREATE TABLE orders (
id int generated always as identity constraint ord_pk primary key,
customer_id int constraint cust_foreign_key references customers,
order_time timestamp,
discount float
)
|
En plus de la clef primaire id , vous avez déclaré la colonne de customer_id pour être une clef étrangère mettant en référence la table client. (Si vous n'incluez pas une colonne étrangère dans la déclaration, Derby suppose que vous mettez en référence la clef primaire de l'autre table.) Ceci signifie que Derby validera que n'importe quel customer_id ajouté a cette table corresponds a un client dans le système. Votre administrateur de base de données vous dira que vous devriez toujours faire ceci. Cependant, je pense qu'il y a des cas légitimes dans lesquels vous ne pourriez pas vouloir que la base de données doit strictement valide tout le temps. Par exemple, vous pourriez devoir saisir des données avant que vous sachiez ou puissiez valider quelle est la valeur étrangère. Alternativement, vous pourriez vouloir supprimer l'enregistrement étranger mais garder l'enregistrement de votre table. Dans ce cas-ci, par exemple, vous pourriez vouloir supprimer un client mais garder les ordres du client pour la collecte de données. Vous pouvez utiliser Derby pour faire cela, mais il ne sera pas portable vers d'autres systèmes de base de données.
Créer la table des garnitures
Le dernier problème de conception de base de données est la pizza et les garnitures. Bien, pas les garnitures; c'est assez simple, comme le montre la liste 3.
Lise 3. La table des garnitures (toppings)
CREATE TABLE toppings(
id int generated always as identity constraint top_pk primary key,
name varchar(100),
price float
)
|
The question is, how do you manage the relationship between pizza and toppings?
A pizza is an order, a size, and a set of toppings. Classic database
normalization would say to create a Pizza table, and then a many-to-many
table relating pizza IDs to topping IDs. Doing so has many nice properties,
among them the fact that it allows an infinite number of toppings on a pizza.
However, managing the database relationship between the tables can have a
performance cost. If infinite toppings aren't needed, you can include several
topping fields in the Pizza table (topping_1 ,
topping_2 , and so on). Conceptually, that's a bit
simpler, but it would make it awkward to, say, mine your order data to count
the most popular toppings. If you're feeling particularly adventurous, you
could have a single topping field and populate it with a bitmap or concatenated
string or the like. I really don't recommend that.
La question est, comment contrôlez-vous le rapport entre la pizza et les garnitures ? Une pizza est un ordre, une taille, et un ensemble de garnitures. La normalisation classique de base de données indiquerait de créer une table de pizza, et puis une table multiple reliant des identifications de pizza (IDs) aux identifications de garniture (IDs). Faire ainsi a beaucoup de propriétés gentilles, parmi elles le fait qu'il permet un nombre infini de garniture sur une pizza. Cependant, la gestion du rapport de base de données entre les tables peut avoir un coût d'exécution. Si les garnitures infinis ne sont pas nécessaires, vous pouvez inclure plusieurs champs de garnitures dans la table Pizza (topping_1, topping_2, et ainsi de suite). Conceptuellement, c'est un peu plus simple, mais ca la rendrait plus maladroites par exemple pour compter les garnitures les plus populaires. Si vous vous sentez particulièrement aventureux, vous pourriez avoir un simple champs de garnitures et le peupler avec un bitmap ou une chaine concaténée ou analogue. Je vous le déconseille fortement.
Crér la table des pizzas
Après une petite reflexion, j'ai décidé d'aller de pair avec la forme entièrement normale. Vous voudriez laisser autant de garnitures que voulu sur une pizza, car la mise des garnitures dans la même table deviendrait plutôt laide. Ainsi, utilisez le code montré dans la liste 4.
Liste 4. La tables des pizzas
CREATE TABLE pizzas (
id int generated always as identity constraint piz_pk primary key,
order_id int constraint order_foreign_key references orders,
size int
)
CREATE TABLE pizza_topping_map (
id int generated always as identity constraint ptmap_pk primary key,
pizza_id int constraint pizza_fk references pizzas,
topping_id int constraint topping_fk references toppings,
placement int
)
|
Juste pour être clair, vous aurez les tailles 1, 2, 3, et 4 représentant respectivement petite, moyenne, grande, et ultra-large. Le placement des garnitures sera -1, 0, ou 1 pour demi gauche, pizza entière, et la moitié droite, respectivement. Et vous avez besoin d'un ID séparée pour chaque partie de la pizza, de sorte que vous puissiez par exemple tenir compte des pepperoni supplémentaires en prenant des pepperoni comme garnitures apparaissant deux fois dans la même pizza.
Note : Est-ce que j'ai mentionné que tous ces noms que vous avez mis après constraint doivent être unique à travers votre base de données ? Ils le sont. Derby crée réellement un index interne, et chaque index doit avoir un nom unique.
Cela devrait le faire pour votre schéma de base de données. Maintenant vous pouvez l'entrer dans la base de données.
Remplir la base de données
Vous avez un schéma; maintenant vous le créer et y insèrer quelques données initiales. Vous allez créer un petit programme autonome qui exécute cette installation. Cepedant ce n'est pas la seule méthode possible. Vous pourriez employer la ligne de commande d'ij de Derby pour écrire les commandes de SQL directement, ou vous pourriez utiliser un outil SQL graphique. Cependant, l'approche via les programmes, vous donne une manière bien contrôlée de voir comment lancer Derby et comment Derby diffère d'autres bases de données JDBC. Dans la pratique, vous maintiendriez probablement aussi bien le schéma de SQL dans son propre langage de SQL.
Vous commencez par quelques données assez statiques -- la liste des garnitures de pizza ce que vous avez inclus dans la page de Slicr dans la partie 1. Encore, cette approche fonctionne la plupart du temps parce que vous insérez des données statiques. Vous établirez une table de garnitures en laquelle chaque garniture a un nom et un prix de base. Le code montré dans la liste 5 établit ces données. Pour le moment, supposer que toutes les garnitures ont le même prix.
Liste 5. Activer la table des granitures dans Derby
public class SlicrPopulatr {
public static final String[] TOPPINGS = new String[] {
"Anchovy", "Gardineria", "Garlic",
"Green Pepper", "Mushrooms", "Olives",
"Onions", "Pepperoni", "Pineapple",
"Sausage", "Spinach"
}
public void populateDatabase() throws Exception {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
Connection con = DriverManager.getConnection(
"jdbc:derby:slicr;create=true");
con.setAutoCommit(false);
Statement s = con.createStatement();
s.execute("DROP TABLE toppings");
s.execute("CREATE TABLE toppings(" +
"id int generated always as identity constraint top_pk primary key, " +
"name varchar(100), " +
"price float)");
//
// All the other create table statements from above would go here...
//
for (int i = 0; i < TOPPINGS.length; i++) {
s.execute("insert into toppings values (DEFAULT, '" +
TOPPINGS[i] + "', 1.25)");
}
con.commit();
con.close();
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException ignore) {}
}
public static void main(String[] args) throws Exception {
(new SlicrPopulatr()).populateDatabase();
}
|
Si vous connaissez JDBC, la majeure partie de ce code sera familière. Cependant, il y a des couples des fonctionnalités à spécifiques Derby que je devrais couvrir. Vous commencez par charger la classe pilote en utilisant l'idiome de Class.forName . Puisque vous allez employer la version embarquée de Derby, le nom de classe pour le pilote est org.apache.derby.jdbc.EmbeddedDriver . Après, vous créez l'URL de connexion. L'URL de Derby est de la forme :
jdbc:derby:database name;[attr=value]
Le nom de base de données est le nom que vous voulez employer pour se référer à votre base de données. Il n'importe pas beaucoup ce que vous avez sélectionnez tant que vous vous y êtes conformé quand vous ouvrez la base de données toujours depuis votre code de serveur.
Après que vous créiez la connexion, vous êtes dans le standard de JDBC. Vous créez un Statement pour exécuter des commandes pour effacer et recréer la table, ce qui permet de remettre à zéro la base de données depuis ce programme si elle devient corrompue. (Autrement, Derby retournerait une exception quand il essayérai de créer une table qui existe déjà). Après que vous créiez la table, vous employez un rapport d'insertion (insert statement) pour chaque entrée de vos enregistrements de garnitures.
Le code de SQL dans les insert statements a une fonction que vous pouvez ne pas prévoir. J'ai employé le mot-clé DEFAULT comme placeholder pour la colonne d'identité. Derby s'attend à ce mot-clé dans la colonne d'identité si vous n'indiquez pas la liste de colonne dans votre insert statement.
Avant que le programme existe, vous faites un appel spécial pour obtenir une connexion avec l'URL "jdbc:derby:;shutdown=true" -- vous n'avez pas besoin d'indiquer la base de données. Cet appel indique l'arrêt du système de Derby et libére toutes les connexions actives.
Après avoir exécuté ce petit programme, vous verrez un dossier à la racine de votre application appelé derbyDb. Ce dossier stocke les fichiers binaires dans lesquels Derby stocke ses données. Ne changer pas ces fichiers sous aucun prétexte.
Préparer les données pour for GWT
What makes a serializable field? First, the field can be of a type that implements
IsSerializable or has a superclass that does. Or the
field can be one of the basic types, which includes Java primitives, all the
primitive wrapper classes, Date , and String .
An array or collection of serializable types is also serializable. However, if
you're going to serialize a Collection or
List , GWT prefers that you annotate it with a Javadoc
comment specifying the actual type so that the compiler can optimize it.
Listing 6 shows a sample for a field and for a method.
Votre schéma de base de données etant en place et les données statiques étant chargé, maintenant vous devez définir comment vous allez communiquer ces données à votre client et vice-versa. Par la suite, vous allez devoir arranger des données en série (serialize) à travers la connexion client-serveur. Pour que cette sérialisation fonctionne, vos classes de données certaines doivent être où GWT peut les voir et les traiter, qui signifie que les classes doivent être définies dans votre paquet client et compilables par le compilateur de Java-à-Javascript de GWT.
Il y a quelques restrictions additionnelles à une classe de client qui va être sérialisée. Déjà, la classe doit implémenter l'interface
com.google.gwt.user.client.rpc.IsSerializable , qui est une interface de marqueur, ne définissant aucune méthode. En outre, toutes les champs dans la classe doivent eux-mêmes être serializables. (Comme avec la sérialisation ordinaire de Java, vous pouvez exempter des champs d'être sérialisés en les marquant transient .)
Que fait un champ serializable ? D'abord, le champ peut être d'un type qui implémente IsSerializable ou a des superclass qui le font. Ou le champ peut être l'un des types de base, qui inclut des primitifs de Java, toutes classes d'emballage de primitif, Date , et String . Un tableau ou une collection de types serializable est également serializable. Cependant, si vous allez sérialiser une Collection ou une List , GWT préfère que vous l'annotez avec un commentaire Javadoc indiquant le type réel de sorte que le compilateur puisse l'optimiser. La liste 6 montre un échantillon pour un champ et pour une méthode.
Liste 6. Un champ et et une méthode sérialisable
/**
* @gwt.typeArgs <java.lang.Integer>
*/
private List aList;
/**
* @gwt.typeArgs <java.lang.Double>
* @gwt.typeArgs argument <java.lang.String>
*/
public List doSomethingThatReturnsAList(List argument) {
// Stuff goes here
}
|
Note : L'argument dans une liste de méthode doit indiqué ses types dans le commentaire, contrairement à la valeur de retour.
Noter que quelque toute chose à faire avec java.sql et le JDBC est absent de cette liste d'objets serializable. Peut importe ce que vous fassiez pour obtenir de votre jeu de données vous devez le faire dans me code côté serveur.
En ce moment, vous entrez dans le monde de l'Object-Relational Mapping (ORM), ou transférer des données depuis une structure de base de données relationnelle à votre programme Java, une structure orientée object. Pour un système de production complexe Java, vous voulez probablement employer un système préexistant et véritable d'ORM, tel que Hibernate ou Castor. Tous les deux systèmes chargent automatiquement vos données de la base de données dans des objets Java de votre choix. Cependant, ils exigent également une grosse configuration avant que vous obteniez commencé. Dans l'intérêt de se concentrer sur Derby et GWT ici, je présente un convertisseur rapide qui sert pendant le début du développement. Par la suite, vous pouvez le permuter pour un outil plus puissant.
Un simple convertisseur d'ORM
D'abord, créer les classes d'haricot (bean classes) pour toutes vos tables de données. J'emploie la classe Topping comme exemple parce qu'il est simple et a déjà des données. Employer les conventions ordinaire d'appellation des bean pour chaque colonne dans la table, mais convertissez les underscores en nom composé (par exemple, le topping_id devient getToppingId ). La liste 7 montre la classe de Topping .
Listing 7. La classe Topping
package com.ibm.examples.client;
import com.google.gwt.user.client.rpc.IsSerializable;
public class Topping implements IsSerializable {
private Integer id;
private String name;
private Double price;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
|
L'outil simple d'ORM est indiqué dans la liste 8.
Liste 8. Simple ORM tool
package com.ibm.examples.server;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class ObjectFactory {
public static String convertPropertyName(String name) {
String lowerName = name.toLowerCase();
String[] pieces = lowerName.split("_");
if (pieces.length == 1) {
return lowerName;
}
StringBuffer result = new StringBuffer(pieces[0]);
for (int i = 1; i < pieces.length; i++) {
result.append(Character.toUpperCase(pieces[i].charAt(0)));
result.append(pieces[i].substring(1));
}
return result.toString();
}
public static List convertToObjects(ResultSet rs, Class cl) {
List result = new ArrayList();
try {
int colCount = rs.getMetaData().getColumnCount();
while (rs.next()) {
Object item = cl.newInstance();
for (int i = 1; i <= colCount; i += 1 ) {
String colName = rs.getMetaData().getColumnName(i);
String propertyName = convertPropertyName(colName);
Object value = rs.getObject(i);
PropertyDescriptor pd = new PropertyDescriptor(propertyName, cl);
Method mt = pd.getWriteMethod();
mt.invoke(item, new Object[] {value});
}
result.add(item);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return result;
}
}
|
La méthode convertToObjects() fait une boucle simplement dans l'ensemble des résultats, implique l'acquéreur de propriété (getter) en utilisant la réflexion de JavaBean, et place toutes valeurs. La méthode convertPropertyName() commute entre le SQL souligné appelant la convention et la convention de mélanger la casse (mixed-case) de Java.
|
Ce que l'outil d'ORM ne fait pas
Vous pourriez remplir un livre avec toutes les fonctionnalités utiles manquantes d'ORM à partir de cet outil. Par exemple, l'outil ne fait pas :
- Éviter de créer des versions multiples du même objet.
- Vous laisser annuler l'ecriture (write back) dans la base de données.
- Travailler très rapidement.
|
|
Le code va plus loing que vous pourriez penser. Vous pouvez executer avec lui tout de suite sur n'importe quel outil de base de données sans davantage de configuration. Vous n'avez pas besoin de maintenir un fichier synchronisé avec votre base de données pendant la phase de développement, quand vous changerez votre schéma. Et il ne sera pas difficile de permuter sur un outil plus puissant dans quand le moment sera venu.
La liste 9 présente cet outil dans l'action, relistant tous l'exemple de l'instance Topping que vous avez créé plus tôt.
Liste 9. Essayer l'outil ORM
public class ToppingTestr {
public static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
public static final String PROTOCOL = "jdbc:derby:slicr;";
public static void main(String[] args) throws Exception {
try {
Class.forName(DRIVER).newInstance();
Connection con = DriverManager.getConnection(PROTOCOL);
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM toppings");
List result = ObjectFactory.convertToObjects(rs, Topping.class);
for (Iterator itr = result.iterator(); itr.hasNext();) {
Topping t = (Topping) itr.next();
System.out.println("Topping " + t.getId() + ": " +
t.getName() + " is $" + t.getPrice());
}
} finally {
try {
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException ignore) {}
}
}
}
|
| |
Ce programme d'essai crée une connexion à Derby sur la base de données de Slicr. (Vous n'aurez plus a vous demander plus l'URL duprotocole pour créer la base de données si nécessaire.) Vous exécutez une simple question SQL, et puis passez les résultats à votre usine (factory). Alors vous êtes libre de faire une boucle sur la liste résultatante et de quitter la base de données.
Tune in next time
Your database is now installed and configured. You created a database schema and
discovered some simple tools for putting data into it. After two articles in this
series, your Slicr project now has simple but functional front and back ends. The
next step is communication. In the third article in this series, you'll learn about the
framework that GWT uses to make Remote Procedure Calls (RPCs) easy to code and
manage.
Votre base de données est maintenant installée et configurée. Vous avez créé un schéma de base de données et avez découvert quelques outils simples pour y mettre des données. Après deux articles de cette série, votre projet de Slicr a maintenant les extrémités avant (front end) et arrières (back end) simples mais fonctionnelles. La prochaine étape est le communication. Dans le troisième article de cette série, vous apprendrez l'utilisation du cadre (framework) GWT pour faire de la procédure d'appel distant (RPCs) facile à coder et contrôler.
Resources Article traduit en Français
- Partie 1 : Construire une application Ajax en utilisant Google Web Toolkit, Apache Derby, et Eclipse, Partie 1: Le bel interface
- Partie 2 : Construire une application Ajax en utilisant Google Web Toolkit, Apache Derby, et Eclipse, Partie 2: Côté serveur
- Partie 3 : Construire une application Ajax en utilisant Google Web Toolkit, Apache Derby, et Eclipse, Partie 3: Communication
- Partie 4 : Construire une application Ajax en utilisant Google Web Toolkit, Apache Derby, et Eclipse, Partie 4: Déploiement
Original English article
Learn
Get products and technologies
Discuss
A propos de l'auteur | | | Noel
Rappin, a Ph.D. from the Graphics, Visualization, and Usability Center
at the Georgia Institute of Technology, is a senior software engineer
at Motorola. He is also the coauthor of wxPython in Action and Jython
Essentials. |
| |