1.1集成Mybatis-plus
1、 Meven引入引来
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
2、配置yml数据库配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/idea_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&servetTimeZone=Asia/Shanghai
username: root
password: root
3、创建表的实体类 创建pojo包 里面创建对应的实体类
@NoArgsConstructor
@AllArgsConstructor
@Data
@TableName("`user`")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String password;
private String nikname;
private String email;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@Version
private Integer version;
}
4、创建对应的实体类Mapper 新建mapper包
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
5、相关使用
@Autowired
private UserMapper userMapper;
@Test
void contextLoads()
{
User user = new User();
user.setName("D123");
userMapper.insert(user);
}
6、乐观锁跟分页插件的使用
6.1引入相关的配置 新建config包里面新建类MybatisPlusConfig
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); //乐观锁配置
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页配置
return interceptor;
}
}
6.2乐观锁在实体类上加上注解@Version
@Version
private Integer version;
6.3分页插件的使用
Page<User> userPage = new Page<>();
userPage.setCurrent(2);//设置当前页数
userPage.setSize(3); //设置多少条数据
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
List<User> users = userMapper.selectList(userPage, wrapper);
7、自动注入时间
1、数据库创建字段 create_time、update_time 设置为datetime类型
2、实体类加注解
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE,update ="now()")
private LocalDateTime updateTime;
3、自定义实现类 MyMetaObjectHandler 创建新的handlers包
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
}
}
2、接口数据校验相关
2.1数据校验 validation
1、引入数据校验依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.2.2</version>
</dependency>
2、接口上添加相关正则表达式 @Pattern(regexp = “^\S{5,16}$”) 类上加@Validated注解
@Validated
@PostMapping("/login")
private Result Login(@Pattern(regexp = "^\\S{5,16}$") String name, @Pattern(regexp = "^\\S{5,16}$")String password)
{
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name",name);
User user = userMapper.selectOne(wrapper);
if (user==null)
{
return Result.fail("当前用户名不存在");
}else
{
if (user.getPassword().equals(MD5Util.getMD5(password)))
{
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("id",user.getId());
hashMap.put("name",user.getName());
String token = JWTUtils.getToken(hashMap);
return Result.success(token);
}
return Result.fail("密码错误");
}
}
3、JWT 令牌
3.1引入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
3.2 创建工具类
public class JWTUtils {
private static String KEN = "JokerDJToken";
public static String getToken(Map<String,Object> claims){
return JWT.create()
.withClaim("claims",claims)
.withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12))
.sign(Algorithm.HMAC256(KEN));
}
public static Map<String,Object> parseToken(String token)
{
return JWT.require(Algorithm.HMAC256(KEN))
.build()
.verify(token)
.getClaim("claims")
.asMap();
}
}
3.3创建拦截器
1、在interceptors包里创建LoginInterceptor类
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token=request.getHeader("Authorization");
try {
Map<String, Object> stringObjectMap = JWTUtils.parseToken(token);
return true;
} catch (Exception e)
{
response.setStatus(401);
return false;
}
}
}
2、在config包里创建WebConfig类
@Configuration
public class WebConfig implements WebMvcConfigurer
{
@Autowired
private LoginInterceptor loginInterceptor;
public void addInterceptors(InterceptorRegistry registry)
{ registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register"); //白名单
}
}
3.4全局异常处理器
1、在exception包里创建 GlobalExceptionHandler类
@RestControllerAdvice
public class GlobalExceptionHandler
{
@ExceptionHandler(Exception.class)
public Result handleException(Exception e)
{
return Result.fail(StringUtils.hasLength(e.getMessage())?e.getMessage():"操作失败");
}
}
4、MD5加密工具类
1、没加盐
public class MD5Util {
private static final char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static String getMD5(String inStr) {
byte[] inStrBytes = inStr.getBytes();
try {
MessageDigest MD = MessageDigest.getInstance("MD5");
MD.update(inStrBytes);
byte[] mdByte = MD.digest();
char[] str = new char[mdByte.length * 2];
int k = 0;
for (byte temp : mdByte) {
str[k++] = hexDigits[temp >>> 4 & 15];
str[k++] = hexDigits[temp & 15];
}
return new String(str);
} catch (NoSuchAlgorithmException var8) {
var8.printStackTrace();
return null;
}
}
}
5、Result统一接头返回类
@Builder
@Data
public class Result<T> {
private int code;
private String message;
private T data;
/**
* 成功,只能是0
*/
private static final int SUCCESS_CODE = 0;
public static final String SUCCESS_MESSAGE = "操作成功";
/**
* 失败
*/
public static final int FAIL_CODE = 1;
public static final String FAIL_MESSAGE = "操作失败";
public static <T> Result<T> success(T data) {
return new Result<>(SUCCESS_CODE, SUCCESS_MESSAGE, data);
}
public static <T> Result<T> success(String message, T data) {
return new Result<>(SUCCESS_CODE, message, data);
}
public static <T> Result<T> fail() {
return new Result<>(FAIL_CODE, FAIL_MESSAGE, null);
}
public static <T> Result<T> fail(String message) {
return new Result<>(FAIL_CODE, message, null);
}
public static <T> Result<T> fail(int code, String message) {
return new Result<>(code, message, null);
}
private Result(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
}
6、登陆类
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController
{
@Autowired
private UserMapper userMapper;
@Validated
@PostMapping("/register")
private Result Register(@Pattern(regexp = "^\\S{5,16}$") String name, @Pattern(regexp = "^\\S{5,16}$")String password)
{
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name",name);
List<User> users = userMapper.selectList(wrapper);
if (!users.isEmpty())
{
return Result.fail("当前用户名存在");
}else
{
User user = new User();
user.setName(name);
user.setPassword(MD5Util.getMD5(password));
userMapper.insert(user);
return Result.success("注册成功");
}
}
@Validated
@PostMapping("/login")
private Result Login(@Pattern(regexp = "^\\S{5,16}$") String name, @Pattern(regexp = "^\\S{5,16}$")String password)
{
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name",name);
User user = userMapper.selectOne(wrapper);
if (user==null)
{
return Result.fail("当前用户名不存在");
}else
{
if (user.getPassword().equals(MD5Util.getMD5(password)))
{
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("id",user.getId());
hashMap.put("name",user.getName());
String token = JWTUtils.getToken(hashMap);
return Result.success(token);
}
return Result.fail("密码错误");
}
}
}