MyBatis use combs

1, Analysis of data flow sequence when MyBatis is used

Requirements:
The front end submits the form and requests the background to use MyBatis to insert a piece of data into the database

Use process:

  1. The front end returns the data. At this time, the data is transferred to the corresponding method of the controller
  2. The controller calls the corresponding method of the service object to pass the data
  3. Service is actually an interface through which data is passed to the interface implementation class serviceImp of the service
  4. serviceImp receives the call, receives the data, and calls the corresponding method of userDAO object in this class to pass the data
  5. userDAO is actually an interface. It has a Mapper annotation on its head. It will pass data to its corresponding Mapper through this annotation
  6. Mapper.html has many names, but mapper has a namespace attribute, which locates the location of its corresponding DAO interface. userDAO also finds its own mapper according to this attribute
  7. There are many methods in a DAO interface, so it also needs to have corresponding implementation in its corresponding Mapper, that is, to complete the specific implementation of this method, such as adding, deleting, modifying and querying in the database
  8. Mapper has an id attribute whose value corresponds to the name of each method in DAO. DAO has multiple methods and mapper also has multiple id values
  9. After finding the corresponding Mapper, find the corresponding implementation according to the id, transfer the data to the implementation, and the implementation will complete the operation on the database according to the established rules

PS: this data flow actually uses the dependency inversion principle in the design pattern.
Dependency reversal principle:

  1. High level modules should not rely on low-level modules, but on their abstraction.
  2. Abstract should not rely on details, details should rely on abstraction
  3. The core of this principle is: interface oriented programming
  4. The design concept of this principle: the variability of relative details and the stability of abstract things;
    An architecture based on abstraction is much more stable than an architecture based on detail
  5. The purpose of using interfaces or abstract classes is to formulate specifications without involving any details,
    Give the task of showing details to their implementation classes

2, Specific code (realizing registration function)

Directory structure:

regist.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <title>regist</title>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <link rel="stylesheet" type="text/css" href="css/style.css" />
   </head>
   <body>
      <div id="wrap">
         <div id="top_content">
               <div id="header">
                  <div id="rightheader">
                     <p>
                        2009/11/20
                        <br />
                     </p>
                  </div>
                  <div id="topheader">
                     <h1 id="title">
                        <a href="#">main</a>
                     </h1>
                  </div>
                  <div id="navigation">
                  </div>
               </div>
            <div id="content">
               <p id="whereami">
               </p>
               <h1>
                  register
               </h1>
               <form action="login.html" method="post">
                  <table cellpadding="0" cellspacing="0" border="0"
                     class="form_table">
                     <tr>
                        <!--The whole is asynchronous communication, and the form is not submitted, so it is in the form input of name meaningless-->
                        <td valign="middle" align="right">
                           user name:
                        </td>
                        <td valign="middle" align="left">
<!--                           Bind form to Vue Attribute-->
                           <input type="text" class="inputgri" v-model="user.username" />
                        </td>
                     </tr>

                     <tr>
                        <td valign="middle" align="right">
                           Real name:
                        </td>
                        <td valign="middle" align="left">
                           <input type="text" class="inputgri" v-model="user.realName" />
                        </td>
                     </tr>
                     <tr>
                        <td valign="middle" align="right">
                           password:
                        </td>
                        <td valign="middle" align="left">
                           <input type="password" class="inputgri" v-model="user.password" />
                        </td>
                     </tr>
                     <tr>
                        <td valign="middle" align="right">
                           Gender:
                        </td>
                        <td valign="middle" align="left">
                           male
                           <input type="radio" class="inputgri" v-model="user.sex" value="male" checked="checked"/>
                           female
                           <input type="radio" class="inputgri" v-model="user.sex" value="female"/>
                        </td>
                     </tr>
                     
                     <tr>
                        <td valign="middle" align="right">
                           Verification Code:
                        </td>
                        <td valign="middle" align="left">
                           <input type="text" class="inputgri" v-model="code" />
                        </td>

                        <td>
                           <!--from Vue Get from url attribute-->
                           <img id="num" :src="url"/>
