ADO.Net ADO.Net ADO.Net ADO.Net

Transcription

ADO.Net ADO.Net ADO.Net ADO.Net
ADO.Net
ActiveX Data Object .Net (ADO.Net)
ADO.Net
API d’accès (local ou distant)
à une source de données : SGBD, tableur, fichier, messagerie, …
Fonctionne selon un principe client/serveur (local ou distant)
• client = le programme (C#, VB, C++, …)
• serveur = la source de données
Lionel Seinturier
INRIA Futurs Lille – Projet JACQUARD
Université Pierre & Marie Curie
Principe
• le programme ouvre une connexion
• il envoie des requêtes SQL
• il récupère les résultats
• ...
• il ferme la connexion
[email protected]
30/8/04
ADO.Net
1
Lionel Seinturier
ADO.Net
2
ADO.Net
Lionel Seinturier
ADO.Net
ActiveX Data Object .Net (ADO.Net)
Historique
ODBC Accès SGBD
• API d'interaction avec un SGBD
• nombreuses utilisations
- sauvegarde de données de manière sûre
- exploration du contenu d'un SGBD
- client/serveur 3 tiers
évolutions
DAO C++
VB RDO
unification
OLE-DB ts langages – API COM
présentation
traitement
simplification
(+ haut niveau)
donnée
ADO
ADO.Net
framework .Net
client
ADO.Net
serveur d'applications
3
SGBD
ADO.Net
Lionel Seinturier
ADO.Net
4
Lionel Seinturier
ADO.Net
ADO.Net
Fournisseur (provider) ADO.Net
Connection string ADO.Net
Implémentation de l’API pour un type de sources de données
Identifie la source de données à laquelle on se connecte
Principaux providers
• chaîne de caractères
• liste de couples propriété=valeur
• format dépend du provider
• SQL Server (>= 7.0)
• OLE-DB (SQL Server < 7.0, …)
• ODBC (Excel, Access, …)
• MySQL
•…
System.Data.SqlClient.SqlConnection
System.Data.OleDb.OleDbConnection
System.Data.Odbc.OdbcConnection
http://sourceforge.net/projects/mysqlnet/
• ODBC
"Driver={SQL Server};Server=localhost;Database=mydb;Uid=login;Pwd=passwd"
• OLE-DB
“Provider=sqloledb;Data Source=…;Database=…;User Id=…;Password=…”
•…
voir http://geekswithblogs.net/brcraju/archive/2004/02/03/1689.aspx
Fournisseur
Chaque provider = une classe
OLE-DB
ODBC
ADO.Net
5
Exemple
Lionel Seinturier
ADO.Net
6
ADO.Net
Lionel Seinturier
ADO.Net
Utilisation de ADO.Net
Utilisation de ADO.Net (suite)
L'ensemble de l'API ADO.Net est définie dans System.Data
3. Récupération du résultat
1. Ouverture d'une connexion avec la base comptes
reader.Read()
OdbcConnection cx =
new OdbcConnection("Driver={SQL Server};Server=localhost;Database=pubs;");
cx.Open();
reader.GetString(int column)
retourne vrai tant qu'il reste des enregistrements dans le résultat
et positionne le curseur sur l'enregistrement suivant
(ex. : reader.GetString(0) )
retourne la valeur de la colonne 0 de type String de l’enregistrement courant
2. Envoi d'une requête SELECT
GetInt32, GetBoolean, GetByte, GetDouble, GetFloat
OdbcCommand cmd = new OdbcCommand("SELECT * FROM ages");
OdbcDataReader reader = cmd.ExecuteReader();
idem pour des colonnes de type int, boolean, byte, double ou float
Envoi d'une requête CREATE, INSERT ou UPDATE
OdbcCommand cmd = new OdbcCommand("INSERT INTO ages VALUES ('toto',12)");
cmd.ExecuteNonQuery();
ADO.Net
7
Lionel Seinturier
while( reader.Read() ) {
String nom = reader.GetString(0);
int age = reader.GetInt32(1);
Console.WriteLine( nom + " a " + age + " ans" );
}
ADO.Net
8
Lionel Seinturier
ADO.Net
ADO.Net
Utilisation de ADO.Net (code complet)
Types de requêtes SQL
using System.Data;
using System.Data.Odbc;
• "normale"
- interprétée à chaque exécution
public class TestADONet {
• précompilée
- paramétrable
- préparée pour être exécutée plusieurs fois
- gérée par le programme
public static void Main( String[] args ) {
OdbcConnection cx = new OdbcConnection(
"Driver={SQL Server};Server=localhost;Database=pubs;" );
cx.Open();
• procédure stockée
- paramétrable
- écrite dans le langage interne du SGBD (ex SQL Server Transac-SQL)
- gérée par le SGBD
OdbcCommand cmd = new OdbcCommand("SELECT * FROM ages",cx);
OdbcDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
string nom = reader.GetString(0);
int age = reader.GetInt32(1);
Console.WriteLine( nom + " a " + age + " ans" );
}
+ masque schéma base
+ meilleures perf
+ validées par rapport schéma base
cx.Close();
- langage propriétaire (- évolution)
- risque de mélange
logiques traitement/donnée
} }
ADO.Net
9
Lionel Seinturier
ADO.Net
ADO.Net
10
Lionel Seinturier
ADO.Net
Requêtes SQL précompilées
Procédures stockées
1. Possibilité de définition de 1 ou +sieurs paramètres !
caractères ?
Exemple de procédure stockée Transact-SQL (SQL Server)
CREATE PROCEDURE [pubs].[GetRange]
@age int
AS
SELECT nom FROM ages WHERE age < @age
GO
OdbcCommand cmd = new OdbcCommand
("SELECT * FROM ages WHERE nom=? AND age>?",cx);
2. Valeurs des paramètres ajoutés à la commande
cmd.Parameters.Add(new OdbcParameter("","Bob"),cx);
cmd.Parameters.Add(new OdbcParameter("",Convert.ToInt32(5)),cx);
Le code d’appel de la procédure
• new OdbcParameter( string name, object value )
• paramètres ajoutés dans l'ordre de leur définition dans la requête
• name non significatif dans ce contexte (voir procédure stockée)
OdbcCommand cmd = new OdbcCommand("GetRange",cx);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add( new OdbcParameter("age",Convert.ToInt32(5) );
OdbcDataReader reader = cmd.ExecuteReader();
...
3. Exécution de la requête
OdbcDataReader reader = cmd.ExecuteReader();
...
ADO.Net
11
Lionel Seinturier
ADO.Net
12
Lionel Seinturier
ADO.Net
ADO.Net
Transactions
Transactions
Groupes de requêtes devant être exécutés de façon indivisible
Exemple
La transaction doit être
CREATE TABLE comptes (nom VARCHAR(30) PRIMARY KEY, solde FLOAT CHECK(solde>=0) );
- validée (commit) ! les résultats ne sont visibles qu'à partir de ce moment
- ou annulée (rollback)
OdbcCommand cmd1, cmd2;
cmd1 = new OdbcCommand("UPDATE comptes SET solde=solde+montant WHERE nom='Paul'",cx);
cmd2 = new OdbcCommand("UPDATE comptes SET solde=solde-montant WHERE nom='Bob'",cx);
OdbcTransaction trans = cx.BeginTransaction();
OdbcCommand cmd1 = new OdbcCommand("INSERT INTO ages VALUES ('Pierre',12)",cx);
OdbcCommand cmd2 = new OdbcCommand("UPDATE ages SET age=15 WHERE nom='Joe'",cx);
OdbcTransaction trans = cx.BeginTransaction();
cmd1.Transaction = trans;
cmd2.Transaction = trans;
cmd1.ExecuteNonQuery();
cmd2.ExecuteNonQuery();
déclaration du début de la transaction
trans.Commit();
validation de la transaction
ADO.Net
13
Lionel Seinturier
try {
cmd1.Transaction = trans;
cmd2.Transaction = trans;
cmd1.ExecuteNonQuery();
cmd2.ExecuteNonQuery();
trans.Commit();
}
catch( Exception e ) {
trans.Rollback();
}
ADO.Net
14
ADO.Net
Lionel Seinturier
ADO.Net
Accès aux données en mode déconnecté
Accès aux données en mode déconnecté
• par défaut c/s connecté vers SGBD
+ 1 seule copie des données (SGBD)
+ mises à jour simples
• datasets : représentation mémoire des données d'un SGBD
SELECT …
adapter.Update(dataset)
rés
eau
DataSet
connecté vs non connecté
n messages petite taille
vs 1 message grande taille
SELECT …
rés
eau
Data
Adapter
SGBD
adapter.Fill(dataset)
DataAdapter : gère liaison mémoire (DataSet) – SGBD
! contient les requêtes SQL (select, update, insert) associées aux données
Déconnecté
• pouvoir consulter/modifier les données off line
• économiser les ressources réseaux (connexions moins longues)
• travailler sur des données en mémoire plutôt que directement sur un SGBD
ADO.Net
15
Lionel Seinturier
ADO.Net
16
Lionel Seinturier
ADO.Net
ADO.Net
DataSet
Exemple d'utilisation d'un DataSet
Un DataSet contient
OdbcConnection cx = new OdbcConnection(
"Driver={SQL Server};Server=localhost;Database=pubs;" );
cx.Open();
• des DataTable
données sous forme de table
- des DataColumn
- nom, type, propriétés (autoincrement, unique, readonly, maxlength, …), …
- des DataRow
- valeurs
- des DataConstraint
• des DataRelation
relation entre 2 DataTable
• une DefaultView
Un DataSet peut être
• consulté
• modifié (valeurs, lignes)
• sauvegardé/chargé en XML
! mise à jour BD lors de Update()
ADO.Net
17
Lionel Seinturier
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = new OdbcCommand("SELECT * FROM comptes",cx);
OdbcCommandBuilder builder = new OdbcCommandBuilder(adapter);
DataSet dataset = new DataSet();
adapter.Fill(dataset);
cx.Close();
for( int i=0 ; i<dataset.Tables.Count ; i++ ) {
DataTable table = dataset.Tables[i];
DataColumnCollection columns = table.Columns;
for( int j=0 ; j<table.Rows.Count ; j++ ) {
DataRow row = table.Rows[j];
Console.WriteLine("Row "+j+": "+row["nom"]+" "+row["solde"]);
}
}
ADO.Net
ADO.Net
18
Lionel Seinturier
ADO.Net
Mise à jour d'un DataSet
DataView
Modification d'une valeur
Vue (pas de copie des données) sur une Datatable
table.Rows[0][0] = "Bill";
adapter.Update(dataset);
• séléction
• tri
Ajout d'une ligne
Mise à jour données dans la vue = maj des données dans la DataTable
DataRow myDataRow = table.NewRow();
myDataRow["nom"] = "John";
myDataRow["solde"] = 123;
table.Rows.Add(myDataRow);
adapter.Update(dataset);
DataView view = new DataView(table);
view.RowFilter = "nom='Bob'";
// sélection de(s) Bob
for( int i=0 ; i < view.Count ; i++ ) {
view.Delete(i);
// suppression aussi dans la DataTable
}
view.Sort = "nom, age DESC";
// d'abord pas nom puis par age décroissant
Expression de sélection "à la SQL"
- opérateur LIKE
- fonctions sum, avg, count, min, max
ADO.Net
19
Lionel Seinturier
ADO.Net
nom LIKE '*ob*'
20
Lionel Seinturier
ADO.Net
ADO.Net
Utilisation des DataSet avec les DataGrid
Trou de sécurité (bien connu)
DataGrid
Attaque "SQL injection" à partir de formulaires Web
composants
WinForm et WebForm
d'édition de
données tabulaires
CREATE TABLE notes ( netudiant text, note float );
Formulaire traité ASP (idem PHP, JSP, …)
String num = ...
String requete =
"SELECT * FROM notes WHERE netudiant='"+num+"'";
OdbcCommand cmd = new OdbcCommand(requete,cx);
datagrid.DataSource =
dataset.Tables[0];
datagrid.DataBind();
Saisie
'; SELECT * FROM notes WHERE ''='
requete =
DataGrid
Data
Adapter
DataSet
ADO.Net
21
SELECT * FROM notes WHERE
netudiant=''; SELECT * FROM notes WHERE ''=''
SGBD
Lionel Seinturier
! toutes les notes !!
ADO.Net
ADO.Net
≠ niv. isolation
ADO.Net
Lionel Seinturier
ADO.Net
Comparaison ADO.Net - JDBC
c/s
accès
désignation
initialisation
connexion
commande
curseur résultat
curs. multi-dir
curs. maj
deconnecté
transaction
22
Comparaison ADO.Net - JDBC
ADO.Net
JDBC
oui
provider
Driver=…
new …
Open()
…Command
…DataReader
non
non
DataSet
cx.BeginTransaction()
trans.Commit()
trans.Rollback()
oui
oui
driver
jdbc:mysql://…
Class.forName("…")
DriverManager.getConnection
Statement/PreparedStatement/CallableState
ResultSet
oui
oui
RowSet (JDBC 3.0)
cx.setAutoCommit(false)
cx.commit()
cx.rollback()
oui
23
Lionel Seinturier
≠ niv. isolation
méta-données
batch
pool de cx
ADO.Net
ADO.Net
JDBC
oui
oui
non
oui (provider)
oui
oui
oui
oui (JNDI)
24
Lionel Seinturier

Documents pareils