1.创建一个Result类,包含返回的状态码,返回提示消息和数据结果
package com.dyzwj.zwjsharding.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Title: Result
* @Description: 接口返回集
* @Company: caixun
* @Author: zhengtonghui
* @Create: Date:2021年08月10日
*/
// 成功结果实体
@Data
public class Result implements Serializable {
private Integer code;
private String message;
private T data;
public void setResultCode(ResultCode resultCode) {
this.code = resultCode.code();
}
public static Result success() {
Result result = new Result();
result.setResultCode(ResultCode.SUCCESS);
return result;
}
public static Result success(T data) {
Result result = new Result();
result.setResultCode(ResultCode.SUCCESS);
result.setCode(ResultCode.SUCCESS.code());
result.setMessage(ResultCode.SUCCESS.message());
result.setData(data);
return result;
}
public static Result failure(Integer code, String message) {
Result result = new Result();
result.setCode(code);
result.setMessage(message);
return result;
}
}
2.创建结果状态码枚举类
package com.dyzwj.zwjsharding.entity;
/**
* @Title: ResultCode
* @Description: 接口状态码
* @Company: caixun
* @Author: ChenCanWen
* @Create: Date:2021年08月10日
*/
public enum ResultCode {
/*成功状态码*/
SUCCESS(1, "成功"),
SYSTEM_ERROR(400, "系统繁忙,请稍后重试"),
/*参数错误: 1001-1999 */
PARAM_IS_INVALID(1001, "参数无效"),
PARAM_IS_BLANK(1002, "参数为空"),
PARAM_TYPE_BIND_ERROR(1003, "参数类型错误"),
PARAM_NOT_COMPLETE(1004, "参数缺失"),
/*用户错误: 2001-2999*/
USER_NOT_LOGGED_IN(2001, "用户未登录,访问的路径需要验证,请登录"),
USER_LOGIN_ERROR(2002, "账号不存在或密码错误"),
USER_ACCOUNT_FORBIDDEN(2003, "账号已被禁用"),
USER_NOT_EXIST(2004, "用户不存在"),
USER_HAS_EXISTED(2005, "用户已存在");
private Integer code;
private String message;
ResultCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer code() {
return this.code;
}
public String message(){
return this.message;
}
}
3.错误结果集
package com.concom.domain;
import lombok.Data;
// 错误结果实体
@Data
public class ErrorResult {
private Integer code;
private String message;
public ErrorResult(Integer code, String message){
this.code = code;
this.message = message;
}
}
4.创建注解类
package com.dyzwj.zwjsharding.annotation;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface ResponseResult {
}
5.创建切面类
package com.dyzwj.zwjsharding.aop;
import com.dyzwj.zwjsharding.annotation.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Aspect
@Component
@Slf4j
public class ResponseResultAop {
private static final String RESPONSE_RESULT_ANNO = "RESPONSE_RESULT_ANNO";
//@Around("@within(com.dyzwj.zwjsharding.annotation.ResponseResult)")//这个切点表达式只作用在类上
@Around("@annotation(com.dyzwj.zwjsharding.annotation.ResponseResult)")//这个切点表达式的作用只用在方法上
public Object processAop(ProceedingJoinPoint joinPoint) {
Object result = null;
try {
log.info("开始切入");
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Class> clazz = joinPoint.getTarget().getClass();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
if (clazz.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANNO, clazz.getAnnotation(ResponseResult.class));
}else if (method.isAnnotationPresent(ResponseResult.class)) {
request.setAttribute(RESPONSE_RESULT_ANNO, method.getAnnotation(ResponseResult.class));
}
result = joinPoint.proceed();
log.info("目标方法执行完成");
} catch (Throwable e) {
log.error("切面执行出错,原因是:{}", e);
}
return result;
}
}
6. 写一个类继承ResponseBodyAdvice重写supports()和beforeBodyWrire()方法,该类需要使用@RestControllerAdvice注解和@RestControllerAdvice注解,并将其放入IOC容器交给spring进行管理,这个类就是在将数据返回给DispathchServlet对视图进行渲渲染前对body进行重写,当supports方法返回true的时候,该方法才会去执行beforeBodyWrite()方法,对返回的body进行重写
package com.dyzwj.zwjsharding.handler;
import com.dyzwj.zwjsharding.annotation.ResponseResult;
import com.dyzwj.zwjsharding.entity.ErrorResult;
import com.dyzwj.zwjsharding.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;
@Component
@Slf4j
@RestControllerAdvice
public class ResponseResultAdvice implements ResponseBodyAdvice
7.控制器,用来发送请求,调用业务层获取数据,注意自定义注解是用在类上还是用在方法上,如果用在类上的话,则aop中的切点表达式使用的是@Around(@within("xxx.xx.class")),如果用在方法上则切点表达式为@Around(@annotation("xxxx.xxx.class"))
package com.dyzwj.zwjsharding.controller;
import com.dyzwj.zwjsharding.annotation.ResponseResult;
import com.dyzwj.zwjsharding.entity.User;
import com.dyzwj.zwjsharding.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@GetMapping(value = "/findAll")
@ResponseResult
public List findAll() {
return userService.findAll();
}
@GetMapping(value = "/findById/{id}")
public User listUserByID(@PathVariable("id") long id) {
return userService.findById(id);
}
@PostMapping(value = "/saveOrUpdate")
public boolean updateOrInsertUser(@RequestBody User user) {
if (user == null) {
log.info("参数不对:{}", user);
}
User user1 = userService.findById(user.getId());
if(user1!=null) {
return userService.updateUser(user);
}else{
return userService.saveUser(user);
}
}
@DeleteMapping(value = "/deleteUser/{id}")
public int deleteUser(@PathVariable("id")long id){
return userService.deleteUser(id);
}
@GetMapping(value = "/getAll")
public List getAll(){
return userService.list();
}
}
8.业务接口层
package com.dyzwj.zwjsharding.service;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dyzwj.zwjsharding.entity.User;
import com.dyzwj.zwjsharding.exception.CustomException;
import java.util.List;
public interface UserService extends IService {
List findAll();
User findById(long id) throws CustomException;
boolean updateUser(User user);
boolean saveUser(User user);
int deleteUser(long id);
}
9.业务实现类
package com.dyzwj.zwjsharding.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dyzwj.zwjsharding.entity.User;
import com.dyzwj.zwjsharding.exception.CustomException;
import com.dyzwj.zwjsharding.mapper.UserMapper;
import com.dyzwj.zwjsharding.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List findAll() {
return userMapper.selectAll();
}
@Override
public User findById(long id) throws CustomException{
if(id==0){
throw new CustomException("id不能为0");
}
return userMapper.findById(id);
}
@Override
public boolean updateUser(User user) {
return userMapper.updateUser(user);
}
@Override
public boolean saveUser(User user) {
return userMapper.saveUser(user);
}
@Override
public int deleteUser(long id) {
return userMapper.deleteById(id);
}
}
10.数据访问层
package com.dyzwj.zwjsharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dyzwj.zwjsharding.entity.User;
import org.apache.ibatis.annotations.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper extends BaseMapper {
@Insert("insert into t_user(nickname,password,age,sex,birthday) values(#{nickname},#{password},#{age},#{sex},#{birthday})")
int insert(User user);
@Delete("delete from t_user")
int delete();
@Select("select * from t_user")
List selectAll();
@Select("select * from t_user where id=#{id}")
User findById(long id);
@Update("update t_user set nickname=#{nickname},password=#{password},age=#{age},sex=#{sex},birthday=now() where id=#{id}")
boolean updateUser(User user);
@Insert("insert into t_user(nickname,password,age,sex,birthday) values(#{nickname},#{password},#{age},#{sex},#{birthday})")
boolean saveUser(User user);
}
11.访问结果 ,数据比较多,暂未截完整图
12.实体类
package com.dyzwj.zwjsharding.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
@Data
@TableName(value = "t_user")
public class User {
private long id;
private String nickname;
private String password;
private Integer age;
private Integer sex;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date birthday;
}
13.依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-aop
mysql
mysql-connector-java
com.alibaba
druid
1.2.8
com.alibaba
fastjson
1.2.78
com.baomidou
mybatis-plus-boot-starter
3.3.1.tmp
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
4.0.0-RC1
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-test
test
14.配置application.propertis文件
server:
port: 8089
spring:
application:
name: boot-student
datasource:
url: jdbc:mysql://localhost:3306/db3?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: west151211
mybatis-plus:
mapper-locations: classpath:/mapper/*Mapper.xml
type-aliases-package: com.concom.domain
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启SQL语句打印
15.SQL语句
CREATE TABLE `t_user` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`user_name` varchar(20) DEFAULT NULL,
`user_sex` varchar(6) DEFAULT NULL,
`user_age` int(10) DEFAULT NULL,
`user_telphone` varchar(11) DEFAULT NULL,
`login_time` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;