Les informations sur les étudiants dans cet exemple ajoutent des transactions à la base de données (la transaction peut être soumise, les transactions peuvent être annulées et améliorées avec des threads locaux)
Index de page principale.jsp
<% @ Page Language = "Java" import = "java.util. *" Pageencoding = "utf-8"%> <% @ taglib uri = "http://java.sun.com/jsp/jstl/Core" Prefix = "C" %> <html> <a-head> <title> Student Management </Titre> </read> Value = "/ Query" />? Cmd = Query '> Afficher les informations de l'étudiant </a> <br> <br> <! - <a href = "<C: URL Value =' / StuderServlet? CMD = SAVE '/>"> Informations étudiantes Ajouter </a> -> <h2> Informations étudiantes Ajouter </h2> <formulaire Form =' <C: URL Value = "/ Query" />? Nom: <entrée type = "text" name = "name" /> <br> <br> <fieldset style = "border: solide; border-color: red; width: 250px;"> <gend> book1 </ légende> title: <input type = "text" name = "book" /> <br> <br> Price: <entrée = "text" name = "Price" /> </ fieldset> Style = "Border: Solid; Border-Color: Green; Width: 250px;"> <gend> livre 2 </gend> Titre: <Input Type = "Text" name = "book" /> <br> <br> Price: <Input Type = "Text" name = "Price" /> </ Fieldsset> <br> <br> <Entrée Type = "Soudre" Value = "Soumide" /> <br> <br> <br> <Form> </ body> </html>
Boîte à outils
Outil pour obtenir la connexion de la base de données Connutils5.java
Package cn.hncu.utils; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.proxy; import java.sql.connection; import java.sql.Drivermanager; import java.util.Arraylist; import java.util. java.util.properties; classe publique Connutils5 {// Objet de gestion de threads local, utilisé pour implémenter: La connexion obtenue par le même thread est le même threadlocal statique privé <Connexion> T = nouveau ThreadLocal <Connexion> (); Liste statique finale privée <Connexion> pool = new ArrayList <Connexion> (); Taille privée statique statique; // Lire private connutils5 () {} static {Properties p = new Properties (); Essayez {// La méthode suivante peut lire le fichier de ressources sous ClassPath dans un projet Java pur, mais le projet Javaee ne peut pas être lu. Parce que Tomcat a modifié le chargeur de classe par défaut du système //p.load (classloader.getSystemClassloader (). GetSystemResourceStream ("jdbc.properties")); // P.Load (classloader.getSystemResourceSstream ("jdbc.properties")); // Lire le fichier de ressources sous le chemin de classe du projet Web, utilisez-le pour p.load (connutils3.class.getClassLoader (). GetResourceSstream ("jdbc.properties")); String Driver = P.GetProperty ("Driver"); String url = p.getProperty ("URL"); String name = p.getProperty ("nom d'utilisateur"); String pwd = p.getProperty ("mot de passe"); String ssize = p.getProperty ("taille"); Size = Integer.ParseInt (SSIZE); Class.forname (pilote); for (int i = 0; i <size; i ++) {Final Connection con = driverManager.getConnection (URL, nom, pwd); System.out.println ("Con ==" + Con); // Modifier la méthode conn.close () // Utilisez le mode proxy pour générer une version améliorée de l'objet Conn, intercepter et modifier sa méthode close () en objet ncon = proxy.newproxyinstance (connutils3.class.getClassloader (), // Conn.getClass (). Programme actuel (Le chargeur de classe est différent) Nouvelle classe [] {connection.class}, new invocationhandler () {@Override public objet invoke (objet proxy, méthode de la méthode, objet [] args) lance throwable {if (method.getName (). retourner null;} return method.invoke (con, args); pool.add ((connexion) nCon); }} catch (exception e) {e.printStackTrace (); }} Connexion publique publique statique GetConnection () {// Profitez de T en premier, s'il y en a un, retirez-le. Sinon, saisissez-le dans le pool et mettez l'objet dans la connexion T Con = T.get (); if (con == null) {if (pool.size () <= 0) {System.out.println ("La connexion dans le pool est partie ..."); essayez {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } return getConnection (); } con = pool.remove (0); t.set (con); // mettez-le dans t} return con; // obtenez-en un pour en déplacer un}}par intérim
package cn.hncu.utils; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; importer java.lang.reflect.proxy; import java.sql.connection; import java.sql.sqxception; classe publique txproxy implémente invocationhandler {privilth TxProxy privé (objet SrCobj) {this.srCobj = srCobj; } objet statique public getProxy (objet srCobj) {System.out.println ("srCobj:" + srCobj); Objet newoBj = proxy.newproxyinstance (txproxy.class.getClassloader (), srCobj.getClass (). GetInterfaces (), new txproxy (srCobj)); System.out.println ("NewObj:" + NewObj); retourner newoBJ; } @Override Public Object Invoke (Proxy d'objet, méthode de la méthode, objet [] args) lève throwable {connection con = null; Objet returnObj = null; essayez {con = connutils5.getConnection (); System.out.println ("Invoke a obtenu un lien:" + con); con.setAutoCommit (false); returnObj = méthode.invoke (srCobj, args); System.out.println ("Soumettre une transaction ..."); Con.Commit (); } catch (exception e) {try {System.out.println ("Rolling Back a Transaction ..."); con.rollback (); } catch (sqlexception e1) {e1.printStackTrace (); }} enfin {try {con.setautoCommit (true); con.close (); } catch (sqlexception e) {e.printStackTrace (); }} return returnObj; }}Agent 2: Pas besoin de forcer le transfert, mais tout
package cn.hncu.utils; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; importer java.lang.reflect.proxy; import java.sql.connection; import java.sql.sqxception; classe publique txproxy2 implémente invocationhandler {Private Objet Srcjj = null; privé txproxy2 (objet srCobj) {this.srcobj = srCobj; } public static <t> t getProxy (class <t> c) {objet obj = null; essayez {obj = c.newinstance (); } catch (exception e) {e.printStackTrace (); } Objet newoBj = proxy.newproxyinstance (txproxy2.class.getClassloadher (), c.getInterfaces (), new txproxy2 (obj)); retour (t) newoBJ; } @Override Public Object Invoke (Proxy d'objet, méthode de la méthode, objet [] args) lève throwable {connection con = null; Objet returnObj = null; essayez {con = connutils5.getConnection (); System.out.println ("Invoke a obtenu un lien:" + con); con.setAutoCommit (false); returnObj = méthode.invoke (srCobj, args); System.out.println ("Soumettre une transaction ..."); Con.Commit (); } catch (exception e) {try {System.out.println ("Rolle Back a Transaction ..."); con.rollback (); } catch (sqlexception e1) {e1.printStackTrace (); }} enfin {try {con.setautoCommit (true); con.close (); } catch (sqlexception e) {e.printStackTrace (); }} return returnObj; }}annotation
Package CN.hncu.utils; import java.lang.annotation.elementType; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @target (valeur = elementType.Method) @retention (retententionpolicy.RuntIle) @terface @retention @retention (RetentionPolicy.RuntIle) @terface @retention @retention (RetentionPolicy.Runtime) Public '
Agent 3: Utilisez des annotations pour implémenter les transactions en cas de besoin
package cn.hncu.utils; importer java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.proxy; import java.sql.connection; import java.sql.sqxception; classe publique txproxy3 implémente invocationhandler {Private Objet Srcjj = null; privé txproxy3 (objet srCobj) {this.srCobj = srCobj; } public static <t> t getProxy (t srCobj) {objet newoBj = proxy.newproxyinstance (txproxy3.class.getClassloader (), srCobj.getClass (). GetInterfaces (), new txproxy3 (srcobj)); retour (t) newoBJ; } @Override public Object Invoke (Object Proxy, Method Method, Object [] args) lève Throwsable {/ * de cette façon pour implémenter uniquement l'interception de la méthode spécifiée if (method.getName (). Equals ("close")) {... intercept} else {return method.invoke (srcobj, args); } * / if (méthode.isannotationPresent (transaction.class)) {connexion con = null; Objet returnObj = null; essayez {con = connutils5.getConnection (); System.out.println ("Invoke a obtenu un lien:" + con); con.setAutoCommit (false); // Real Business Code, release returnObj = method.invoke (srCobj, args); System.out.println ("Soumettre une transaction ..."); Con.Commit (); } catch (exception e) {try {System.out.println ("Rolle Back a Transaction ..."); con.rollback (); } catch (sqlexception e1) {e1.printStackTrace (); }} enfin {try {con.setautoCommit (true); con.close (); } catch (sqlexception e) {e.printStackTrace (); }} return returnObj; } else {System.out.println ("Il n'y a pas d'annotation de transaction, il suffit de le libérer!"); Retour méthode.invoke (srCobj, args); }}}Fichier de ressources JDBC.Properties
## mysqldriver = com.mysql.jdbc.DriverUrl = jdbc: mysql: //127.0.0.1: 3306 / hncu? Useunicode = true & worseencoding = utf-8userName = rootpasswor D = 1234Size = 3 ## Oracle # Driver = Oracle.jdbc.Driver.oracledriver # url = JDBC: Oracle: mince: @ 127.0.0.1: 1521: ORCL # Username = Scott # Password = Tiger
Couche de servoie de serviette queyservlet.java
Package cn.hncu.stud.servlet; import java.io.ioexception; importer java.util.list; import java.util.map; import javax.servlet.servletException; import javax.servlet.http.httpleservlet; import javax.servlet.http.https Javax.servlet.http.httpservletResponse; import Cn.hncu.domain.book; import Cn.hncu.domain.stud; import Cn.hncu.stud.service.istudService; import Cn.hncu.stud.service.studSenviceImpl; Import Cn.hncu.UTILSYTXPROXY3 QueyServlet étend httpServlet {//inject//1.// istudService Service = (iStudService) txproxy.getProxy (new StudServiceImpll ()); //. // 3. ISTUDSERVICE Service = TxProxy3.GetProxy (new StudServiceImpll ()); public void doGet (demande httpservletRequest, réponse httpservletResponse) lève ServletException, ioException {doPost (request, réponse); } public void doPost (request httpServLetRequest, httpsservletResponse réponse) lève Servlexception, ioException {String cmd = request.getParameter ("cmd"); System.out.println ("CMD:" + CMD); if ("query" .equals (cmd)) {query (request, réponse); } else if ("add" .equals (cmd)) {add (request, réponse); }} public void Query (HttpServLetRequest Request, HttpServletResponse Response) lève ServletException, ioException {System.out.println ("Service:" + Service); List <map <string, string >> studs = service.query (); request.setAttribute ("studs", studs); request.getRequestDispatcher ("/ jsps / show.jsp"). Forward (demande, réponse); } public void add (httpservletRequest request, httpservletResponse réponse) lève ServletException, ioException {// 1 Collect Paramètres 2 Organize Paramètres (laissez le champ ID dans DAO pour compléter) Nom de chaîne [] = request.getParameTervalues ("Name"); Stud S = new Stud (); S.SetName (nom [0]); // Book Information String Books [] = request.getParameTervalues ("Book"); // Protéger --- La protection des prix doit également être écrite. Nous sommes paresseux ici if (books == null || books.length <= 0) {return; } Prix de chaînes [] = request.getParameTervalues ("Price"); for (int i = 0; i <books.length; i ++) {book b = new book (); B.SetName (livres [i]); B.SetPrice (double.Parsedouble (prix [i])); // ※ Complétez l'encapsulation des données de la relation "un à plusieurs" entre deux objets de valeur s.getBooks (). Add (b); // One-Party b.sets (s); // multiplatey} // 3 appelez la couche de service try {service.save (s); } catch (exception e) {// Page de mise en échec de la direction}}} La couche de service de la couche de goujon
interface:
package cn.hncu.stud.service; import java.util.list; import java.util.map; import cn.hncu.domain.stud; import Cn.hncu.utils.transaction; interface publique iStudService {public list <map <string, string >> wery (); // Notez que les annotations ne sont utiles que dans l'interface ,,,, La méthode écrite dans la classe d'implémentation n'est pas valide (elle ne décidera pas de démarrer la transaction) @transaction public void Save (Stud Stud) exception;}Classe d'implémentation
Package CN.HNCU.STUD.SERVICE; IMPORT JAVA.SQL.CONNECTION; IMPORT JAVA.SQL.SQLEXception; Import Java.util.List; Importer Java.util.map; Import Cn.hncu.Domain.Stud; cn.hncu.stud.dao.bookjdbcdao; import Cn.hncu.stud.dao.studdao; import Cn.hncu.utils.connnutils5; / * Nous utilisons généralement un tableau pour fonctionner indépendamment pendant le développement futur. S'il y a plusieurs tables entités dans le système, écrivez quelques DAO. * À l'avenir, le cadre le fera, et nous devons le faire, car l'architecture est bonne! * * En cas d'utilisation de transactions: * 1. S'il n'y a qu'un seul DAO, mais plusieurs instructions SQL doivent être exécutées et ajouter, supprimer et modifier, la transaction doit être ouverte. 2. Si un service appelle plusieurs DAO, la transaction doit également être ouverte. * / classe publique StudServiceIMPl implémente iStudService {// inject Studdao dao_stud = new StudJdbcdao (); Bookdao dao_book = new bookjdbcdao (); @Override public list <map <string, string >> query () {return dao_stud.query (); } @Override public void Save (Stud Stud) lève une exception {dao_stud.save (stud); dao_book.save (stud.getBooks ()); }} La couche Dao de la couche Stu
Pratique de séparation de l'interface de goujon, un tableau correspond à un DAO, préparez-vous au cadre
package cn.hncu.stud.dao; import java.util.list; import java.util.map; import cn.hncu.domain.stud; interface publique Studdao {public list <map <string, string >> query (); public void Save (Stud Stud) lève une exception;}Classe d'implémentation de goujon
package cn.hncu.stud.dao; import java.sql.connection; import java.sql.preparedstatement; import java.sql.resulttset; import java.sql.sqlexception; import java.sql.statement; import java.util.arraylist; import java.util.hashmap; java.util.list; importer java.util.map; import java.util.uuid; import Cn.hncu.domain.book; import Cn.hncu.domain.stud; import Cn.hncu.utils.connutils3; public class Studjdbcdao Implements Studdao {@Override Public List <map List <map <string, string >> list = new ArrayList <map <string, string >> (); // Une carte est une ligne de données, la liste <map> est la connexion entière de la table de données con = null; essayez {con = connutils3.getConnection (); Instruction st = con.createStatement (); String SQL = "SELECT * FROM Stud"; ResultSet rs = St.ExecuteQuery (SQL); while (Rs.Next ()) {map <string, string> m = new HashMap <String, String> (); m.put ("id", (String) Rs.GetObject (1)); m.put ("name", (String) Rs.GetObject (2)); list.add (m); } Rs.Close (); St.Close (); } catch (sqlexception e) {e.printStackTrace (); } enfin {try {con.close (); } catch (sqlexception e) {e.printStackTrace (); }} Retour List; } @Override public void Save (stud stud) lève une exception {connexion con = connutils3.getConnection (); System.out.println ("Obtenez un lien:" + con); String sql = "Insérer dans les valeurs de goujon (?,?)"; String UUID = uUid.randomuuid (). ToString (). Remplace ("-", ""); Préparé PST = CON.PrepareStatement (SQL); Stud.setid (UUID); // Pour "plusieurs parties", c'est-à-dire que le livre peut obtenir l'ID "One Party", il est spécialement complété par PST.SetString (1, UUID); PST.SETSTRING (2, Stud.GetName ()); System.out.println ("1:" + uuid + ", 2:" + stud.getName ()); pst.executeupdate (); // con.close (); // obtient le même con, il n'est pas nécessaire de le fermer ici}}Interface de livre
Le package cn.hncu.stud.dao; import java.util.list; import cn.hncu.domain.book; interface publique bookdao {public void Save (list <book> books) lève une exception;};Classe d'implémentation de livre
Package CN.hncu.stud.dao; Import Java.sql.Connection; Import Java.Sql.PreparedStation; Importer Java.util.list; Importer CN.HNCU.Domain.Book; Import Cn.hncu.utils.connuls3; Public Class Bookjdbcdao Implementation Bookdao {@override VOIC livres) lève une exception {connexion con = connutils3.getConnection (); System.out.println ("Obtenez un lien:" + con); String sql = "Insérer dans le livre (nom, prix, studid) valeurs (? ,?)"; Préparé PST = CON.PrepareStatement (SQL); pour (livre b: livres) {pst.setstring (1, b.getName ()); PST.SetDouble (2, B.GetPrice ()); PST.SetObject (3, "12132312"); // Exception (Donnez délibérément un champ de clé étrangère inexistante pour tester le rollback de transaction) -Test Rollback // PST.SetObject (3, b.gets (). getID ()); System.out.println ("1:" + b.getName () + ", 2:" + b.getprice () + ", 3:" + b.gets (). GetID ()); pst.addbatch (); // ajouter à Batch} PST.ExecuteBatch (); // Exécuter un lot // con.close (); // Obtenez le même con ici, pas besoin de fermer ici}} Valeur de la valeur
Objet de goujon
package cn.hncu.domain; import java.util.arraylist; import java.util.list; / * * méthode pour créer un objet de valeur carré "une" dans un seul * / classe publique class Stud {private string id; nom de chaîne privé; // ※ Ajoutez une collection spécifiquement pour "multi" carrés --- reflétant la "relation un à plusieurs" dans une liste privée multi-table <Book> Books = New ArrayList <Book> (); // Notez que la collection doit être nouvelle à la construction ou avant. public String getID () {return id; } public void setid (String id) {this.id = id; } public String getName () {Nom de retour; } public void setName (string name) {this.name = name; } public List <Book> getBooks () {return books; } public void setbooks (list <book> books) {this.books = books; } @Override public String toString () {return "id =" + id + "," + name + "," + books; }}Objet de livre
Package cn.hncu.domain; / * * Méthode de création d'objets de valeur carrée multi "dans un livre de classe un-à-plusieurs * / public {ID entier privé; // Tous les types de données de base sont déclarés par la classe d'emballage pour se préparer à une utilisation future des frameworks --- La classe d'emballage est compatible avec les frameworks (car généralement les frameworks utilisent la réflexion de classe) le nom de chaîne privé; double prix privé; // ※ Ajoutez une variable de type d'objet spécifiquement pour "un" carré (note, n'utilisez pas d'études) --- reflétez la "relation un à many" dans plusieurs tables Stud privé S; // définir le maître // String privé Studyd; // ★★ Ne définissez pas public Integer getID () {return id; } public void setid (INGER ID) {this.id = id; } public String getName () {Nom de retour; } public void setName (string name) {this.name = name; } public double getPrice () {prix de retour; } public void setPrice (double prix) {this.price = prix; } public stud get () {return s; } public void sets (stud s) {this.s = s; } / * * Lorsque l'association multi-table, vous devriez prêter attention à un piège, c'est-à-dire qu'une partie publie l'autre partie, et l'autre partie sort à son tour la partie précédente, formant une récursivité infinie! * / @Override public String toString () {return "id =" + id + "," + name + "," + prix; // L'objet Stud ne peut pas être sorti ici, sinon la récursivité infinie}}Afficher la page des informations de l'étudiant JSPS / show.jsp
<% @ Page Language = "Java" Import = "Java.util. *" Pageencoding = "UTF-8"%> <% @ Taglib uri = "http://java.sun.com/jsp/jstl/core" Prefix = "C"%> <html> <hadif> <t titre> Information Student Management </itle> </read> <c: foreach items = "$ {studs}" var = "x"> $ {x.id}, $ {x.name} <br/> </c: foreach> </odody> </html>Image de reproduction:
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.