Récemment, lorsque j'ai vu la méthode du modèle de JDBCTemplete de Spring, je suis devenu très intéressé par les modèles et les rappels, et j'ai interrogé des informations et fait un résumé.
Fonction de rappel:
Le soi-disant rappel signifie que le programme client C appelle une certaine fonction A dans le programme de service, puis S appelle une certaine fonction B en C à un moment donné. Pour C, ce B est appelé une fonction de rappel. Une fonction de rappel n'est qu'une fonction implémentée par l'utilisateur en fonction de la convention d'appel de la fonction de rappel. Une fonction de rappel fait partie d'un workflow et le workflow détermine le moment de l'appel de la fonction (rappel). D'une manière générale, C n'appellera pas B par lui-même. Le but de C à fournir B est de laisser S l'appeler, et C doit le fournir. Étant donné que S ne sait pas qui est nommé d'après C, S s'accordera sur la spécification de l'interface de B (prototype de fonction), puis C dira à l'avance qu'il utilisera la fonction B via une fonction R de S. Ce processus est appelé enregistrement de la fonction de rappel, et R est appelé fonction d'enregistrement. Le service Web et Java RMI utilisent des mécanismes de rappel pour accéder aux programmes de serveur distant. La fonction de rappel contient les caractéristiques suivantes:
1. Appartient à une partie du flux de travail;
2. Il doit être déclaré (défini) conformément à la convention d'appel spécifiée par le flux de travail;
3. Le moment de son appel est déterminé par le workflow. L'implémentateur de la fonction de rappel ne peut pas appeler directement la fonction de rappel pour implémenter la fonction du workflow;
Mécanisme de rappel:
Le mécanisme de rappel est un modèle de conception commun. Il expose une fonction dans le flux de travail aux utilisateurs externes en fonction de l'interface convenue, fournit des données aux utilisateurs externes ou oblige les utilisateurs externes à fournir des données.
Mécanisme de rappel Java:
Il existe toujours certaines interfaces entre les modules logiciels. En termes de méthodes d'appel, ils peuvent être divisés en trois catégories: appels synchrones, rappels et appels asynchrones.
Appel synchrone: un appel de blocage, l'appelant doit attendre que l'autre partie termine l'exécution avant de revenir. C'est un appel à sens unique;
Rappel: un mode d'appel bidirectionnel, c'est-à-dire que l'appel appellera également l'interface de l'autre partie lorsque l'interface est appelée;
Appel asynchrone: un mécanisme similaire à un message ou un événement, mais sa direction d'appel est tout le contraire. Lorsqu'un service d'interface reçoit un certain message ou un événement se produit, il informera activement le client (c'est-à-dire l'appeler l'interface du client).
La relation entre les rappels et les appels asynchrones est très étroitement liée: les rappels sont utilisés pour mettre en œuvre l'enregistrement des messages asynchrones, et la notification des messages est réalisée par le biais d'appels asynchrones.
Instance de rappel
1. Interface de rappel
Public Interface Rappel {String Callback (); } 2. Appelant
classe publique un autre {rappel privé; // Appel de la méthode qui implémente la classe publique void setCallback (callback callback) {this.callback = callback; } // Lorsque l'entreprise en a besoin, appelez la méthode spécifique qui implémente la classe publique void docallback () {System.out.println (callback.callback ()); }} 3. Test de la fonction de rappel
classe publique TestCallCack {public static void main (String [] args) {// Créer la classe d'implémentation de l'appelant Another un autre = nouveau autre (); // Enregistrez l'interface arrière dans la classe d'implémentation Another.SetCallback (nouveau callback () {@Override public String callback () {return "vous êtes un cochon";}}); // Exécuter la fonction de rappel un autre.docallback (); }}L'utilisation de méthodes de rappel se produit généralement lors de l'utilisation de "Java Interface" et "Class Abstract". Le modèle de conception de la méthode du modèle utilise le mécanisme de rappel de la méthode. Ce modèle définit d'abord le squelette d'algorithme d'étapes spécifiques et retarde certaines étapes du modèle de conception implémenté dans la sous-classe. Le modèle de conception de la méthode de modèle permet aux sous-classes de redéfinir certaines étapes spécifiques d'un algorithme sans modifier la structure d'un algorithme.
Applicabilité du modèle de conception de modèle:
1. Implémentez la partie immuable d'un algorithme en même temps et laissez l'algorithme variable aux sous-classes pour l'implémenter.
2. Les comportements publics dans chaque sous-classe doivent être extraits et concentrés dans une classe de parent public pour éviter la duplication de code.
3. Les extensions de sous-classe peuvent être contrôlées.
Exemple de modèle:
Classe de méthode de modèle abstrait:
Public Abstract Class AbstractSup {// Méthodes qui nécessitent l'implémentation de la sous-classe Public abstract void print (); // méthode de modèle public void doprint () {System.out.println ("Exécuter la méthode du modèle"); pour (int i = 0; i <3; i ++) {print (); }}} Classe de méthode du modèle d'implémentation de sous-classe:
Public Class Sous-Class étend AbstractSup {@Override public void print () {System.out.println ("Méthode d'implémentation des sous-classes"); }} Classe de test de méthode du modèle:
classe publique TempleTeTest {public static void main (String [] args) {Subclass Subclass = new Subclass (); sous-classe.print (); sous-classe.doprint (); }} Ce qui suit est une introduction détaillée à l'utilisation de la méthode du modèle de ressort. En prenant JDBCTemplete à titre d'exemple, nous expliquerons en détail l'utilisation du mode modèle et du mécanisme de rappel.
Tout d'abord, jetons un coup d'œil à l'exemple de programmation JDBC classique:
public list <ser user> query () {list <ser utilisateur> userList = new ArrayList <User> (); String SQL = "SELECT * FROM User"; Connexion con = null; PréparetStatement PST = NULL; ResultSet rs = null; essayez {con = hsqldbutil.getConnection (); PST = CON.PrepareStatement (SQL); rs = pst.executequery (); Utilisateur utilisateur = null; while (Rs.Next ()) {user = new User (); User.SetId (Rs.GetInt ("ID")); user.setUserName (Rs.GetString ("user_name")); user.setbirth (Rs.GetDate ("Birth")); user.setCreatEdate (Rs.GetDate ("Create_Date")); userList.add (utilisateur); }} catch (sqlexception e) {e.printStackTrace (); } enfin {if (rs! = null) {try {Rs.close (); } catch (sqlexception e) {e.printStackTrace (); }} essayez {pst.close (); } catch (sqlexception e) {e.printStackTrace (); } try {if (! con.isclosed ()) {try {con.close (); } catch (sqlexception e) {e.printStackTrace (); }}} catch (sqlexception e) {e.printStackTrace (); }} return userList user; }
Une requête simple nécessite beaucoup de choses et traite également d'exceptions. Terons-le si nous ne voulons pas:
1. Obtenez la connexion
2. Obtenir une déclaration
3. Obtenez des résultats
4. itérer à travers le résultat et le résumer dans une collection
5. Fermer la connexion, l'énoncé et le résultat à tour de rôle, et considérer diverses exceptions, etc.
Si plusieurs requêtes généreront plus de code en double, vous pouvez utiliser le mécanisme de modèle. Grâce à l'observation, nous avons constaté que la plupart des étapes ci-dessus sont répétitives et réutilisables. Ce n'est que lorsque la traversée du résultat et le résumer dans une collection est personnalisable, car chaque table mappe différents haricots Java. Il n'y a aucun moyen de réutiliser cette partie du code, il ne peut être personnalisé.
Code de classe abstrait:
classe abstraite publique JDBCTemplate {// Méthode du modèle Public Final Object Execute (String SQL) lève SQLEXception {Connection Con = HsqldButil.getConnection (); Déclaration stmt = null; essayez {stmt = con.creatEstatement (); ResultSet rs = stmt.ExecuteQuery (SQL); Résultat de l'objet = DOInstatement (RS); // Méthode Résumé (Méthode personnalisée, implémentation de la sous-classe requise) Retour Résultat; } catch (sqlexception ex) {ex.printStackTrace (); jeter ex; } enfin {try {stmt.close (); } catch (sqlexception e) {e.printStackTrace (); } try {if (! con.isclosed ()) {try {con.close (); } catch (sqlexception e) {e.printStackTrace (); }}} catch (sqlexception e) {e.printStackTrace (); }}} // Méthode abstraite (méthode personnalisée) Objet abstrait protégé DOINSATATION (resultSet rs); }Dans cette classe abstraite, le processus principal de l'API SUN JDBC est encapsulé, et l'étape de traversée du résultat est placée dans la méthode abstraite DOINSTAMENT (), qui est implémentée par la sous-classe.
Code d'implémentation de sous-classe:
La classe publique JDBCTemplateUserImpl étend JDBCTemplate {@Override Protected Object DOINSTAMENT (ResultSet RS) {List <User> userList = new ArrayList <User> (); essayez {utilisateur utilisateur = null; while (Rs.Next ()) {user = new User (); User.SetId (Rs.GetInt ("ID")); user.setUserName (Rs.GetString ("user_name")); user.setbirth (Rs.GetDate ("Birth")); user.setCreatEdate (Rs.GetDate ("Create_Date")); userList.add (utilisateur); } return userList; } catch (sqlexception e) {e.printStackTrace (); retourner null; }}}Dans la méthode Doinstatement (), nous traversons le résultat et le renvoyons enfin.
Code de test:
String SQL = "SELECT * FROM User"; JDBCTemplate jt = new JDBCTemplateUserImpl (); List <ser user> userList = (list <serser>) jt.execcute (sql);
Le mécanisme de modèle a été utilisé jusqu'à présent, mais si vous avez besoin de hériter de la classe parent à chaque fois que vous appelez JDBCTemplate, il est assez gênant, donc le mécanisme de rappel peut jouer un rôle.
Le soi-disant rappel signifie passer une interface dans les paramètres de la méthode. Lorsque la classe parent appelle cette méthode, elle doit appeler la classe d'implémentation de l'interface réalisée dans la méthode.
Implémentation du mode de modèle Rappel Plus
Interface de rappel:
Interface publique StatementCallback {objet Doinstatement (instruction STMT) lève SQLEXception; } Méthode du modèle:
classe publique JDBCTEmplate {// Méthode du modèle Public Final Object Execute (StatementCallback Action) lève SqException {Connection Con = HsqldButil.getConnection (); Déclaration stmt = null; essayez {stmt = con.creatEstatement (); Résultat objet = action.doinstatement (RS); // Méthode de rappel Résultat Résultat; } catch (sqlexception ex) {ex.printStackTrace (); jeter ex; } enfin {try {stmt.close (); } catch (sqlexception e) {e.printStackTrace (); } try {if (! con.isclosed ()) {try {con.close (); } catch (sqlexception e) {e.printStackTrace (); }}} catch (sqlexception e) {e.printStackTrace (); }}}} Public Object Query (StatesCallback STMT) lève SQELLEXception {return execute (stmt); }}} Classe testée:
Public Object Query (Final String SQL) lève SQLEXception {class QueryStatementCallback implémente instructionCallback {public Object DOINStation (instruction stmt) lève SQException {resultSet rs = stmt.Executequery (sql); List <ser user> userList = new ArrayList <User> (); Utilisateur utilisateur = null; while (Rs.Next ()) {user = new User (); User.SetId (Rs.GetInt ("ID")); user.setUserName (Rs.GetString ("user_name")); user.setbirth (Rs.GetDate ("Birth")); user.setCreatEdate (Rs.GetDate ("Create_Date")); userList.add (utilisateur); } return userList; }} JdbcTemplate jt = new JDBCTemplate (); return jt.Query (nouveau queryStatementCallback ()); }
Pourquoi le printemps n'utilise-t-il pas des méthodes de modèle traditionnelles, mais coopérer également avec le rappel?
Imaginez simplement, s'il existe 10 méthodes abstraites dans la classe parent et toutes les sous-classes qui héritent de la mise en œuvre de toutes ces 10 méthodes abstraites, la sous-classe semblera très gonflée. Parfois, que dois-je faire si une sous-classe n'a besoin que de personnaliser une certaine méthode dans la classe parent? Pour le moment, le rappel est utilisé.
De plus, la méthode ci-dessus implémente essentiellement la méthode du modèle + mode de rappel. Mais c'est encore un peu loin de JDBCTemplate de Spring. Bien que nous ayons implémenté le mode Modèle de modèle + le mode de rappel ci-dessus, il semble un peu "laid" par rapport au JDBCTemplate de Spring. Spring présente les concepts de RowMapper et de ResultSetExtractor. L'interface RowMapper est responsable du traitement d'une certaine ligne de données. Par exemple, nous pouvons opérer sur une certaine ligne d'enregistrements dans la méthode MapRow, ou le résumer en entité. Le resultSetExtractor est un extracteur de données de données, qui est responsable de la traversée de la résolution et du traitement des données en fonction des règles du RowMapper. La différence entre RowMapper et ResultSetExtractor est que RowMapper traite une certaine ligne de données et renvoie un objet entité. Le resulturetExtractor traite un ensemble de données et renvoie une collection d'objets.
Bien sûr, ce qui précède n'est que les principes de base de la mise en œuvre de Spring JDBCTemplate. Spring JDBCTemplate a fait plus de choses, telles que l'encapsulation de toutes les opérations de base dans l'interface JDBCoperations, et l'utilisation de JDBCAccessor pour gérer les exceptions de données de données et de conversion.
Ce qui précède concerne cet article, j'espère qu'il sera utile à l'apprentissage de tout le monde.