Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.
For the best experience please use the latest Chrome, Safari or Firefox browser.
Connection
en lui fournissant les informations nécessaires à la connexion.
String url = "jdbc:mysql://localhost:3306/mabase";
String user = "root"; String pwd = "root";
java.sql.Connection connexion = null;
try {
connexion = java.sql.DriverManager.getConnection(url, user, pwd);
//L'object connexion va nous permettre d'effectuer des requêtes...
...
} catch ( java.sql.SQLException e ) {
//Problème de connexion à la base !
}
//Lorsqu'on a fini de l'utiliser :
if(connexion != null) {
try {
connexion.close();
}
catch ( java.sql.SQLException e ) {
//Problème de déconnexion, ce n'est pas très grave...
}
}
SELECT
Connection
, on va créer un objet de type Statement
pour créer une requête, puis un objet ResultSet
pour traiter les résultats.
//La variable de type Statement permettra de gérer des requêtes SQL
Statement statement = connexion.createStatement();
//La variable de type ResultSet contiendra les résultats de la requêtes
String query = "SELECT id, marque, modele, date_mise_circulation FROM vehicule";
ResultSet resultSet = statement.executeQuery(query);
//On parcours un à un les résultats grâche à next() qui renvoie un booléen
//précisant s'il y a une ligne suivante dans nos résultats et récupère ce
//résultat le cas échéant (au début, son curseur est situé avant le premier élément).
while(resultSet.next()){
System.out.println("Identifiant : " + resultSet.getInt("id"));
System.out.println("Marque : " + resultSet.getString("marque"));
System.out.println("Modèle : " + resultSet.getString(3));
System.out.println("Date MC : " + resultSet.getDate("date_mise_circulation"));
System.out.println("? : " + resultSet.getBoolean("inconnu"));//SQLException
}
try catch
ou de propager l'exception avec un throws
au niveau de la méthode.
UPDATE
, DELETE
ou INSERT
executeUpdate()
.
Statement statement = connexion.createStatement();
String query = "INSERT INTO vehicule(marque, modele) VALUES ('Peugeot', '208')";
int status = statement.executeUpdate(query);//nombre de lignes insérées
query = "DELETE FROM vehicule WHERE marque = 'Renault'";
status = statement.executeUpdate(query);//nombre de lignes supprimées
query = "UPDATE FROM vehicule SET marque = 'Lada' WHERE marque = 'LADA'";
status = statement.executeUpdate(query);//nombre de lignes mises à jour
executeUpdate
peut lever une exception, il est donc nécessaire de la gérer.
//Soient les variables marque et modele contenant
//des valeurs renseignée par l'utilisateur
String query = "SELECT * FROM vehicule WHERE marque = '" +
marque + "')";
statement.executeQuery(query);//OK !
//Que se passe-t-il si modele vaut "test' OR '1' = '1" ?
//La solution ? Les Prepared Statements
String queryPrep = "SELECT * FROM vehicule WHERE marque = ? AND modele = ?)";
PreparedStatement statement = connexion.prepareStatement(queryPrep);
statement.setString(1, marque);
statement.setString(2, modele);
statement.executeQuery();
PreparedStatement
permettent de paramétrer la requête de manière plus fiable, de protéger la requête en échappant les valeurs des paramètres et d'augmenter les performances lors d'utilisations multiples grâce à la pré-compilation.
JDBC
présentent des avantages et des inconvénients.
JPA
.
JPA
pour Java Persistence API est un standard de JEE permettant notamment de faire correspondre des classes Java avec des tables de base de données (c'est ce qu'on appelle ORM pour Object-Relational Mapping). Hibernate
est une implémentation de ce standard et s'appuie sur JDBC
pour dialoguer avec la base de données.
import javax.persistence.*;
@Entity
@Table(name = "vehicule")
public class Vehicule {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "marque")//superflu car noms identiques
private String marque;
private String modele;
private String immatriculation;
@Column(name = "date_mise_circulation")
private Date dateMiseCirculation;
}
Vehicule
prêt à être automatiquement rempli avec les données issues de la table vehicule
.
Repository
vont nous permettre d'accéder et de manipuler les données :
JpaRepository
de Spring Data.
JpaRepository
MonEntiteRepository
) est la faire implémenter JpaRepository
.
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID> {
<S extends T> S save(S entity);
<S extends T> List<S> saveAll(Iterable<S> var1);
Optional<T> findById(ID id);
T getOne(ID var1);
List<T> findAllById(Iterable<ID> var1);
List<T> findAll();
boolean existsById(ID id);
long count();
void deleteById(ID id);
void delete(T entity);
void deleteAll(Iterable<? extends T> entities);
void deleteAll();
//...
}
//Fichier VehiculeRepository.java
public interface VehiculeRepository extends JpaRepository<Vehicule,Integer> {}
JpaRepository
sont définies dans le VehiculeRepository
, il ne reste plus qu'à les appeler.
READ
, voyons les autres
@Service
public class VehiculeService {
@Autowired
private VehiculeRepository vehiculeRepository;
...
public void test(){
//Create
Vehicule v = vehiculeRepository.save(new Vehicule("Peugeot", "208"));
//Read
Vehicule v2 = vehiculeRepository.findById(5).get();
...
v2.setDateMiseCirculation(new Date());
//Update
v2 = vehiculeRepository.save(v2);
...
//Delete
vehiculeRepository.delete(v2);
}
@Autowired
permet d'injecter une instance de VehiculeRepository
. Ces instances sont gérées par Spring, on n'effectue pas de new
.
Pagination et tri
JpaRepository
hérite de PagingAndSortingRepository
qui permet d'utiliser des fonctionnalités de pagination et de tri.
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
//Fichier VehiculeRepository.java
public interface VehiculeRepository extends JpaRepository<Vehicule,Integer> {}
//Classe VehiculeService
@Autowired
private VehiculeRepository vehiculeRepository;
...
public Page<Vehicule> findAllVehiculesPaging(Integer page, Integer size){
PageRequest pageRequest = PageRequest.of(page, size, Sort.Direction.ASC, "immatriculation");
return vehiculeRepository.findAll(pageRequest);
}
public List<Vehicule> findAllVehiculesSortingDesc(String attribute){
return vehiculeRepository.findAll(Sort.by(Sort.Direction.DESC, attribute));
}
//Autre classe utilisant VehiculeService
vehiculeService.findAllVehiculesPaging(0,5).forEach(System.out::println);
vehiculeService.findAllVehiculesSortingDesc("immatriculation").forEach(System.out::println);
public interface VehiculeRepository extends CrudRepository<Vehicule,Integer> {
//SELECT * FROM vehicule WHERE immatriculation = ?;
Vehicule findByImmatriculation(String immatriculation);
//SELECT * FROM vehicule WHERE marque = ? AND modele = ?;
List<Vehicule> findByMarqueAndModele(String marque, String modele);
//SELECT * FROM vehicule WHERE lower(marque) = ?;
List<Vehicule> findByMarqueIgnoreCase(String nom);
//Idem mais avec pagination
Page<Vehicule> findByMarqueIgnoreCase(String nom, Pageable pageable);
//SELECT * FROM vehicule WHERE date_mise_circulation < ?;
List<Vehicule> findByDateMiseCirculationBefore(LocalDate date);
//SELECT * FROM vehicule WHERE puissance > ? ORDER BY immatriculation DESC;
List<Vehicule> findByPuissanceGreaterThanOrderByImmatriculationDesc(Integer puissance);
}
Mot-clé | Exemple | Equivalent JPQL |
---|---|---|
And |
findByLastnameAndFirstname |
… where x.lastname = ?1 and x.firstname = ?2 |
Or |
findByLastnameOrFirstname |
… where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals |
findByFirstname ,findByFirstnameIs ,findByFirstnameEquals |
… where x.firstname = ?1 |
Between |
findByStartDateBetween |
… where x.startDate between ?1 and ?2 |
LessThan |
findByAgeLessThan |
… where x.age < ?1 |
LessThanEqual |
findByAgeLessThanEqual |
… where x.age <= ?1 |
GreaterThan |
findByAgeGreaterThan |
… where x.age > ?1 |
GreaterThanEqual |
findByAgeGreaterThanEqual |
… where x.age >= ?1 |
After |
findByStartDateAfter |
… where x.startDate > ?1 |
Before |
findByStartDateBefore |
… where x.startDate < ?1 |
IsNull |
findByAgeIsNull |
… where x.age is null |
IsNotNull,NotNull |
findByAge(Is)NotNull |
… where x.age not null |
Like |
findByFirstnameLike |
… where x.firstname like ?1 |
NotLike |
findByFirstnameNotLike |
… where x.firstname not like ?1 |
StartingWith |
findByFirstnameStartingWith |
… where x.firstname like ?1 (paramètre + % ) |
EndingWith |
findByFirstnameEndingWith |
… where x.firstname like ?1 (% + paramètre) |
Containing |
findByFirstnameContaining |
… where x.firstname like ?1 (paramètre entre deux % ) |
OrderBy |
findByAgeOrderByLastnameDesc |
… where x.age = ?1 order by x.lastname desc |
Not |
findByLastnameNot |
… where x.lastname <> ?1 |
In |
findByAgeIn(Collection<Age> ages) |
… where x.age in ?1 |
NotIn |
findByAgeNotIn(Collection<Age> ages) |
… where x.age not in ?1 |
True |
findByActiveTrue() |
… where x.active = true |
False |
findByActiveFalse() |
… where x.active = false |
IgnoreCase |
findByFirstnameIgnoreCase |
… where UPPER(x.firstame) = UPPER(?1) |
public interface VehiculeRepository extends CrudRepository<Vehicule,Integer> {
@Query("select v from Vehicule v where length(v.marque) = ? ")
List<Vehicule> findByLongueurMarque(Integer longueur);
}
JPQL
est un langage de requête orienté objet indépendant de la plateforme qui travaille sur les entités Java, pas sur les tables elles-mêmes.
public interface ProprietaireRepository extends CrudRepository<Proprietaire,Integer> {
@Query(value = "SELECT p.* FROM proprietaire p " +
"INNER JOIN vehicule v ON v.proprietaire_id = p.id " +
"WHERE v.marque = :marque1 " +
"AND EXISTS ( " +
"SELECT p2.* FROM proprietaire p2 " +
"INNER JOIN vehicule v2 ON v2.proprietaire_id = p2.id " +
"WHERE p2.id = p.id" +
"AND v2.marque = :marque2 " +
")", nativeQuery = true)
List<Proprietaire> findByDeuxMarques(@Param("marque1") String marque1, @Param("marque2") String marque2);
}
@Entity
public class Vehicule {
...
@OneToOne
@JoinColumn(name = "contrat_id", nullable = false)
//Le nullable = false est nécessaire si la FK a été
//définie en NOT NULL. Sinon on peut l'enlever.
private ContratAssurance contrat;
}
@Entity
public class ContratAssurance {
...
}
@Entity
public class Vehicule {
...
@OneToOne
@JoinColumn(name = "contrat_id", nullable = false)
//Le nullable = false est nécessaire si la FK a été
//définie en NOT NULL. Sinon on peut l'enlever.
private ContratAssurance contrat;
}
@Entity
public class ContratAssurance {
...
@OneToOne( mappedBy = "contrat" )
private Vehicule vehicule;
}
@Entity
public class Vehicule {
...
@OneToMany
@JoinColumn( name = "vehicule_id")
private List<Entretien> entretiens;
}
@Entity
public class Entretien {
...
}
@Entity
public class Vehicule {
...
@OneToMany( mappedBy = "vehicule" )
private List<Entretien> entretiens;
}
@Entity
public class Entretien {
...
@ManyToOne
@JoinColumn( name = "vehicule_id" )
private Vehicule vehicule;
}
@Entity
public class Vehicule {
...
@ManyToMany(mappedBy = "vehicules")
private List<Proprietaire> proprietaires;
}
@Entity
public class Proprietaire {
...
@ManyToMany
@JoinTable(name = "Vehicules_Proprietaires",
joinColumns = @JoinColumn(name = "proprietaire_id"),
inverseJoinColumns = @JoinColumn(name = "vehicule_id")
)
private List<Vehicule> vehicules;
}
@MappedSuperclass
public abstract class Publication {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
protected String title;
private int version;
private Date publishingDate;
}
@Entity
public class Book extends Publication {
private int pages;
}
@Entity
public class BlogPost extends Publication {
private String url;
}
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Publication {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
protected String title;
private int version;
@ManyToMany @JoinTable(name = "PublicationAuthor"...)
private Set authors = new HashSet();
private Date publishingDate;
}
@Entity
public class Book extends Publication {
private int pages;
}
@Entity
public class BlogPost extends Publication {
private String url;
}
Publication
.
@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "Publication_Type")
public abstract class Publication {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
protected String title;
private int version;
@ManyToMany @JoinTable(name = "PublicationAuthor"...)
private Set authors = new HashSet();
private Date publishingDate;
}
@Entity @DiscriminatorValue("Book")
public class Book extends Publication {
private int pages;
}
@Entity @DiscriminatorValue("Blog")
public class BlogPost extends Publication {
private String url;
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Publication {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
protected String title;
private int version;
@ManyToMany
@JoinTable(name = "PublicationAuthor"...)
private Set authors = new HashSet();
private Date publishingDate;
}
@Entity
public class Book extends Publication {
private int pages;
}
@Entity
public class BlogPost extends Publication {
private String url;
}