JSP & three tier architecture

Chapter 1 - EL expression

1.1 EL expression overview

What is an El expression

Expression Language: Expression Language, jsp2 Built in JSP after 0

Purpose: in order to make the JSP easier to write, the value (the value stored in the domain object) is simpler. (instead of script <%% >)

EL syntax

${el expression}

Purpose of EL expression

​ 1. Get data Get the data stored in the domain (request,session,ServletContext) object

​ 2.EL execution operation

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>01_EL Expression experience</title>
</head>
<body>
<%--el: It is used to get the value in the domain object,Or perform operations--%>
<%--format: ${el expression}--%>
<%--JSP-->Translate into Servlet-->There are many built-in objects()--%>
<%--jsp Built in object:request(HttpServletRequest),response(HttpServletResponse),session(HttpSession),application(ServletContext),config(ServletConfig)--%>

<%
    // Request to save value in domain object
    request.setAttribute("username","zhangsan");
%>

<h1>jsp mode:</h1>
<%= request.getAttribute("username") %><br/>

<%--el Built in objects inside: requestScope,sessionScope,applicationScope,pageScope,cookie--%>
<h1>el mode:</h1>
${requestScope.get("username")}<br/>

<h1>el Simple way:</h1>
${username}<br/>

</body>
</html>

1.2 El acquisition data

  • Be able to use the data in the el expression field (first save the data in the field object)

Get simple data type data

Syntax: ${requestScope|sessionScope|applicationScope. Attribute name};

Shortcut: ${attribute name}, which is the key in the domain object

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>02_el Get simple data type data</title>
</head>
<body>
    
     <%--use EL Get simple type data
        use:
            1.Storing data in domain objects
            2.use EL Get data from expression
        be careful:
            1.use EL The expression obtains data from the domain object. If the shorthand method is used, the default range is from small to large[ request-session-application]Get it,
                If you get it, you can return it directly. If you can't get it, you can return an empty string""
    --%>
    
<%
    //Request is the built-in object of JSP, and there is no need to create it. In JSP, you can directly use the large built-in objects of jsp9: request, session, application [ServletContext], out [response.getWriter()], response
    /*Save value to request domain object*/
    request.setAttribute("akey","aaa");

    /*Save value to session domain object*/
    session.setAttribute("bkey","bbb");

    /*Save the value (ServletContext) to the application domain object*/
    application.setAttribute("ckey","ccc");

    /*At the same time, a key and value with the same name are stored in the request domain object, session domain object and application domain object*/
    //request.setAttribute("rkey","rrr");
    //session.setAttribute("rkey","rrrr");
    //application.setAttribute("rkey","rrrrr");
%>

<h1>Get the value in the request domain object:</h1>
jsp mode:<br/>
<%= request.getAttribute("akey") %><br/>
el mode:<br/>
${requestScope.get("akey")}


<h1>take session Values in domain objects:</h1>
jsp mode:<br/>
<%= session.getAttribute("bkey")%><br/>
el mode:<br/>
${sessionScope.get("bkey")}<br/>

<h1>take application Values in domain objects:</h1>
jsp mode:<br/>
<%= application.getAttribute("ckey")%><br/>
el mode:<br/>
${applicationScope.get("ckey")}<br/>

<%--el Expression is a simple way to get the value of a domain object: ${Key name}--%>
<%--Search from small to large:  request-->session-->application --%>
<h1>el Simple way</h1>
${akey}<br/>
${bkey}<br/>
${ckey}<br/>
${rkey}<br/>


</body>
</html>

Get array

Syntax: ${key [subscript]} key is the key stored in the domain object

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>03_EL Get array</title>
</head>
<body>
<%
    /*An array is stored in the request field object*/
    String[] arr = {"china","hello","java"};
    request.setAttribute("array",arr);
%>

<h1>jsp Method value:</h1>
<%= ((String[])request.getAttribute("array"))[0]%><br/>
<%= ((String[])request.getAttribute("array"))[1]%><br/>
<%= ((String[])request.getAttribute("array"))[2]%><br/>

