创建一个拦截器LogicDeleteInterceptor
@Intercepts(
@Signature(type= StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})
)
@Component
public class LogicDeleteInterceptor implements Interceptor, HandlerInterceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
//invocation获取原始对象
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//获取旧有得sql语句
BoundSql boundSql = statementHandler.getBoundSql();
String oldSQL = boundSql.getSql();
String newSQL = oldSQL.replace("where 1=1","where 1=1 and is_deleted=0");
//用newSQL替换oldSQL
Field sql = boundSql.getClass().getDeclaredField("sql");
sql.setAccessible(true);
sql.set(boundSql,newSQL);
//调用原始对象执行原始方法且返回
return invocation.proceed();
}
}
在WebConfig中注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Autowired
private LogicDeleteInterceptor logicDeleteInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logicDeleteInterceptor);
//登录接口和注册接口不拦截
registry
.addInterceptor(loginInterceptor)
.excludePathPatterns("/user/login","/user/register");
}
}
sql语句写法
逻辑删除时,controller使用@DeleteMapping,在mapper层使用<update>标签
检查用户名是否被暂用
public boolean isUsernameAvailable(String username) {
// 检查数据库中是否存在该用户名,包括逻辑删除的用户
User user = userRepository.findByUsername(username);
if (user == null || user.isDeleted()) {
// 用户不存在或已被逻辑删除,用户名可用
return true;
} else {
// 用户存在且未被删除,用户名不可用
return false;
}
}
public User saveUser(User user) {
if (isUsernameAvailable(user.getUsername())) {
// 用户名可用,保存新用户
return userRepository.save(user);
} else {
// 用户名不可用,抛出异常或返回错误信息
throw new UsernameNotAvailableException("用户名已被占用");
}
}