<!--                           from Vue Called in the middle note getImage()Method of-->
                           <a href="javascript:;" @click="getImage">Change one</a>
                        </td>


                     </tr>
                  </table>
                  <p>
                     <input type="buttton" @click="register" class="button" value="Submit &raquo;" />
                  </p>
               </form>
            </div>
         </div>
         <div id="footer">
            <div id="footer_bg">
            ABC@126.com
            </div>
         </div>
      </div>
   </body>
</html>
<!--vue Import-->
<script src="/ems_vue/js/vue.js"></script>
<!--Asynchronous request import-->
<script src="/ems_vue/js/axios.min.js"></script>
<script>
<!--   vue example-->
   var app = new Vue({
      //Mount scope
      //From register As you can see from HTML, the whole is wrapped by wrap
      //So just pass in the scope wrap
      el:"#wrap",

      //Data obtained in scope
      data:{
         //Define an attribute url to store the verification code data obtained from the back end
         //Let the page call this property to get the verification code image
         url:"",

         //user object
         user:{
            sex:"male"
         },
         //Verification Code
         code:"",
      },
      methods:{
         //Used to replace verification code
         getImage(){
            this.getSrc();
         },

         //Get the verification code, reuse the code and make it easy to call
         getSrc(){
            var _this = this;
            //console.log("xxxx");
            //Asynchronous request: request verification code picture
            axios.get("http://localhost:8989/ems_vue/user/getImage?time="+Math.random()).then(res=>{
               console.log(res.data);
               // Assign the image to the url attribute
               _this.url = res.data;


            });
         },
         //Used to register user information
         register(){
            //this.code: it is equivalent to passing parameters in the address bar, so that UserController can directly get the code
            axios.post("http://localhost:8989/ems_vue/user/register?code="+this.code,this.user).then(res=>{
               console.log(res.data);
               // Give the user a hint
               // true: the registration is successful. Do you want to jump to the page
               // false: registration failed
               if (res.data.state){
                  alert(res.data.msg+"Click OK to jump to the login page!");
                  location.href="http://localhost:8989/ems_vue/login.html"
               }else{
                  alert(res.data.msg);
               }
            })
         }
      },
      //Process before page creation
      //It is used to request for verification code before page creation
      created(){
         //Get verification code
         this.getSrc();
      }
   })
</script>

UserController:

package com.chen.controller;

import com.chen.entity.User;
import com.chen.service.UserService;
import com.chen.utils.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author light
 * @version 1.0
 * @description
 * @create 2021-02-23 12:44
 */
@Slf4j
@RestController
@CrossOrigin//Allow cross domain
@RequestMapping("user")
public class UserController {

    @Autowired
    //In fact, this is a tool object through which business methods are called
    //The business method is written in the implementation class of UserService interface: UserServiceImpl
    private UserService userService;

    
    /**
     * @description Process user login requests
     * <br>
     * @param  
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author light
     * @since 2021/2/23 21:39
     */
    @PostMapping("login")
    public Map<String, Object> login(@RequestBody User user){
        log.info("Current login user information:[{}]",user.toString());
        Map<String, Object> map = new HashMap<>();
        try {
            User userDB = userService.login(user);
            map.put("state",true);
            map.put("msg","Login successful");
            map.put("user",userDB);
        }catch (Exception e){
            e.printStackTrace();
            map.put("state", false);
            map.put("msg",e.getMessage());
        }

        return map;
        
    }
    
    
    
    
    