<%--grammar:${Array name[Indexes]}--%>
<h1>el Method value: </h1>
${requestScope.get("array")[0]}<br/>
${requestScope.get("array")[1]}<br/>
${requestScope.get("array")[2]}<br/>
${array[0]}<br/>
${array[1]}<br/>
${array[2]}<br/>

</body>
</html>

Get list

Syntax: ${key[index]} or ${key. Get (index)}; The list attribute name is the key stored in the domain object

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>04_EL obtain list aggregate</title>
</head>
<body>
<%
    ArrayList<String> list = new ArrayList<>();
    list.add("china");
    list.add("hello");
    list.add("java");
    request.setAttribute("list",list);
%>

<h1>jsp mode:</h1>
<%= ((ArrayList<String>)request.getAttribute("list")).get(0)%><br/>
<%= ((ArrayList<String>)request.getAttribute("list")).get(1)%><br/>
<%= ((ArrayList<String>)request.getAttribute("list")).get(2)%><br/>

<h1>el mode:</h1>
${requestScope.get("list").get(0)}<br/>
${requestScope.get("list").get(1)}<br/>
${requestScope.get("list").get(2)}<br/>
${list.get(0)}<br/>
${list.get(1)}<br/>
${list.get(2)}<br/>
${list[0]}<br/>
${list[1]}<br/>
${list[2]}<br/>

</body>
</html>

Get Map

Syntax: ${map attribute name. Key} or ${map attribute name. get("key")}. The map attribute name is the key stored in the domain object

<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>05_EL obtain Map</title>
</head>
<body>
<%
    HashMap<String,String> map = new HashMap<>();
    map.put("k1","v1");
    map.put("k2","v2");
    map.put("k3","v3");
    request.setAttribute("m",map);
%>

<%--grammar: ${Domain object key.map Collective key} perhaps ${Domain object key.get(map Collective key)}--%>
<h1>EL mode:</h1>
${m.k1}<br/>
${m.k2}<br/>
${m.k3}<br/>

${m.get("k1")}<br/>
${m.get("k2")}<br/>
${m.get("k3")}<br/>

</body>
</html>

Get bean

Syntax: ${key.javabean attribute}

Rely on getxxx() method; eg: getPassword() - remove get – > password() -- initial lowercase - > password

<%@ page import="com.geekly.bean.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>06_EL obtain bean</title>
</head>
<body>
<%
    User user = new User("zs","123456");
    request.setAttribute("u",user);
%>
<h1>el mode:</h1>
${u.username}<br/>
${u.password}<br/>

</body>
</html>

matters needing attention

  • If it can be obtained, it will be obtained. If it cannot be obtained, it will return the string "" instead of null

  • ${attribute name in domain}: successively find the specified attribute from requestScope|sessionScope|applicationScope

    If found, return immediately and end the search

    Return "" if not found

  • [] and Differences in methods: if there are special characters, use []

    • If "." appears in the attribute name For "+" - "and other special symbols, the quick access method is not easy to use. The following methods must be used:

    ${xxscope [attribute name]}

exceptional case:

<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>07_EL Precautions for value selection.jsp</title>
</head>
<body>
<%--If you can get it, you can get it,Cannot get return" "character string ,Not return null--%>
${akey}<br/>

<%--${Attribute name in domain}:Successively from requestScope|sessionScope|applicationScope Find the specified attribute in--%>
<%
    /*At the same time, a key and value with the same name are stored in the request domain object, session domain object and application domain object*/
    //request.setAttribute("rkey","rrr");
    //session.setAttribute("rkey","rrrr");
    //application.setAttribute("rkey","rrrrr");
%>
${rkey}<br/>

<%
    request.setAttribute("a.b.c.d","abcd");

    HashMap<String,String> map = new HashMap<>();
    map.put("a.k1","v1");
    map.put("k2","v2");
    map.put("k3","v3");
    request.setAttribute("m",map);

%>
<%--
[]and.Differences in methods: Use if there are special characters[]
- If the property name appears".""+""-"When waiting for a special symbol,The shortcut is not easy to get,The following methods must be used:
${xxxScope["Attribute name"]}
${key["Attribute name"]}
--%>
<h1>el mode:</h1>
${a.b.c.d} -- ${requestScope.get("a.b.c.d")} -- ${requestScope["a.b.c.d"]}<br/>
${m.a.k1} -- ${requestScope.get("m").get("a.k1")} -- ${m["a.k1"]}<br/>

