[Java] SpringBoot basic grammar and application

The following analysis and application are all for springboot with front-end and back-end separation

1. Analysis of each level

Divided into several levels:
Hierarchy

1.1 Hierarchical relationship

entity
mapper
service
serviceImpl
controller

Reference: Hierarchical Relationship Analysis
Hierarchy

1.2 Hierarchical role

See also: Hierarchy

  1. entity layer

Same type: model layer = entity layer = domain layer
Function: used to store our entity classes, which are basically consistent with the attribute values ​​in the database.

  1. mapper layer

Similar: mapper layer = dao layer
Function: perform data persistence operations on the database, and its method statements are directly aimed at database operations

  1. service layer

Same type: Only one service layer
Function: The service layer is the controller for the controller layer, that is, for our users.
The impl of service is a file that integrates mapper and service.

  1. controller layer

Similar: controller layer = web layer
Function: controller, import service layer, because the method in service is what we use, the controller performs business operations by receiving the parameters passed from the front end, and then returns the processing results to the front end.

2. Database: MyBatis

CRUD syntax:

<?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.main.datainfo.mapper.UserMapper">
    <select id="getAllUsers" resultType="User">select * from user</select>
    <select id="getUserByPhone" resultType="User">select * from user where phone=#{phone}</select>
    <insert id="insertUser">
        insert into user(name,password,phone,job,question,answer, tags)
        values (#{name},#{password},#{phone},#{job},#{question},#{answer},#{tags})
    </insert>
    <update id="updatePasswd">
        update user set password = #{new_password} where phone = #{phone}
    </update>
</mapper>

Among them, the id should correspond to the id in Mapper

2.1 Stepping on pits

2.1.1 The query result is null or 0

The database field name is set to underlined: user_id, the query result is 0, and the query result of changing to varchar type is null. It turns out that it is a problem with the MyBatis mechanism. Either set the resultMap yourself, or remove the underscore.
Reference: [MyBatis stepped on the pit] Execute sql correctly and print it on the console, but the value is [null] ==> underlined field name

2.2 Application

2.2.1 Browse article record query

Specific requirements:
Query information about articles browsed by a user.
Note:
It is possible that a user browsed this article at the previous moment, and browsed this article again at the next moment. This article only appears once in the table, and it is the latest browsing result.

Note: The PageHelper tool is used.

The query statement is as follows:

	<select id="getBehaviorsByUserIDAndType" resultType="com.main.datainfo.entity.Behavior">
        select * from behavior where id in (
            select max(id) from behavior
            where userID=#{userID} and type=#{type} group by articleID order by time desc
        ) order by time desc
    </select>

Reference: Basic use of PageHelper
The statements that use PageHelper are as follows:

	@Override
    public List<Behavior> getBehaviorsByUserIDAndTypeByPage(int userID, int type, int pageNum,int pageSize){
    
    
        PageHelper.startPage(pageNum, pageSize);
        return behaviorMapper.getBehaviorsByUserIDAndType(userID, type);
    }

3. Rights management

Very comprehensive: understand at a glance! Front-end and back-end separated login interception based on Springboot interceptor

3.1 Create an interceptor

package com.main.datainfo.interceptor;

import com.main.datainfo.entity.User;
import com.main.datainfo.service.AuthService;
import com.main.datainfo.utils.HttpContextUtil;
import com.main.datainfo.utils.Result;
import com.main.datainfo.utils.TimeUtil;
import com.main.datainfo.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import java.time.LocalDateTime;

public class AuthInterceptor implements HandlerInterceptor {
    
    
    @Autowired
    private AuthService authService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
    
    
        String token = TokenUtil.getRequestToken(request);
        //如果token为空
        if (StringUtils.isBlank(token)) {
    
    
            setReturn(response,400,"用户未登录,请先登录");
            return false;
        }
        //1. 根据token,查询用户信息
        User user = authService.findByToken(token);
        //2. 若用户不存在,
        if (user == null) {
    
    
            setReturn(response,400,"用户不存在");
            return false;
        }
        //3. token失效
        if (TimeUtil.StringToLocalDateTime(user.getExpireTime()).isBefore(LocalDateTime.now())) {
    
    
            setReturn(response,400,"用户登录凭证已失效,请重新登录");
            return false;
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    
    

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    
    

    }
    //返回错误信息
    private static void setReturn(HttpServletResponse response, int status, String msg) throws IOException {
    
    
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtil.getOrigin());
        //UTF-8编码
        httpResponse.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        Result build = Result.build(status, msg);
        String json = JSON.toJSONString(build);
        httpResponse.getWriter().print(json);
    }

}

