The student information in this example adds transactions to the database (the transaction can be submitted, transactions can be rolled back, and improved with local threads)
Main page index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html> <head> <title>Student Information Management</title> </head> <body> <a href='<c:url value="/query"/>?cmd=query'>View student information</a> <br><br> <!-- <a href="<c:url value='/StudServlet?cmd=save' />">Student Information Add</a> --> <h2>Student Information Add</h2> <form action='<c:url value="/query"/>?cmd=add' method="post"> Name:<input type="text" name="name"/><br><br> <fieldset style="border: solid;border-color: red;width: 250px;"> <legend>Book1</legend> Title:<input type="text" name="book"/><br><br> Price:<input type="text" name="price"/> </fieldset> <br> <fieldset style="border: solid;border-color:green;width: 250px;"> <legend>Book 2</legend> Title:<input type="text" name="book"/><br><br> Price:<input type="text" name="price"/> </fieldset> <br><br> <input type="submit" value="submit"/><br><br> </form> </body></html>
Tool for getting database connection 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.List;import java.util.Properties;public class ConnUtils5 { //Local thread management object, used to implement: The connection obtained by the same thread is the same private static ThreadLocal<Connection> t=new ThreadLocal<Connection>(); private final static List<Connection> pool=new ArrayList<Connection>(); private static int SIZE;//Read private ConnUtils5(){ } static{ Properties p=new Properties(); try { //The following method can read the resource file under classpath in a pure Java project, but the JavaEE project cannot be read. Because Tomcat changed the system's default class loader //p.load( ClassLoader.getSystemClassLoader().getSystemResourceAsStream("jdbc.properties")); // p.load(ClassLoader.getSystemResourceAsStream("jdbc.properties")); // Read the resource file under the classpath of the web project, use this to p.load(ConnUtils3.class.getClassLoader().getResourceAsStream("jdbc.properties")); String driver=p.getProperty("driver"); String url=p.getProperty("url"); String name=p.getProperty("username"); String pwd=p.getProperty("password"); String ssize=p.getProperty("size"); SIZE=Integer.parseInt(ssize); Class.forName(driver); for(int i=0;i<SIZE;i++){ final Connection con=DriverManager.getConnection(url,name,pwd); System.out.println("con=="+con); //Change the conn.close() method//Use proxy mode to generate an enhanced version of the conn object, intercept and change its close() method to Object nCon=Proxy.newProxyInstance( ConnUtils3.class.getClassLoader(), // conn.getClass().getInterfaces(), // This method does not work, it should be that the implementation class in the driver is not in the same space as our current program (the class loader is different) new Class[]{Connection.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("close")){ System.out.println("Return a link: "+(Connection)proxy); pool.add((Connection)proxy); return null; } return method.invoke(con, args); } }); pool.add((Connection)nCon); } } catch (Exception e) { e.printStackTrace(); } } public static synchronized Connection getConnection(){ //Get from t first, if there is one, take it out. If not, grab it in the pool and put the object in t Connection con=t.get(); if(con==null){ if(pool.size()<=0){ System.out.println("The connection in the pool is gone..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return getConnection(); } con=pool.remove(0); t.set(con);//Put it in t} return con;//Get one to move one}}Resource file jdbc.properties
##MySQLdriver=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8username=rootpassword=1234size=3##Oracle#driver=oracle.jdbc.driver.OracleDriver#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl#username=scott#password=tiger
Value Object
Stud.java
package cn.hncu.domain;import java.util.ArrayList;import java.util.List;/* * Method for creating a "one" square value object in one-to-many*/public class Stud { private String id; private String name; //※Add a collection specifically for "multi" squares---reflecting the "one-to-many relationship" in a multi-table private List<Book> books=new ArrayList<Book>();//Note that the collection must be new at or before construction. public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } 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; }}Book.java
package cn.hncu.domain;/* * Method for creating "multi" square value objects in one-to-many*/public class Book { private Integer id; // All basic data types are declared by the packaging class to prepare for future use of frameworks---the packaging class is compatible with frameworks (because generally frameworks use class reflection) private String name; private Double price; //※Add a variable of object type specifically for "one" square (note, don't use studyd)---reflect the "one-to-many relationship" in multiple tables private Stud s;//Set the master//private String studyd;//★★Don't set public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public Stud getS() { return s; } public void setS(Stud s) { this.s = s; } /* * When multi-table association, you should pay attention to a trap, that is, one party outputs the other party, and the other party in turn outputs the previous party, forming infinite recursion! */ @Override public String toString() { return "id=" + id + "," + name + "," + price;//The Stud object cannot be output here, otherwise infinite recursion}}QueryServlet.java servlet layer of stud layer
package cn.hncu.stud.servlet;import java.io.IOException;import java.util.List;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import 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.StudServiceImpl;public class QueryServlet extends HttpServlet { //Inject IStudService service=new StudServiceImpl(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String cmd=request.getParameter("cmd"); System.out.println("cmd:"+cmd); if("query".equals(cmd)){ query(request, response); }else if("add".equals(cmd)){ add(request, response); } } public void query(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Map<String, String>> studs=service.query(); request.setAttribute("studs", studs); request.getRequestDispatcher("/jsps/show.jsp").forward(request, response); } public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1 Collect parameters 2 Organize parameters (id field is left in dao to supplement) String name[]=request.getParameterValues("name"); System.out.println(name[0]); Stud s=new Stud(); s.setName(name[0]); // Book information String books[]=request.getParameterValues("book"); //Protect ---The price protection should also be written, here we are lazy if(books==null||books.length<=0){ return; } String prices[]=request.getParameterValues("price"); for(int i=0;i<books.length;i++){ Book b=new Book(); b.setName(books[i]); b.setPrice(Double.parseDouble(prices[i])); //※ Complete the "one-to-many" relationship of two value objects s.getBooks().add(b); //One-party b.setS(s); //Multiple-party} //3Call service layer try { service.save(s); } catch (Exception e) { //Direction failed page} }}The service layer interface of the stud layer:
package cn.hncu.stud.service;import java.util.List;import java.util.Map;import cn.hncu.domain.Stud;public interface IStudService { public List<Map<String, String>> query(); public void save(Stud stud);}Implementation Class
package cn.hncu.stud.service;import java.sql.Connection;import java.sql.SQLException;import java.util.List;import java.util.Map;import cn.hncu.domain.Stud;import cn.hncu.stud.dao.BookDAO;import cn.hncu.stud.dao.BookDAO;import cn.hncu.stud.dao.BookJdbcDao;import cn.hncu.stud.dao.StudDAO;import cn.hncu.utils.ConnUtils3;/*In the future, we usually use a table to operate independently. If there are several entity tables in the system, write a few dao. * In the future, the framework will do this, and we must do this, because the architecture is good! * * In case of using transactions: * 1. If there is only one dao, but multiple SQL statements need to be executed and add, delete and modify, the transaction must be opened. 2. If a service calls multiple dao, the transaction must also be opened. */public class StudServiceImpl implements 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) { Connection con=null; try { con=ConnUtils3.getConnection(); System.out.println("Get a link: "+con); con.setAutoCommit(false); dao_stud.save(stud); dao_book.save(stud.getBooks()); System.out.println("Commit a transaction..."); con.commit(); } catch (Exception e) { try { System.out.println("Rolle back a transaction..."); con.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } finally{ try { con.setAutoCommit(true); con.close(); } catch (SQLException e) { e.printStackTrace(); } } }} The dao layer of the stu layer
Stud interface
package cn.hncu.stud.dao;import java.util.List;import java.util.Map;import cn.hncu.domain.Stud;public interface StudDAO { public List<Map<String, String>> query(); public void save(Stud stud) throws Exception;}Stud implementation class
package cn.hncu.stud.dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import 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<String, String>> query() { List<Map<String, String>> list=new ArrayList<Map<String, String>>(); //A map is a row of data, List<Map> is the entire data table Connection con=null; try { con=ConnUtils3.getConnection(); Statement 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(); } finally{ try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } return list; } @Override public void save(Stud stud) throws Exception { Connection con=ConnUtils3.getConnection(); System.out.println("Get a link: "+con); String sql="insert into stud values(?,?)"; String uuid=UUID.randomUUID().toString().replace("-", ""); PreparedStatement pst=con.prepareStatement(sql); stud.setId(uuid);//In order to "multiple parties", that is, the book can get the "one party" id, it is specially supplemented with pst.setString(1, uuid); pst.setString(2, stud.getName()); System.out.println("1:"+uuid+",2:"+stud.getName()); pst.executeUpdate();// con.close();// get the same con, there is no need to close it here}}Book interface
package cn.hncu.stud.dao;import java.util.List;import cn.hncu.domain.Book;public interface BookDAO { public void save(List<Book> books) throws Exception;}Book implementation class
package cn.hncu.stud.dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.util.List;import cn.hncu.domain.Book;import cn.hncu.utils.ConnUtils3;public class BookJdbcDao implements BookDAO { @Override public void save(List<Book> books) throws Exception { Connection con=ConnUtils3.getConnection(); System.out.println("Get a link: "+con); String sql="insert into book(name,price,studid) values(?,?,?)"; PreparedStatement pst=con.prepareStatement(sql); for(Book b:books){ pst.setString(1, b.getName()); pst.setDouble(2, b.getPrice()); pst.setObject(3, "12132312");//Exception (deliberately give a non-existent foreign key field to test transaction rollback)-test transaction rollback// pst.setObject(3, b.getS().getId()); System.out.println("1:"+b.getName()+",2:"+b.getPrice()+",3:"+b.getS().getId()); pst.addBatch();//Add to batch} pst.executeBatch();//Execute batch// con.close();//Get the same con here, no need to close here}}Show student information page jsps/show.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html> <head> <title>Student Information Management</title> </head> <body> <h2>Student Information</h2> <c:forEach items="${studs}" var="x"> ${x.id},${x.name}<br/> </c:forEach> </body></html>Reproduction image:
For more information about the management system, please click "Management System Special Topic" to learn
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.