</body>
</html>

1.3 EL execution operation

2.1 arithmetic operation

​ +,-,*,/,%

+: the plus sign represents the addition operation in the EL expression and is not used for splicing. If it is in the string form of numbers, the EL expression will automatically carry out type conversion and then carry out arithmetic operation

  • +Cannot splice strings

    <body>
    <%
        request.setAttribute("num",10);
    %>
    
    <h1>EL Perform operations: And java The operation is the same in</h1>
    ${10 + 20}<br/>
    ${10 > 20}<br/>
    ${num + 20}<br/>
    
    <h1>EL Perform operations: And java The operation is different in</h1>
    <%--Arithmetic operator+Sign operator--%>
    <%--java The addition of basic types and strings in is splicing--%>
    <%--EL The addition of basic types and strings in cannot be spliced,If it is an array plus a string,And the string is a number,Automatically formatted,Otherwise, it will be abnormal--%>
    ${num +  "20"}<br/>
    ${num +  "abc"}<br/>
    
    
    </body>
    

2.2 relation operation

​ > < >= <= != ==

2.3 logic operation

&& || !

2.4 non empty judgment [ key ]

​ empty,

​ **1. Judge whether an object is null, and return true if it is null**

​ 2. Judge whether the length of the collection is 0. If the collection is null or the length is 0, return true

​ 3. Judge whether a string is null or "". If so, return true

​ not empty

Syntax: ${empyt attribute name}; The attribute name is the key value in the domain object

<%--empty:  Judge whether an object is null;  Judge whether the set length is 0;   Judge whether a string is ""--%>
<%
    User u1 = new User();
    User u2 = null;
    ArrayList<String> list1 = new ArrayList<>();
    ArrayList<String> list2 = null;
    String str1 = "";
    String str2 = null;

    request.setAttribute("u1",u1);
    request.setAttribute("u2",u2);
    request.setAttribute("list1",list1);
    request.setAttribute("list2",list2);
    request.setAttribute("str1",str1);
    request.setAttribute("str2",str2);
%>

${empty u1}<br/>
${empty u2}<br/>
${empty list1}<br/>
${empty list2}<br/>
${empty str1}<br/>
${empty str2}<br/>
<hr/>
${not empty u1}<br/>
${not empty u2}<br/>
${not empty list1}<br/>
${not empty list2}<br/>
${not empty str1}<br/>
${not empty str2}<br/>

Chapter 2 - JSTL tag library

2.1 overview of JSTL tag library

What is a JSTL tag library

JSTL (JSP Standard Tag Library) is a continuously improved open source JSP tag library, which is maintained by apache's jakarta team. This JSTL tag library is not integrated into JSP. If you want to use it, you need to import the jar package

Role of JSTL tag library

In order to simplify the operation of data on jsp pages; eg: traverse data, judge data, etc

JSTL and EL are golden partners: JSTL performs logical processing and EL obtains data display.

Categories of JSTL tag library

Tag library function descriptionuri of tag librarySuggested prefix
Core tag libraryhttp://java.sun.com/jsp/jstl/corec
XML tag libraryhttp://java.sun.com/jsp/jstl/xmlx
Internationalization / formatting label Libraryhttp://java.sun.com/jsp/jstl/fmtfmt
Database tag libraryhttp://java.sun.com/jsp/jstl/sqlsql
EL custom functionhttp://java.sun.com/jsp/jstl/functionsfn

Summary

  1. JSTL: JSP standard tag library, used as logic processing, can replace java small script and simplify JSP development
  2. Function: judge data and traverse data
  3. Usage: since JSTL is not integrated into JSP, you need to import jar package when using it

2.2 JSTL core tag library

Steps for using core tag library

  1. Import jar packages (jstl.jar and standard.jar)

  2. Import the core tag library <% @ taglib prefix = "C" URI on the JSP page=“ http://java.sun.com/jsp/jstl/core " %>

