Accueil > > > OBJETS JDBC
OBJETS JDBC
Information sur la source
Description
L'objet Database encapsule l'ensemble des objets nécessaires à la connexion à une base de données, et dispose de méthodes simples pour l'exécution de requêtes et l'accès aux métadonnées. L'objet DataSet (renvoyé par la méthode executeQuery de Database) encapsule un objet ResultSet et renvoie les données sous forme d'un tableau de valeurs. Il contient également des méthodes permettant d'accéder aux métadonnées du ResultSet.
Source
- //Classe Database
-
- import java.sql.*;
- import java.io.*;
- import java.util.*;
- import javax.swing.JOptionPane;
-
- public class Database {
- private
- Connection cnt;
- DataSet results;
- ResultSetMetaData rsmd;
- DatabaseMetaData dma;
- String[] types;
- String productName;
- String productVersion;
-
- public Database(String driver) {
- try{
- types = new String[1];
- types[0] = "TABLE";
- Class.forName(driver);
- }
- catch (Exception ex){
- JOptionPane.showMessageDialog(null, "Erreur lors du chargement du driver :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public void open(String url, String username, String password) {
- try{
- cnt = DriverManager.getConnection(url, username, password);
- dma = cnt.getMetaData();
- productName = dma.getDatabaseProductName();
- productVersion = dma.getDatabaseProductVersion();
- results = new DataSet(dma.getCatalogs());
- String s[] = null;
- while(results.hasMoreElements()) {
- s = results.nextElement();
- }
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, "Echec d'ouverture :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public void close(){
- try{
- cnt.close();
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, "Echec lors de la fermeture :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public String[] getTableNames() {
- String[] tbnames = null;
- Vector tname = new Vector();
-
- try{
- results = new DataSet(dma.getTables(null, null, "%", types));
- while (results.hasMoreElements())
- tname.addElement(results.getColumnValue("TABLE_NAME"));
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- tbnames = new String[tname.size()];
- for(int i=0;i<tname.size();i++)
- tbnames[i] = (String)tname.elementAt(i);
- return tbnames;
- }
-
- public String[] getTableMetaData() {
- results = null;
-
- try{
- results = new DataSet(dma.getTables(null, null, "%", types));
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- return results.getMetaData();
- }
-
- public String[] getColumnMetaData(String tablename) {
- results = null;
-
- try{
- results = new DataSet(dma.getColumns(null, null, tablename, null));
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- return results.getMetaData();
- }
-
- public String[] getColumnNames(String table) {
- String[] tbnames = null;
- Vector tname = new Vector();
-
- try{
- results = new DataSet(dma.getTables(null, null, table, null));
- while (results.hasMoreElements())
- tname.addElement(results.getColumnValue("COLUMN_NAME"));
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- tbnames = new String[tname.size()];
- for(int i=0;i<tname.size();i++)
- tbnames[i] = (String)tname.elementAt(i);
- return tbnames;
- }
-
- public void getColumnValue(String table, String columnName) {
- try{
- if (table.length()>0)
- results = executeQuery("Select "+columnName+" from "+table+" order by "+columnName);
- }
- catch (Exception ex){
- JOptionPane.showMessageDialog(null, "Erreur sur la valeur de la colonne "+columnName+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public String getNextValue(String columnName) {
- String res = "";
- try{
- if (results.hasMoreElements())
- res = results.getColumnValue(columnName);
- }
- catch (Exception ex){
- JOptionPane.showMessageDialog(null, "Erreur sur la valeur suivante "+columnName+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- return res;
- }
-
- public DataSet executeQuery(String sql){
- results = null;
- try{
- Statement stmt = cnt.createStatement();
- results = new DataSet(stmt.executeQuery(sql));
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- return results;
- }
-
- public void executeUpdate(String sql){
- try{
- Statement stmt = cnt.createStatement();
- stmt.executeUpdate(sql);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public String getProductName(){
- return productName;
- }
-
- public String getProductVersion(){
- return productVersion;
- }
- }
-
- //Classe DataSet
-
- import java.sql.*;
- import javax.swing.JOptionPane;
-
- public class DataSet {
- ResultSet results;
- ResultSetMetaData rsmd;
- int columnCount;
- String[] columnNames;
-
- public DataSet(ResultSet results){
- try {
- this.results = results;
- rsmd = results.getMetaData();
- columnCount = rsmd.getColumnCount();
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public boolean hasMoreElements() {
- try{
- return results.next();
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return false;
- }
- }
-
- public String[] getMetaData() {
- String[] s;
- s = new String[columnCount+1];
- try{
- results.next();
- for (int i=1; i<=columnCount; i++){
- s[i] = results.getString(i);
- }
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- return s;
- }
-
- public String[] nextElement() {
- String[] line;
- line = new String[columnCount+1];
- try{
- for (int i = 1; i <= columnCount; i++){
- line[i] = results.getString(i);
- }
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- }
- return line;
- }
-
- public String getColumnValue(String columnName) {
- try{
- return results.getString(columnName);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return "";
- }
- }
-
- public int getColumnCount(){
- return columnCount;
- }
-
- public String getColumnName(int i) {
- try{
- return rsmd.getColumnName(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return "";
- }
- }
-
- public String getColumnLabel(int i) throws SQLException {
- try{
- return rsmd.getColumnLabel(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return "";
- }
- }
-
- public int getColumnDisplaySize(int i) throws SQLException {
- try{
- return rsmd.getColumnDisplaySize(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return 0;
- }
- }
-
- public int getColumnType(int i) throws SQLException{
- try{
- return rsmd.getColumnType(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return 0;
- }
- }
-
- public String getColumnTypeName(int i) throws SQLException{
- try{
- return rsmd.getColumnTypeName(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return "";
- }
- }
-
- public String getCatalogName(int i) throws SQLException{
- try{
- return rsmd.getCatalogName(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return "";
- }
- }
-
- public boolean isAutoIncrement(int i) throws SQLException{
- try{
- return rsmd.isAutoIncrement(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return false;
- }
- }
-
- public String getSchemaName(int i) throws SQLException{
- try{
- return rsmd.getSchemaName(i);
- }
- catch (SQLException ex){
- JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
- return "";
- }
- }
- }
-
-
//Classe Database
import java.sql.*;
import java.io.*;
import java.util.*;
import javax.swing.JOptionPane;
public class Database {
private
Connection cnt;
DataSet results;
ResultSetMetaData rsmd;
DatabaseMetaData dma;
String[] types;
String productName;
String productVersion;
public Database(String driver) {
try{
types = new String[1];
types[0] = "TABLE";
Class.forName(driver);
}
catch (Exception ex){
JOptionPane.showMessageDialog(null, "Erreur lors du chargement du driver :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
}
public void open(String url, String username, String password) {
try{
cnt = DriverManager.getConnection(url, username, password);
dma = cnt.getMetaData();
productName = dma.getDatabaseProductName();
productVersion = dma.getDatabaseProductVersion();
results = new DataSet(dma.getCatalogs());
String s[] = null;
while(results.hasMoreElements()) {
s = results.nextElement();
}
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, "Echec d'ouverture :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
}
public void close(){
try{
cnt.close();
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, "Echec lors de la fermeture :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
}
public String[] getTableNames() {
String[] tbnames = null;
Vector tname = new Vector();
try{
results = new DataSet(dma.getTables(null, null, "%", types));
while (results.hasMoreElements())
tname.addElement(results.getColumnValue("TABLE_NAME"));
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
tbnames = new String[tname.size()];
for(int i=0;i<tname.size();i++)
tbnames[i] = (String)tname.elementAt(i);
return tbnames;
}
public String[] getTableMetaData() {
results = null;
try{
results = new DataSet(dma.getTables(null, null, "%", types));
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
return results.getMetaData();
}
public String[] getColumnMetaData(String tablename) {
results = null;
try{
results = new DataSet(dma.getColumns(null, null, tablename, null));
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
return results.getMetaData();
}
public String[] getColumnNames(String table) {
String[] tbnames = null;
Vector tname = new Vector();
try{
results = new DataSet(dma.getTables(null, null, table, null));
while (results.hasMoreElements())
tname.addElement(results.getColumnValue("COLUMN_NAME"));
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
tbnames = new String[tname.size()];
for(int i=0;i<tname.size();i++)
tbnames[i] = (String)tname.elementAt(i);
return tbnames;
}
public void getColumnValue(String table, String columnName) {
try{
if (table.length()>0)
results = executeQuery("Select "+columnName+" from "+table+" order by "+columnName);
}
catch (Exception ex){
JOptionPane.showMessageDialog(null, "Erreur sur la valeur de la colonne "+columnName+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
}
public String getNextValue(String columnName) {
String res = "";
try{
if (results.hasMoreElements())
res = results.getColumnValue(columnName);
}
catch (Exception ex){
JOptionPane.showMessageDialog(null, "Erreur sur la valeur suivante "+columnName+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
return res;
}
public DataSet executeQuery(String sql){
results = null;
try{
Statement stmt = cnt.createStatement();
results = new DataSet(stmt.executeQuery(sql));
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
return results;
}
public void executeUpdate(String sql){
try{
Statement stmt = cnt.createStatement();
stmt.executeUpdate(sql);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
}
public String getProductName(){
return productName;
}
public String getProductVersion(){
return productVersion;
}
}
//Classe DataSet
import java.sql.*;
import javax.swing.JOptionPane;
public class DataSet {
ResultSet results;
ResultSetMetaData rsmd;
int columnCount;
String[] columnNames;
public DataSet(ResultSet results){
try {
this.results = results;
rsmd = results.getMetaData();
columnCount = rsmd.getColumnCount();
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
}
public boolean hasMoreElements() {
try{
return results.next();
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return false;
}
}
public String[] getMetaData() {
String[] s;
s = new String[columnCount+1];
try{
results.next();
for (int i=1; i<=columnCount; i++){
s[i] = results.getString(i);
}
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
return s;
}
public String[] nextElement() {
String[] line;
line = new String[columnCount+1];
try{
for (int i = 1; i <= columnCount; i++){
line[i] = results.getString(i);
}
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
}
return line;
}
public String getColumnValue(String columnName) {
try{
return results.getString(columnName);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return "";
}
}
public int getColumnCount(){
return columnCount;
}
public String getColumnName(int i) {
try{
return rsmd.getColumnName(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return "";
}
}
public String getColumnLabel(int i) throws SQLException {
try{
return rsmd.getColumnLabel(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return "";
}
}
public int getColumnDisplaySize(int i) throws SQLException {
try{
return rsmd.getColumnDisplaySize(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return 0;
}
}
public int getColumnType(int i) throws SQLException{
try{
return rsmd.getColumnType(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return 0;
}
}
public String getColumnTypeName(int i) throws SQLException{
try{
return rsmd.getColumnTypeName(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return "";
}
}
public String getCatalogName(int i) throws SQLException{
try{
return rsmd.getCatalogName(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return "";
}
}
public boolean isAutoIncrement(int i) throws SQLException{
try{
return rsmd.isAutoIncrement(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return false;
}
}
public String getSchemaName(int i) throws SQLException{
try{
return rsmd.getSchemaName(i);
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
return "";
}
}
}
Conclusion
Je me suis inspiré d'un code proposé sur le site www.commentcamarche.net que j'ai corrigé, complété et amélioré.
Je n'ai pas encore beaucoup testé ce code mais tout a l'air de fonctionner, à l'exception des méthodes qui renvoient les métadonnées, qui ne sont pas au point...
Exemple d'utilisation :
Database database = new Database("sun.jdbc.odbc.JdbcOdbcDriver"); database.open("jdbc:odbc:customers","",""); System.out.println(database.getProductName()+" "+database.getProductVersion());
DataSet data = database.executeQuery("select * from t_Customer");
database.getColumnMetaData("t_Customer");
String[] line = null; int i = 0 ;
if (data.hasMoreElements()) { i++ ; line = data.nextElement(); System.out.println(line[i]); }
database.close();
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
connexion à une base de données MySQL [ par malbackt ]
Bonjour;J'essaye depuis deux jous de me connecter à une base de données mysql mais je ne parvien toujours pas;mon code est le suivant:import
etablir une connexion a la base de données avec une applet [ par ghezella ]
salut; j'ai essayé d'établir une connexion a une base de données mysql sous une applet mais il m'affiche une erreur de connexion voici mon code: pac
Ouvrir une base des données MySQL en utilisant jpasswordfield en JAVA [ par Manyanya ]
Salut, J'utilise MySQL comme base des données. Dans sa gestion, j'ai défini des utilisateurs avec naturellment leur login et password respectifs. De
Déploiement : problème de connexion entre l'exécutable jar et ma base de données access [ par GueyeBass ]
Bonjour,j'ai créé un jar executable de mon application java utilisant une base de données access. Ensuite, j'ai installé le JRE dans la machine où je
connection application java avec une base des données mysql [ par aladino ]
bonjour mon projet conciste à créer une base des données avec mysql et le geré en utilisant une application java mais le probleme que je connais comme
connexion Base des données Acces avec Jbuilder [ par omarF ]
stp les programmeurs je cherche le code en java qui permet de faire la connexion entre ma base des données Acces et Jbuider , aider moi , c Urgent ,
Probleme de connexion à une base de données ACCESS contenu dans mon jar [ par xterreur ]
Bonjour à tous,J'essaie de développer une application Java dans laquelle je ne fais que recupérer des informations d'une base de données ACCESS. Dans
connection a la base mysql [ par ikramta ]
ikramsalut tout le mande bon je veut me connecter a la base mais toujour il me affiche le meme truc:il me donne ça: Connection ratée: java.lang.Clas
connexion avec la base de données [ par ahlemkh ]
bonjour, je suis en train de développer une système de gestion de bibliothèque ça englobe des interactions avec les base de données, les web services,
Connection à la base de données [ par MHaya ]
Salut à tous S'il vous plait j'ai un problème avec la connexion à la base de données, lorsque je clique sur le bouton OK qui me permet de me connecter
|
Derniers Blogs
UNE JOLIE-HORLOGE ET PAS QU'UN PEU !UNE JOLIE-HORLOGE ET PAS QU'UN PEU ! par neodante
Pour les possesseurs d'iPhone, ça y est Bijin Tokei - qui se traduit littéralement en Français par " Jolie Horloge " - est arrivé et GRATUITEMENT s'il vous plaît ! Après la version Tokyo, Hokkaido, night club, racing, Gal, "pour les mademoiselles'", . voi...
Cliquez pour lire la suite de l'article par neodante TECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICESTECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICES par ROMELARD Fabrice
Animé par: Gaetan Bouveret et Julien Chomarat Business Connectivity Services (BCS) est dans SharePoint 2010 la version 2 de Business Data Catalog (BDC dans SharePoint 2007). Il s'agit de la solution permettant de visualiser des données provenan...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE[DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE par orion
Comme de nombreux geek, je suis un grand amateur de série TV et je rate régulièrement des épisodes de mes séries préférés. Une solution s'offre à vous avec ce merveilleux site : Tv Gorge - www.tvgorge.com Moteur de recherche à l'appui, vous pouvez ...
Cliquez pour lire la suite de l'article par orion TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Vincent Bellet et Baptiste Giraudier La BI dans SharePoint 2010, Les nouveaux services d'application dans SP2010 et SQL Server Reporting services 2008 R2. La BI dans SharePoint est généralisée pour tous afin de permettre à tous les coll...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|