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:
1.1 Hierarchical relationship
Reference: Hierarchical Relationship Analysis
1.2 Hierarchical role
See also: Hierarchy
- 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.
- 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
- 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.
- 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