    /*
    * Method for handling user registration
    * Return a registration information to the foreground
    * */
    @PostMapping("register")
    // The purpose of using @ RequestBody is to directly encapsulate objects
    // When Axios transmits data, it is directly transmitted in the form of JSON string
    // You must use @ RequestBody to automatically convert it into the User object we want
    // HttpServletRequest: stores the last verification code information transmitted to the browser before
    public Map<String, Object> register( @RequestBody User user,String code, HttpServletRequest request){
        log.info("User information:[{}]",user.toString());
        log.info("Verification code entered by the user:[{}]",code);
        Map<String, Object> map = new HashMap<>();

        try {
            String key = (String) request.getServletContext().getAttribute("code");
            if(key.equalsIgnoreCase(code)){
                //1. Call business method
                userService.register(user);
                map.put("state",true);
                map.put("msg","Prompt: Registration succeeded!");
            }else{
                throw new RuntimeException("Verification code exception");
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("state",false);
            map.put("msg","Tips:"+e.getMessage());
        }
        return map;
    }





    /**
     * @description Generate verification code image
     * <br>
     * @param request   HttpServletRequest object
     *                  Requests on behalf of clients,
     *                  When the client accesses the server through HTTP protocol,
     *                  HTTP All the information in the request header is encapsulated in this object,
     *                  Through the method provided by this object, you can get all the information requested by the client.
     * @return java.lang.String
     * @author light
     * @since 2021/2/23 12:47
     */
    @GetMapping("getImage")
    public String getImageCode(HttpServletRequest request) throws IOException {
        //1. Use tool class to generate verification code
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //2. Put the verification code into the scope of servletContext
        request.getServletContext().setAttribute("code",code);
        //3. Convert the picture to base64
        //Byte array output stream creates a byte array buffer in memory, and all data sent to the output stream is saved in the byte array buffer.
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        //Use the tool class to generate the verification code picture and put it into the byte array cache
        VerifyCodeUtils.outputImage(220,60,byteArrayOutputStream,code);
        //Use the tool class provided by spring to convert the verification code picture stream in the byte cache array into Base64
        //And return to the browser
        return "data:image/png;base64," + Base64Utils.encodeToString(byteArrayOutputStream.toByteArray());

    }

}

UserService:

package com.chen.service;

import com.chen.entity.User;

public interface UserService {

    //User registration
    void register(User user);

    //User login
    User login(User user);
}

UserServiceImp:

package com.chen.service;

import com.chen.dao.UserDAO;
import com.chen.entity.User;
import com.chen.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;

/**
 * @author light
 * @version 1.0
 * @description
 * @create 2021-02-23 15:55
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    // 1. This is also a tool object, which is used to call business methods
    // 2. The business method is actually written in usermapper In XML
    // 3. UserDAO through @ Mapper, usermapper XML connects the two through the direction of namespace
    // 4. UserMapper uses the attribute id to correspond to the methods of the UserDAO interface
    // 5. In fact, UserMapper is the method body of the method in UserDAO and the implementation of the method
    // 6. This is actually an embodiment of the design pattern (relying on the inversion principle)

    // ps: Dependency Inversion Principle:
    // 1. The high-level module should not rely on the low-level module, but on its abstraction.
    // 2. Abstraction should not rely on details, and details should rely on abstraction
    // 3. The core of this principle is: interface oriented programming
    // 4. The design concept of this principle: the variability of relative details and the stability of abstract things;
    //                   An architecture based on abstraction is much more stable than an architecture based on detail
    // 5. The purpose of using interfaces or abstract classes is to formulate specifications without involving any details,
    //    Give the task of showing details to their implementation classes
    private UserDAO userDAO;


    @Override
    public void register(User user){
        //0. Judge whether the user exists according to the user name entered by the user
        User userDB = userDAO.findByUserName(user.getUsername());
        if(userDB == null){
            //1. Generate user status
            user.setStatus("Activated");
            //2. Set user registration time
            user.setRegisterTime(new Date());
            //3. Call DAO
            userDAO.save(user);
        }else{
            throw new RuntimeException("User name already exists!");
        }


    }

    @Override
    public User login(User user) {
        // 1. Query according to the user name entered by the user
        User userDB = userDAO.findByUserName(user.getUsername());
        if(!ObjectUtils.isEmpty(userDB)){
            // 2. Compare passwords
            if(userDB.getPassword().equals(user.getPassword())){
                return userDB;
            }else{
                throw new RuntimeException("Password error");
            }
        }else {
            throw new RuntimeException("User name input error");
        }


    }
}

UserDAO:

package com.chen.dao;

import com.chen.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper //Create DAO object
public interface UserDAO {

    void save(User user);

    User findByUserName(String username);
}

UserMapper:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.chen.dao.UserDAO">

<!--    save-->
<!--     useGeneratedKeys="true"Assign the newly added primary key to the self-defined primary key keyProperty(id)in-->
    <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        insert into t_user values (#{id},#{username},#{realName},#{password},#{sex},#{status},#{registerTime})
    </insert>

    <select id="findByUserName" parameterType="String" resultType="User">
        select id, username,realname,password,sex,status,regsterTime
        from t_user where username=#{username}
    </select>

</mapper>

Tags: Java Mybatis

Posted by dicky18 on Fri, 15 Apr 2022 02:50:45 +0930