第一步导坐标
<!--mybatis-plus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!--mybatis-plus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
关于代码生成器,如果项目小做学习没怎么用过MP还是建议手敲,项目大建实体麻烦还得有生成器偷懒。
maven更新记得按等下载依赖。
第二步分页拦截器
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//定义Mp拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//添加分页拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
建议包树-utils-config-MpConfig.java
第三步编写实体类
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.GeneratedValue;
@Data
@EqualsAndHashCode(callSuper = false)
public class MpEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("uuid")
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "org.hibernate.id.UUIDGenerator")
private String uuid;
private String property;
private Boolean property1;
private String property2;
@TableField(fill = FieldFill.INSERT)
private String createUser;
@TableField(fill = FieldFill.INSERT)
private Date createDate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateDate;
}
@TableId("uuid")
绑定主键属性,没写这个调用BaseMapper的方法会报错,主键找不到
getById等方法,出现select * FROM table WHERE null = ?
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "org.hibernate.id.UUIDGenerator")
这两东西自定义的,系统框架迭代,用了uuid生成算法,懒得扒出来了,也没用,建议直接用MP的雪花就可以了
@TableId(value = "uuid",type = IdType.ASSIGN_ID)
从源码中可以看到,共有如下几种生成策略:
- AUTO:id自增
- NONE: 不设置id生成策略
- INPUT:用户手工输入id
第四步自定义填充字段
自定义填充字段涉及修改人和创建人字段,开发测试的时候记得先别弄不然Swagger没用,或者用postman做登录操作再测试
import cn.frame.security.CustomerUserDetail;
import cn.frame.toolbox.security.SpringSecurityUtils;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Calendar;
@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
Calendar calendar = Calendar.getInstance();
metaObject.setValue("createDate", calendar.getTime());
metaObject.setValue("updateDate",calendar.getTime());
不能直接通过request获得ID,通过线程方式获得ID
CustomerUserDetail user = SpringSecurityUtils.getCurrentUser();
metaObject.setValue("createUser", user.getUuid());
metaObject.setValue("updateUser",user.getUuid());
}
@Override
public void updateFill(MetaObject metaObject) {
Calendar calendar = Calendar.getInstance();
CustomerUserDetail user = SpringSecurityUtils.getCurrentUser();
metaObject.setValue("updateDate",calendar.getTime());
metaObject.setValue("updateUser",user.getUuid());
}
}
系统用到Security框架,封装utils类
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import cn.frame.security.CustomerUserDetail;
import java.util.ArrayList;
import java.util.Collection;
public class SpringSecurityUtils {
@SuppressWarnings("unchecked")
public static <T extends User> T getCurrentUser() {
Authentication authentication = getAuthentication();
if (authentication == null) {
return null;
}
Object principal = authentication.getPrincipal();
if (!(principal instanceof User)) {
return null;
}
return (T) principal;
}
/**
* 取得当前用户的用户名, 如果当前用户未登录则返回空字符串.
*/
public static String getCurrentUserUuid() {
Authentication authentication = getAuthentication();
if (authentication == null || authentication.getPrincipal() == null) {
return "";
}
if ("anonymousUser".equals(authentication.getName())) {
return authentication.getName();
}
return ((CustomerUserDetail) authentication.getPrincipal()).getUuid();
}
/**
* 取得当前用户的用户名, 如果当前用户未登录则返回空字符串.
*/
public static String getCurrentUserName() {
Authentication authentication = getAuthentication();
if (authentication == null || authentication.getPrincipal() == null) {
return "";
}
if ("anonymousUser".equals(authentication.getName())) {
return authentication.getName();
}
return ((CustomerUserDetail) authentication.getPrincipal()).getName();
}
/**
* 取得当前用户的登录名, 如果当前用户未登录则返回空字符串.
*/
public static String getCurrentLoginName() {
Authentication authentication = getAuthentication();
if (authentication == null || authentication.getPrincipal() == null) {
return "";
}
if ("anonymousUser".equals(authentication.getName())) {
return authentication.getName();
}
return ((CustomerUserDetail) authentication.getPrincipal()).getUsername();
}
/**
* 取得当前用户登录IP, 如果当前用户未登录则返回空字符串.
*/
public static String getCurrentUserIp() {
Authentication authentication = getAuthentication();
if (authentication == null) {
return "";
}
Object details = authentication.getDetails();
if (!(details instanceof WebAuthenticationDetails)) {
return "";
}
WebAuthenticationDetails webDetails = (WebAuthenticationDetails) details;
return webDetails.getRemoteAddress();
}
/**
* 判断用户是否拥有角色, 如果用户拥有参数中的任意一个角色则返回true.
*/
public static boolean hasAnyRole(String... roles) {
Authentication authentication = getAuthentication();
if (authentication == null) {
return false;
}
Collection<? extends GrantedAuthority> grantedAuthorityList = authentication.getAuthorities();
for (String role : roles) {
for (GrantedAuthority authority : grantedAuthorityList) {
if (role.equals(authority.getAuthority())) {
return true;
}
}
}
return false;
}
/**
* 取得Authentication, 如当前SecurityContext为空时返回null.
*/
public static Authentication getAuthentication() {
SecurityContext context = SecurityContextHolder.getContext();
if (context == null) {
return null;
}
return context.getAuthentication();
}
/**
* 如何描述该方法
*
* @return
*/
public static Collection<SimpleGrantedAuthority> getCurrentUserAuthorities() {
Collection<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<SimpleGrantedAuthority>(0);
UserDetails user = SpringSecurityUtils.getCurrentUser();
if (user != null) {
for (GrantedAuthority authority : user.getAuthorities()) {
grantedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
}
}
return grantedAuthorities;
}
}
import org.springframework.security.core.GrantedAuthority;
import cn.frame.entity.core.Dept;
import cn.frame.entity.core.Job;
import cn.frame.entity.core.User;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
*
* 自定义 CustomerUserDetail
*/
public class CustomerUserDetail extends org.springframework.security.core.userdetails.User {
private static final long serialVersionUID = 1L;
private String uuid;
private String name;
private User user;
private Dept dept;
private List<Job> jobs;
private Set<String> roleCodes;
private String gridId;
public CustomerUserDetail(String username, String password,
Collection<? extends GrantedAuthority> authorities, String name,
String uuid, Dept dept, User user, List<Job> jobs, Set<String> roleCodes, String gridId) {
super(username, password, authorities);
this.uuid = uuid;
this.name = name;
this.dept = dept;
this.user = user;
this.jobs = jobs;
this.roleCodes = roleCodes;
this.gridId = gridId;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Job> getJobs() {
return jobs;
}
public void setJobs(List<Job> jobs) {
this.jobs = jobs;
}
public Set<String> getRoleCodes() {
return roleCodes;
}
public void setRoleCodes(Set<String> roleCodes) {
this.roleCodes = roleCodes;
}
public String getGridId() {
return gridId;
}
public void setGridId(String gridId) {
this.gridId = gridId;
}
}
没用 Security就看看你的uer信息放哪里了,放到线程里面就好
/**
* 基于ThreedLocal封装工具类,用户保存和获取当前登录用户ID
* 作用域为单线程内
*/
public class BaseContext {
private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setThreadLocal(Long id){
threadLocal.set(id);
}
public static Long getCurrentId(){
return threadLocal.get();
}
}
简单框架的身份过滤器
import com.alibaba.fastjson.JSON;
import com.common.BaseContext;
import com.MpT.common.R;//返回对象
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 检查用户是否登录
* 自定义过滤器
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestURI = request.getRequestURI();
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
"/user/login",
"/user/sendMsg"
};
boolean check = check(urls, requestURI);
if (check){
filterChain.doFilter(request,response);//放行
return;
}
if (request.getSession().getAttribute("employee") != null){
// 线程进入截取ID保存到threadLocal空间中(set)传递至公共字段类(get)(自定义元数据对象处理器)
Long empId = (Long) request.getSession().getAttribute("employee");
BaseContext.setThreadLocal(empId);
filterChain.doFilter(request,response);//放行
return;
}
if (request.getSession().getAttribute("user") != null){
// 线程进入截取ID保存到threadLocal空间中(set)传递至公共字段类(get)(自定义元数据对象处理器)
Long userId = (Long) request.getSession().getAttribute("user");
BaseContext.setThreadLocal(userId);
filterChain.doFilter(request,response);//放行
return;
}
// 通过输出流向客户端页面响应数据,前端拦截器进行页面跳转
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url,requestURI);
if (match){
return true;
}
}
return false;
}
}
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.MpT.common.R;//返回对象
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
String password = employee.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());
// 条件查询构造器LambdaQueryWrapper
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);
// 数据库表设计Username为唯一约束,通过getone获取唯一数据封装成对象 设计表-->索引unique
if (emp == null) {
return R.error("登录失败");
}
if (!emp.getPassword().equals(password)){
return R.error("登录失败");
}
if (emp.getStatus() == 0){
return R.error("账号已禁用");
}
request.getSession().setAttribute("employee",emp.getId());
// Session浏览器缓存区
return R.success(emp);
}
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
request.getSession().removeAttribute("employee");
// 清除缓存
return R.success("退出成功!");
}
}
这部分稍微有点多了,但是还是很有参考价值,逻辑也很简单首先明白你是如何获取到登录用户的信息,讲用户唯一标识id存到线程中传递就可以,一定要用线程传递!!!仔细将代码看看,用了Security就直接放到内存区get就可以
第五步controller层编写
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 前端控制器
*
*/
@RestController
@RequestMapping("/MpEntity")
public class MpEntityController {
@GetMapping(value = "/{uuid}")
public R getById(@PathVariable String uuid){
return R.data(mpEntityService.getByIdForMpEntity(uuid));
}
@GetMapping("/page")
public R<PageResult> page(MpEntityPageQueryDTO mpEntityPageQueryDTO){
return R.data(mpEntityService.pageQuery(MpEntityPageQueryDTO));
}
@PostMapping("/save")
public R save(@RequestBody MpEntity mpEntity){
return mpEntityService.saveForMpEntity(mpEntity);
}
@PostMapping("/update")
private R update(@RequestBody MpEntity mpEntity){
return mpEntityService.updateForMpEntity(mpEntity);
}
@DeleteMapping("/{uuid}")
public R deleteById(@PathVariable String uuid){
return mpEntityService.removeByIdFormpEntity(uuid);
}
}
建议使用RESTful风格写接口,@RequestBody接的是json数据,@PathVariable接的是路径参数
不带的话接的是表单数据
第六步mapper层编写
import com.fjzxdz.ams.module.emergency.riskSource.entity.RiskMaterial;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper 接口
*/
@Mapper
public interface MpEntityMapper extends BaseMapper<MpEntity> {
}
这边是简单继承BaseMapper,单表的增删改查够用了,多联级表则开发自己的方法,涉及多种注解,或者xml编写。
第七步service层编写
import com.ams.module.emergency.result.PageResult;
import com.ams.module.emergency.result.R;
import com.ams.module.emergency.riskSource.dto.MpEntityPageQueryDTO;
import com.ams.module.emergency.riskSource.entity.MpEntity;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 服务类
*/
public interface MpEntityService extends IService<MpEntity> {
PageResult pageQuery(MpEntityPageQueryDTO mpEntityPageQueryDTO);
MpEntity getByIdForMpEntity(String uuid);
R saveForMpEntity(MpEntity mpEntity);
R updateForMpEntity(MpEntity mpEntity);
R removeByIdForMpEntity(String id);
}
第八步ServiceImpl实现
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ams.module.emergency.result.PageResult;
import com.ams.module.emergency.result.R;
import com.ams.module.emergency.riskSource.dto.MpEntityPageQueryDTO;
import com.ams.module.emergency.riskSource.entity.MpEntity;
import com.ams.module.emergency.riskSource.mapper.MpEntityMapper;
import com.ams.module.emergency.riskSource.service.MpEntityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 服务实现类
*/
@Service
public class MpEntityServiceImpl extends ServiceImpl<MpEntityMapper, MpEntity> implements MpEntityService {
@Autowired
private MpEntityService MpEntityService;
/**
* 分页查询
*/
@Override
public PageResult pageQuery(MpEntityPageQueryDTO mpEntityPageQueryDTO) {
Page pageInfo = new Page(MpEntityPageQueryDTO.getCurrent(), mpEntityPageQueryDTO.getSize());
LambdaQueryWrapper<MpEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.orderByDesc(MpEntity::getCreateDate);
mpEntityService.page(pageInfo, lambdaQueryWrapper);
PageResult pageResult = new PageResult(pageInfo.getTotal(),pageInfo.getRecords());
return pageResult;
}
/**
* 根据uuid查物资数据
*/
@Override
public MpEntity getByIdForMpEntity(String uuid) {
return mpEntityService.getById(uuid);
}
/**
* 保存
*/
@Override
public R saveForMpEntity(MpEntity mpEntity) {
try {
MpEntityService.save(mpEntity);
return R.success();
}catch (Exception e){
return R.fail();
}
}
/**
* 修改
*/
@Override
public R updateForMpEntity(MpEntity mpEntity) {
try {
mpEntityService.saveOrUpdate(mpEntity);
return R.success();
}catch (Exception e){
return R.fail();
}
}
/**
* 根据uuid删除
*/
@Override
public R removeByIdForMpEntity(String id) {
try {
mpEntityService.removeById(id);
return R.success();
}catch (Exception e){
return R.fail();
}
}
}