if tag

Attribute nameWhether EL is supportedAttribute typeAttribute description
testtruebooleanA conditional expression that determines whether to process the contents of the label body
varfalseStringUsed to specify the name of an attribute that saves the execution result of the test attribute to a Web domain
scopefalseStringSpecify which Web domain to save the execution result of the test attribute to
  • grammar
<c:if test="el expression ${..}" [var="Give a name to the result of the previous expression"] [scope="Save the results in that field by default page"]>
</c:if>
  • example
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        //Domain objects store data
        request.setAttribute("age",6);
    %>
    <%--
        if Label: used to judge  test Attribute value is true,Then execute if The content in the label body is false,Do not execute
            test: Setting judgment conditions can be used EL Expression to judge and return a boolean Type results true|false
            var: Declare a variable to store the judgment result
            scope: Store the judgment result variable into a scope for later use
    --%>
    <c:if test="${age >= 7}" var="flag" scope="request">
        <h4>You can go to primary school</h4>
    </c:if>
    <c:if test="${age<7}">
        <h4>Go home and play in the mud</h4>
    </c:if>
    <h3>if Judgment result: ${requestScope.flag}</h3>
</body>
</html>

choose tag - if else if

  • Syntax:

    • <c:choose>
    • < C: when test = "el expression" >
    • <c:otherwise> else
  • example

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        //Domain objects store data
        request.setAttribute("age",15);
        //Demand: more than 6 years old can go to primary school, more than 13 years old can go to middle school, more than 18 years old can go to college, if less than or equal to 6 years old, go home and play in the mud
        //Analysis: implementation using multiple if judgments
        //realization:
    %>
    <%--c:choose It means multiple if Select structure  c:when It means if judge  c:otherwise It means else--%>
    <c:choose>
        <c:when test="${age>18}">
            go to university
        </c:when>
        <c:when test="${age>13}">
            Go to middle school
        </c:when>
        <c:when test="${age>6}">
            Go to primary school
        </c:when>
        <c:otherwise>
            Go home and play in the mud
        </c:otherwise>
    </c:choose>
</body>
</html>

foreach tag

Attribute nameWhether EL is supportedAttribute typeAttribute description
varfalseStringSpecifies the attribute name that saves the element to which the current iteration is applied to the Web domain page
itemstrueAny supported typeCollection object to iterate over
varStatusfalseStringSpecify the attribute name of saving the object representing the current iteration state information to the Web domain page
begintrueintIf the items attribute is specified, the iteration starts from the begin element in the collection, and the index value of the begin is numbered from 0; If the items attribute is not specified, the iteration starts from the value specified in begin and ends at the end value
endtrueintSee the description of the begin attribute
steptrueintSpecifies the step size of the iteration, that is, the iteration increment of the iteration factor
  • Simple use:

    <%--forEach Simple use of labels
            Requirements: use foreach Tag traversal 1-10 Each digital display word is titled red
            forEach Tags: used to traverse data
                var: Iteration variables in foreach It is required to obtain iterative variable data in the label body el expression
                begin: Start traversing from the first few
                end: End traversal to what end
                step: Step interval
                varStatus: Record the status information of iteration variables
    --%>
    
    <c:foreach begin="Where to start" end="Where does it end" var="Assignment variable for each traversal" step="step">
    	//The foreach is executed once every time it is traversed
    </c:foreach>		
    
  • Complex use:

    <c:foreach items="use el Extract the collection from the domain object" var="Assignment variable for each traversal" varStatus="Traversal state">
    	//The foreach is executed once every time it is traversed
    </c:foreach>
    
  • c: varStatus property in foreach.

    This object records some information of the currently traversed element:

    Index: returns the index. Start from 0

    Count: returns the count. Start with 1

    Last: is it the last element

    First: is it the first element

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>04_forEach label</title>
</head>
<body>
<%--Ordinary cycle: Cycle printing 10 times hello jsp...--%>
<%--begin: Cycle start position--%>
<%--end: Cycle end position--%>
<%--step:step--%>
<%--var: Store traversal variables(field,default page)--%>
<c:forEach begin="1" end="10" step="1" var="i">
    <font color="red">hello jsp...${i}</font><br/>
