Springbootの基本文法と応用
次の分析とアプリケーションはすべて、フロントエンドとバックエンドが分離された Springboot 用です。
1. 各レベルの分析
いくつかのレベルに分かれています:
1.1 上下関係
参考資料:階層関係分析
1.2 階層的な役割
参照:階層
- エンティティレイヤー
同じタイプ: モデル層 = エンティティ層 = ドメイン層
機能: データベース内の属性値と基本的に一致するエンティティ クラスを保存するために使用されます。
- マッパーレイヤー
類似: マッパー層 = dao 層
機能: データベース上でデータ永続化操作を実行し、そのメソッド ステートメントはデータベース操作を直接目的としています。
- サービス層
同じタイプ: サービス層は 1 つだけ
機能: サービス層は、コントローラー層、つまりユーザーのコントローラーです。
サービスのimplはマッパーとサービスを統合したファイルです。
- コントローラ層
類似:コントローラー層 = Web層
機能:コントローラー、インポートサービス層、サービス中のメソッドを使用するため、コントローラーはフロントエンドから渡されたパラメータを受け取って業務を実行し、処理結果をフロントエンドに返します。
2. データベース: MyBatis
CRUD 構文:
<?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>
このうち、IDはMapperのIDと一致する必要があります。
2.1 ピットを踏む
2.1.1 クエリ結果が null または 0 である
データベースのフィールド名が下線付きの user_id に設定され、クエリ結果が 0、varchar 型に変更したクエリ結果が null となり、MyBatis の仕組みに問題があることが分かりました。resultMap を自分で設定するか、アンダースコアを削除してください。
参考:【MyBatisがピットを踏んだ】 SQLを正しく実行してコンソールに出力するが、値が[null] ==> 下線フィールド名
2.2 アプリケーション
2.2.1 記事レコードの参照クエリ
特定の要件:
ユーザーが閲覧した記事に関する情報をクエリします。
注:
ユーザーが前の瞬間にこの記事を閲覧し、次の瞬間にこの記事を再度閲覧した可能性がありますが、この記事は表に 1 回だけ表示され、最新の閲覧結果となります。
注: PageHelper ツールが使用されます。
クエリ文は次のとおりです。
<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>
参考:PageHelperの基本的な使い方
PageHelperを使用する文は以下のとおりです。
@Override
public List<Behavior> getBehaviorsByUserIDAndTypeByPage(int userID, int type, int pageNum,int pageSize){
PageHelper.startPage(pageNum, pageSize);
return behaviorMapper.getBehaviorsByUserIDAndType(userID, type);
}
3. 権利管理
非常に包括的:一目で理解できます。Springboot インターセプターに基づくフロントエンドとバックエンドの分離されたログイン インターセプト
3.1 インターセプターの作成
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 レジスタインターセプタ: Config クラス
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 クラスと serviceImpl クラス
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);
}
UserMapper の一部のクエリ操作が使用されます
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 コントローラークラス
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. ファイルのプレビュー
私の他のブログ投稿を参照してください:
[1] [バックエンド学習] SpringBoot Web サイトのバックエンドは、Word またはその他の Office ファイルを PDF に変換し、ページごとに画像に変換して表示します。フロントエンド (Linux)
[2] [バックエンド学習] Springboot バックエンドで ppt ファイルを pdf に変換する