3.2 Register interceptor: Config class

import com.main.datainfo.interceptor.AuthInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        InterceptorRegistration registration = registry.addInterceptor(new AuthInterceptor());
        registration.addPathPatterns("/**");//所有路径都被拦截
        registration.excludePathPatterns("/login");//login不被拦截
    }
}

3.3 service and serviceImpl class

package com.main.datainfo.service;

import com.main.datainfo.entity.User;

public interface AuthService {
    
    

    User findByPhone(String phone);
    User findByToken(String token);
    String createToken(User user);

    //根据token去修改用户token ,使原本token失效
    void logout(String token);
}

Some query operations in UserMapper are used

package com.main.datainfo.service.impl;

import com.main.datainfo.entity.User;
import com.main.datainfo.mapper.UserMapper;
import com.main.datainfo.service.AuthService;
import com.main.datainfo.utils.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.UUID;

@Service
public class AuthServiceImpl implements AuthService {
    
    

    @Autowired
    private UserMapper userMapper;

    @Override
    public User findByPhone(String phone) {
    
    
        return userMapper.getUserByPhone(phone);
    }
    @Override
    public User findByToken(String token) {
    
    
        return userMapper.getUserByToken(token);
    }
    //12小时后失效
    private final static int EXPIRE = 12;

    @Override
    public String createToken(User user) {
    
    
        //用UUID生成token
        String token = UUID.randomUUID().toString();
        //当前时间
        LocalDateTime now = LocalDateTime.now();
        //过期时间
        LocalDateTime expireTime = now.plusHours(EXPIRE);
        //保存到数据库

        user.setLoginTime(TimeUtil.LocalDateTimetoString(now));
        user.setExpireTime(TimeUtil.LocalDateTimetoString(expireTime));
        user.setToken(token);
        userMapper.updateLoginInfo(user);
        return token;
    }

    @Override
    public void logout(String token) {
    
    
        User user = userMapper.getUserByToken(token);
        //用UUID生成token
        token = UUID.randomUUID().toString();
        //修改用户的token使原本的token失效,前端需配合将token清除
        user.setToken(token);
        userMapper.updateLoginInfo(user);
    }
}

3.4 Controller class

package com.main.datainfo.controller;

import com.main.datainfo.entity.Token;
import com.main.datainfo.entity.User;
import com.main.datainfo.service.AuthService;
import com.main.datainfo.utils.Result;
import com.main.datainfo.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping
public class AuthController {
    
    

    @Autowired
    AuthService authService;

    @RequestMapping("/login")
    public Result login(HttpServletRequest request) {
    
    
        String phone = request.getParameter("phone");
        String password = request.getParameter("password");
        //System.out.println(phone+" "+password);
        //用户信息
        User user = authService.findByPhone(phone);
        //账号不存在、密码错误
        if (user == null || !user.getPassword().equals(password)) {
    
    
            return Result.build(400, "用户名或密码错误");
        } else {
    
    
            //生成token,并保存到数据库
            String token = authService.createToken(user);
            Token tokenVO = new Token();
            tokenVO.setToken(token);
            return Result.ok(tokenVO);
        }
    }

    @PostMapping("/logout")
    public Result logout(HttpServletRequest request) {
    
    
        //从request中取出token
        String token = TokenUtil.getRequestToken(request);
        authService.logout(token);
        return Result.ok();
    }

    @RequestMapping("/test")
    public Result test() {
    
    
        return Result.ok("恭喜你,验证成功啦,我可以返回数据给你");
    }
}

4. File preview

Refer to my other blog posts:
[1] [Back-end learning] The back-end of the SpringBoot website converts Word or other Office files into pdf and then converts them into pictures on a page-by-page basis for display on the front end (linux)
[2] [Back-end learning] Springboot back-end convert ppt file to pdf

Guess you like

Origin blog.csdn.net/Kandy0125/article/details/121251458