</c:forEach>

<%--enhance for loop: Loop through the elements in the collection--%>
<%
    ArrayList<String> list = new ArrayList<>();
    list.add("china");
    list.add("hello");
    list.add("java");
    request.setAttribute("l",list);
%>
    
<%--items:Set or array to iterate...--%>
<%--varStatus:Record the status during the iteration()--%>
<%--
c:forEach Medium varStatus Properties.
This object records some information of the currently traversed element:
       		   index:Returns the index. Start from 0
        		count:Returns the count. Start with 1
       		    last:Is it the last element
        		first:Is it the first element
--%>
<c:forEach items="${l}" var="e" varStatus="status">
    ${e}<br/>
    Index of the current loop:${status.index}<br/>
    Number of current cycles:${status.count}<br/>
    Is the element from the current iteration the last element:${status.last}<br/>
    Is the element from the current iteration the first element:${status.first}<br/>
    <hr/>
</c:forEach>

</body>
</html>

Chapter III - comprehensive case and development model

Case - the case of completing the transfer v1

  • When you click the submit button, the payer will transfer the amount entered by the payee according to the security license.

1. Case preparation

  • Preparation of database

    create database day26;
    use day26;
    create table account(
        id int primary key auto_increment,
        name varchar(20),
        money double
    );
    
    insert into account values (null,'zs',1000);
    insert into account values (null,'ls',1000);
    insert into account values (null,'ww',1000);
    
  • page

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title here</title>
    </head>
    
    <body>
    <form  action="ServletTransfer" method="post">
      <table border="1px" width="500px" align="center">
        <tr>
          <td>Payer </td>
          <td><input type="text" name="from"></td>
        </tr>
        <tr>
          <td>Payee</td>
          <td><input type="text" name="to"></td>
        </tr>
        <tr>
          <td>amount of money</td>
          <td><input type="text" name="money"></td>
        </tr>
        <tr>
          <td colspan="2"><input type="submit"></td>
        </tr>
      </table>
    </form>
    
    </body>
    </html>
    
  • jar package

  • Tool class

  • configuration file

2. Code implementation

  • UserServlet
@WebServlet("/ServletTransfer")
public class ServletTransfer extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            // 1. Deal with garbled code
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");

            //2. Obtain request parameters (payer, payee, transfer amount)
            String fromUsername = request.getParameter("from");
            String toUsername = request.getParameter("to");
            String moneyStr = request.getParameter("money");
            double money = Double.parseDouble(moneyStr);

            //3. Business logic judgment (whether the balance is enough for transfer, whether the name of the payee is legal,...)
            //3. Create QueryRunner object
            QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());

            //4. Execute sql statement
            String sql1 = "update account set money = money - ? where name = ?";
            int rows1 = qr.update(sql1, money, fromUsername);

            String sql2 = "update account set money = money + ? where name = ?";
            int rows2 = qr.update(sql2, money, toUsername);

            //5. Judge the result, and then respond to the result to the page (transfer succeeded, transfer failed)
            if (rows1 > 0 && rows2 > 0){
                // Transfer succeeded
                response.getWriter().println("Transfer succeeded!");
            }else{
                // Transfer failed
                response.getWriter().println("Transfer failed!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
            // Transfer failed
            response.getWriter().println("Transfer failed!");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

Development mode

JSP development mode I

jsp+javabean: Implementation

JavaBean:Entity class. Characteristics: privatization attribute, public getter setter Method, parameterless construction.

1. Browser request server jsp

2.jsp processing request response browser

All the code is in jsp

Question:

​ 1. All codes are in jsp, and there will be a lot of code redundancy, which is not conducive to code maintenance and modification

​ 2.jsp is an outdated technology of the previous era. jsp execution efficiency is very low. jsp – > translate into java code – > compile class files – > execute

JSP development mode II

JSP + Servlet + JavaBean is called MVC development mode

MVC: development mode

M: model model (javaBean: encapsulating data)

V: View view (JSP: display data)

C: controller (Servlet: processing logic code, as controller)

Mode 3: three-tier architecture

  • Layering in software: it is divided into different layers according to different functions. It is usually divided into three layers: presentation layer (web layer), business layer and persistence (database) layer.

  • Naming of package names at different levels

layeredPackage name
Presentation layer (web layer)com. geekly. Writing servlets for Web
Business layer (service layer)com.geekly.service write service class
Persistence layer (database access layer)com. geekly. Writing Dao classes
JavaBeancom.geekly.bean encapsulates data
Tool classcom.geekly.utils writing tool class
  • Meaning of stratification:
    1. Decoupling: reduce the coupling between layers.
    2. Maintainability: improve the maintainability of the software, and the modification and update of existing functions will not affect the original functions.
    3. Scalability: improve the scalability of the software. Adding new functions will not affect the existing functions.
    4. Reusability: when calling functions between different layers, the same functions can be reused.

Disadvantages: the amount of code increases and the structure is complex. When adding new functions, you need to write web, service and dao once respectively.

Case - case v2- three-tier structure for completing transfer

  • Rewrite the transfer case with a three-tier architecture
@WebServlet("/transfer")
public class TransferServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //0. Chinese garbled code processing
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            //1. Get the request parameter [payer, payee, amount]
            String from = request.getParameter("from"); //Payer 
            String to = request.getParameter("to");     //Payee
            double money = Double.parseDouble(request.getParameter("money"));     //Transfer amount
            //2. Call business processing
            TransferService transferService = new TransferService();
            boolean flag = transferService.transfer(from,to,money);
            //3. Response
            if(flag){
                response.getWriter().print("Transfer succeeded!");
            }else{
                response.getWriter().print("Transfer failed!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("Server exception!");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
public class TransferService {

    /**
     * Transfer business
     * @param from  Payer 
     * @param to    Payee
     * @param money Transfer amount
     * @return Is the transfer successful? true|false
     */
    public boolean transfer(String from, String to, double money) throws SQLException {
        //1. Processing business [judge whether the transfer amount of the payer and the payee is reasonable, assuming that everything is normal]
        //2. Call dao
        TransferDao transferDao = new TransferDao();
        //2.1: decrease of payer's money
        int rows1 = transferDao.reduceMoney(from,money);

        //2.2: increase of payee's money
        int rows2 = transferDao.addMoney(to,money);
        //3. Judge whether the transfer is successful according to the dao processing result and return it
        if(rows1>0 && rows2>0){
            return true;
        }
        return false;
    }
}
public class TransferDao {

    /**
     * Decrease in payer's money
     * @param from
     * @param money
     * @return
     */
    public int reduceMoney(String from, double money) throws SQLException {
        //1. Operation database
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "update account set money = money-? where name=?";
        return queryRunner.update(sql,money,from);
    }

    /**
     * Increase in payee's money
     * @param to
     * @param money
     * @return
     */
    public int addMoney(String to, double money) throws SQLException {
        //1. Operation database
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "update account set money = money+? where name=?";
        return queryRunner.update(sql,money,to);
    }
}

Case v3 - transaction completion control

  • When you click the submit button, the payer will transfer the amount entered by the payee according to the security license. Control with manual transactions

DBUtils implements transaction management

APIexplain
QueryRunner()Create a QueryRunner object Used when manually committing transactions
query(connection,String sql, Object[] params, ResultSetHandler rsh)Query (requires incoming Connection)
update(connection,String sql, Object... params)to update
public class TransferService {

    /**
     * Transfer business
     * @param from  Payer 
     * @param to    Payee
     * @param money Transfer amount
     * @return Is the transfer successful? true|false
     * Demand: transfer includes two operations: one is money decrease and the other is money increase. The transfer is successful only when both operations are successful. If one fails, the transfer fails, and the amounts of the payer and payee should remain unchanged
     * Analysis: to encapsulate the two transfer operations into a whole, use the characteristics of transaction: execute multiple operations as a whole. If you want to succeed, you will succeed, if you want to fail, you will fail
     * Use of transactions:
     *      1.Open transaction: connection setAutoCommit(false);
     *      2.Execution operation: money decrease, money increase
     *      3.Transaction commit or transaction rollback: true: connection commit();      false|exception:connection. rollback();
     * Transaction usage details: if all connection objects are the same, transaction control cannot be performed if they are not the same
     * Where transactions are used:
     *      Transactions are used in the service layer to execute multiple database operations as a whole.
     */
    public boolean transfer(String from, String to, double money) throws Exception {

        /********1.Start manual transaction*******/
        Connection connection = C3P0Utils.getConnection();
        connection.setAutoCommit(false);


        try {
            //1. Processing business [judge whether the transfer amount of the payer and the payee is reasonable, assuming that everything is normal]
            //2. Call dao
            TransferDao transferDao = new TransferDao();
            //2.1: decrease of payer's money
            int rows1 = transferDao.reduceMoney(connection,from,money);

            //Man made exceptions for testing
            //int i = 1/0;

            //2.2: increase of payee's money
            int rows2 = transferDao.addMoney(connection,to,money);
            //3. Judge whether the transfer is successful according to the dao processing result and return it
            if(rows1>0 && rows2>0){
                //Transfer successfully submitted transaction
                connection.commit();
                return true;
            }else{
                //Transfer failed rollback transaction
                connection.rollback();
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            //An exception occurred and the transaction was rolled back
            connection.rollback();
            return false;
        }
    }
}
public class TransferDao {

    /**
     * Decrease in payer's money
     * @param from
     * @param money
     * @return
     */
    public int reduceMoney(Connection connection, String from, double money) throws SQLException {
        //1. Operation database
        //Note: transaction control can only be performed when multiple operations use the same connection, so the parameterless construction method is used when creating QueryRunner object at this time
        QueryRunner queryRunner = new QueryRunner();
        String sql = "update account set money = money-? where name=?";
        return queryRunner.update(connection,sql,money,from);
    }

    /**
     * Increase in payee's money
     * @param to
     * @param money
     * @return
     */
    public int addMoney(Connection connection, String to, double money) throws SQLException {
        //1. Operation database
        QueryRunner queryRunner = new QueryRunner();
        String sql = "update account set money = money+? where name=?";
        return queryRunner.update(connection,sql,money,to);
    }
}
  1. Transaction usage steps
    1. Manually start transaction: connection setAutoCommit(false);
    2. Execute operation: multiple operations need to use the same connection object connection
    3. Transaction commit or transaction rollback: connection commit(); connection. rollback();
  2. Transaction usage location: in the Service layer [a business function contains multiple operations as a whole]
  3. Obtain the connection object in the Service layer and transfer it to the dao layer for operation database.

Case - case v4- transaction control enhancement for completing transfer

  • When you click the submit button, the payer will transfer the amount entered by the payee according to the security license. Use transactions for control

ThreadLocal

In the "transaction transfer parameter version", we must modify the number of parameters of the method and transfer the connection object before the whole transaction operation can be completed. Can I pass the parameter if not? In JDK, we are provided with a tool class: ThreadLocal, which can share data in one thread.

​ java.lang.ThreadLocal, which provides thread local variables to share data in the current thread. The bottom layer of the ThreadLocal tool class is a Map. The key stores the current thread, and the value stores the data to be shared

//Simulate ThreadLocal class 
public class ThreadLocal{
	private Map<Thread,Object> map = new HashMap<Thread,Object>();
	
	public void set(Connection conn){
		map.put(Thread.currentThread(),conn); //Take the current thread object as the key
	}
		
	public Object get(){
		return map.get(Thread.currentThread()); //Only the current thread can fetch value data
	}
}
ThreadLocal:Realize data sharing under the current thread [much smaller range]  
be similar to ServletContext Share data under the current application [wider range]
Conclusion: to ThreadLocal Object can only be used under the current thread.
  • ConnectionManager
public class ConnectionManager {
    // Create ThreadLocal object
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    // Provide a method to obtain the connection object
    public static Connection getConnection() throws Exception{
        // Get the value in ThreadLocal (connection object)
        Connection connection = threadLocal.get(); 

        // If the connection object is not obtained, add a connection object. The connection object is not stored in ThreadLocal for the first time. Therefore, after obtaining, store the connection in ThreadLocal so that the same thread can obtain it later
        if (connection == null){
            connection = C3P0Utils.getConnection();
            threadLocal.set(connection);
        }

        // Return connection object
        return connection;
    }
}
public class TransferService {

    /**
     * Transfer business
     * @param from  Payer 
     * @param to    Payee
     * @param money Transfer amount
     * @return Is the transfer successful? true|false
	*/
    public boolean transfer(String from, String to, double money) throws Exception {

        /********1.Start transaction manually*******/
        Connection connection = ConnectionManager.getConnection();
        connection.setAutoCommit(false);

        try {
            //1. Processing business [judge whether the transfer amount of the payer and the payee is reasonable, assuming that everything is normal]
            //2. Call dao
            TransferDao transferDao = new TransferDao();
            //2.1: decrease of payer's money
            int rows1 = transferDao.reduceMoney(from,money);

            //Man made exceptions for testing
            //int i = 1/0;

            //2.2: increase of payee's money
            int rows2 = transferDao.addMoney(to,money);
            //3. Judge whether the transfer is successful according to the dao processing result and return it
            if(rows1>0 && rows2>0){
                //Transfer successfully submitted transaction
                connection.commit();
                return true;
            }else{
                //Transfer failed rollback transaction
                connection.rollback();
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            //An exception occurred and the transaction was rolled back
            connection.rollback();
            return false;
        }

    }
}
public class TransferDao {

    /**
     * Decrease in payer's money
     * @param from
     * @param money
     * @return
     */
    public int reduceMoney(String from, double money) throws Exception {
        //1. Operation database
        //Note: transaction control can only be performed when multiple operations use the same connection, so the parameterless construction method is used when creating QueryRunner object at this time
        QueryRunner queryRunner = new QueryRunner();
        String sql = "update account set money = money-? where name=?";
        return queryRunner.update(ConnectionManager.getConnection(),sql,money,from);
    }

    /**
     * Increase in payee's money
     * @param to
     * @param money
     * @return
     */
    public int addMoney(String to, double money) throws Exception {
        //1. Operation database
        QueryRunner queryRunner = new QueryRunner();
        String sql = "update account set money = money+? where name=?";
        return queryRunner.update(ConnectionManager.getConnection(),sql,money,to);
    }
}
  1. Theadlocal: an object provided by JDK Data can be shared as long as it is in the same thread
  2. The ConnectionManager is extracted. The connections in service and Dao are obtained from the ConnectionManager

summary

	1.EL Gets the data in the domain object
    2.EL Perform operations
    3.JSTL----if label,forEach label
    4.Transfer case---->Case 4
        
- Can say el Function of expression
    In order to make JSP It's easier to write,  Value(Get the value stored in the domain object)Easier.(Replace script <% %>)
    
- Can use el Expression acquisition javabean Properties of
    Simple type: ${Attribute name}
	Array type: ${Attribute name[Indexes]}
	List aggregate: ${Attribute name[Indexes]}  perhaps ${Attribute name.get(Indexes)}
	Map aggregate: ${Attribute name.key}  perhaps ${Attribute name.get(key)}
	JavaBean: ${Attribute name.JavaBean Attribute name}

- Can use jstl Label Library if label
<c:if test="el expression ${..}" [var="Give a name to the result of the previous expression"] [scope="Save the results in that field by default page"]>
</c:if>
    
- Can use jstl Label Library foreach label
<c:foreach begin="Where to start" end="Where does it end" var="Assignment variable for each traversal" step="step">
	//The foreach is executed once every time it is traversed
</c:foreach>
    
<c:foreach items="use el Extract the collection from the domain object" var="Assignment variable for each traversal" varStatus="Traversal state">
	//The foreach is executed once every time it is traversed
</c:foreach>  
    
- Be able to use the three-tier architecture mode to display user cases
    web
	service
    dao
    utils
    bean
- Can use ThreadLocal
    Ensure that the objects used in the same thread are the same
    
- Able to complete transfer cases

Keywords: Javascript Vue.js architecture

Added by Wakab on Sat, 05 Feb 2022 14:39:02 +0200