Mybatisplus的AR模式

Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索,仅仅需要让实体类继承 Model 类且实现主键指定方法,即可开启 AR 之旅。
逻辑删除

逻辑删除的本质是修改操作,所谓的逻辑删除其实并不是真正的删除,而是在表中将对应的是否删除标识(is_delete)或者说是状态字段(status)做修改操作。比如0是未删除,1是删除。在逻辑上数据是被删除的,但数据本身依然存在库中。
对应的SQL语句:update 表名 set is_delete = 1 where id = 1;语句表示,在该表中将id为1的信息进行逻辑删除,那么客户端进行查询id为1的信息,服务器就不会提供信息。倘若想继续为客户端提供该信息,可将 is_delete 更改为 0 。

一般商城网站,要分析客户的数据等,都会大量使用逻辑删除,所以,这肯定是要掌握了,下面,直接上代码:

entity

@Data
//对应数据库的表名
@TableName("tbl_item")
//继承Model类,开始AR模式
public class Items extends Model<Items>{
// 主键自增
@TableId(type = IdType.AUTO)
private Integer id;
private String picture;
private String name;
private Double price;
//指定逻辑字段,1表示逻辑删除状态,0表示逻辑未删除
@TableLogic
private Integer logic;
}

mapper

@Repository
public interface ItemsMapper extends BaseMapper<Items> {
}

service

@Service
public class ItemsService extends ServiceImpl<ItemsMapper,Items> {
@Resource
private ItemsMapper itemsMapper;
public void delete(String id){
itemsMapper.deleteById(id);
System.out.println("逻辑删除单个商品成功!");
} public void remove(String ids) {
if (ids!=null && !ids.equals("")){
String[] idArray=ids.split(",");
itemsMapper.deleteBatchIds(Arrays.asList(idArray));
System.out.println("逻辑批量删除商品成功!");
}
}
}

controller

@Controller
@RequestMapping("/items")
public class ItemsController {
@Resource
private ItemsService itemsService;
//显示商品列表信息
@RequestMapping("/list")
public String list(Model model){
List<Items> items = itemsService.list();
model.addAttribute("items",items);
return "item";
}
//单个删除
@ResponseBody
@RequestMapping("/delete")
public String delete(String id){
if(id!=null && !id.equals("")){
itemsService.delete(id);
}
return "success";
}
//批量删除
@ResponseBody
@RequestMapping("/remove")
public String remove(String ids){
itemsService.remove(ids);
return "success";
}
}

只有一个页面是用来展示商品信息的

item.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品列表</title>
<!--<link rel="shortcut icon" href="/shopping/image/favicon.ico">-->
<link rel="stylesheet" href="/shopping/css/style.css" th:href="@{/css/style.css}">
<script src="/shopping/js/jquery-3.4.1.min.js" th:src="@{/js/jquery-3.4.1.min.js}"></script>
<script src="/shopping/js/script.js" th:src="@{/js/script.js}"></script>
<link rel="icon" th:href="@{/image/favicon.ico}" type="image/x-icon"/>
<script th:inline="javascript">
var contextPath = [[${#request.getContextPath()}]];
</script>
</head>
<body>
<table>
<caption>商品列表</caption>
<tr>
<th><input type="checkbox" id="cb" th:onclick="|toggle()|"></th>
<th>编号</th>
<th>图片</th>
<th>名称</th>
<th>单价</th>
<th>操作</th>
</tr>
<tr class="itemList" th:each="item,iter:${items}">
<td>
<input type="checkbox" class="orderList" th:name="cks" th:value="${item.id}">
</td>
<td th:text="${iter.index}+1"></td>
<td><a href="/logic/image/${cart.picture}" th:href="@{'/image/'+${item.picture}}" target="_blank"> <img
src="/logic/image/${cart.picture}" th:src="@{'/image/'+${item.picture}}"></a>
</td>
<td th:text="${item.name}"></td>
<td th:text="${item.price}"></td>
<td>
<input type='button' value='删除' class='delBtn' th:onclick="|removeCartItem(${item.id})|">
</td>
</tr>
<tr class="itemList">
<!-- 合并单元格 -->
<th colspan="6"><input type="button" value="删除选中" class='reBtn' th:onclick="|deleteItems()|">
</th>
</tr>
</table>
</body>
</html>

其中,有一个js文件

script.js

//删除单个商品
function removeCartItem(id){
// alert(id);
var r=confirm("确定要删除该商品吗?");
//提交到后台进行异步逻辑删除
if(r){
$.ajax({
url:contextPath+'/items/delete',
data:{'id':id},
method:'post',
success:function (data) {
if (data=='success'){
window.location.href=contextPath+'/items/list';
}
}
})
}
} //批量删除商品
function deleteItems() {
// var r=confirm("确定删除这些商品吗?");
// if(r){
// alert(ids);
// }
//判断是否选择了商品
var count=0;
//存储选中的商品id
var ids='';
var cks=document.getElementsByName("cks");
for (var i=0;i<cks.length;i++){
if (cks[i].checked){
count++;
ids+=cks[i].value+',';
}
}
if (count==0 || count==undefined){
alert("请先选择商品,再进行删除!");
}
else{
var r=confirm("确定删除这些商品吗?");
if(r){
// alert(ids.substring(0,ids.length-1));
$.ajax({
url:contextPath+'/items/remove',
data:{'ids':ids.substring(0,ids.length-1)},
method:'post',
success:function (data) {
if (data=='success'){
window.location.href=contextPath+'/items/list';
}
}
})
}
}
}
//页面加载完毕事件
$(function () {
//给所有图片添加鼠标悬浮事件
$("img").hover(function () {
$(this).css("width","150px").css("height","150px");
},function () {
$(this).css("width","100px").css("height","100px");
});
//获取所有的行,添加鼠标悬停事件
$(".itemList").hover(function () {
$(this).css("backgroundColor", "aliceblue");
},function () {
$(this).css("backgroundColor", "white");
});
//给单个删除按钮添加鼠标悬浮事件
$(".delBtn").hover(function () {
$(this).css("backgroundColor","green");
},function () {
//鼠标移开时背景是绿色
$(this).css("backgroundColor","red");
});
//给批量删除按钮添加悬浮事件
$(".reBtn").hover(function () {
$(this).css("backgroundColor","red");
},function () {
//鼠标移开时背景是绿色
$(this).css("backgroundColor","green");
});
});
//全选和反选,保证每个商品的复选框状态和最顶部的复选框状态一致即可
function toggle() {
if ($("#cb").is(":checked")) {
$(".orderList").each(function(){
$(this).get(0).checked=true;//全选
})
} else {
$(".orderList").each(function () {
$(this).get(0).checked=false;//反选
})
}
}

spring配置文件

application.yml

#服务器配置
server:
port: 8888
servlet:
context-path: /logic
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/shopping?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong
username: root
password: 数据库密码
driver-class-name: com.mysql.cj.jdbc.Driver
mvc:
static-path-pattern: /**
#Mybatisplus配置
mybatis-plus:
type-aliases-package: com.wxb.logicdelete.entity #实体类包扫描
global-config:
db-config:
# logic-delete-field: flag #全局逻辑删除字段值 3.3.0开始支持,详情看下面。
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

对了,在项目启动类中还要配置mapper包扫描

package com.wxb.logicdelete;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan("com.wxb.logicdelete.mapper")
public class LogicDeleteApplication { public static void main(String[] args) {
SpringApplication.run(LogicDeleteApplication.class, args);
} }

数据库表设计

然后,启动项目,访问,最开始应该是这样的页面

然后可以点击删除或删除选中按钮进行逻辑删除了,比如:我先删除一个iphone11之后页面就没有了

但是数据库表中实质是更新操作,并没有删除记录,而是把逻辑字段logic的值更新为1了

然后也可以根据复选框选中的进行批量的逻辑删除,比如,我就删掉索尼X8000G和EPSON投影仪

数据库也是批量根据id进行更新

进行了两次删除之后,后台也打印了两条日志

好了,完成

Spring boot+Mybatisplus用AR模式实现逻辑删除操作的更多相关文章

  1. Spring Boot Mybatis-Plus

    Mybatis-Plus 是对 Mybatis-Plus 的一些扩充. 在 Spring Boot 中进行集成的时候其实基本上和 mybatis 是一致的. 在你的配置文件中.配置 你的 entity ...

  2. Spring Boot切换为APR模式

    Spring Boot内置了tomcat容器,直接运行Application就可以启动web服务器. 在tomcat中提供了三种方式:BIO.NIO.APR. BIO tomcat7以下的版本都是BI ...

  3. Spring Boot+RabbitMQ 通过fanout模式实现消息接收(支持消费者多实例部署)

    本文章适用的场景:同一条消息可以被多个消费者同时消费.注意:当消费者多实例部署时,会轮询消费消息.网上有大量的的案例展示:P生产一条消息,消费者服务C中建立Q1和Q2两个队列共同消费.但极少的材料展示 ...

  4. Spring Boot整合Mybatis完成级联一对多CRUD操作

    在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...

  5. 【ELK】4.spring boot 2.X集成ES spring-data-ES 进行CRUD操作 完整版+kibana管理ES的index操作

    spring boot 2.X集成ES 进行CRUD操作  完整版 内容包括: ============================================================ ...

  6. spring boot容器加载完后执行特定操作

    有时候我们需要在spring boot容器启动并加载完后,开一些线程或者一些程序来干某些事情.这时候我们需要配置ContextRefreshedEvent事件来实现我们要做的事情 1.Applicat ...

  7. 《Spring Boot 实战纪实》缺失的逻辑

    目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...

  8. spring boot 单元测试 --- 在测试类使用 javabean注解操作接口

    1.依赖包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  9. 【转】Spring,Spring MVC及Spring Boot区别

    对于一个Java开发者来说,Spring可谓如雷贯耳,无论是Spring框架,还是Spring引领的IOC,AOP风格,都对后续Java开发产生的深远的影响,同时,Spring社区总能及时响应开发者的 ...

随机推荐

  1. 破解webstorm 亲测有效

    一.首先安装好webstorm,并且配置hosts文件 二.使用以下激活码进行激活,亲测有效可以用到2099年 4RULSIH54N-eyJsaWNlbnNlSWQiOiI0UlVMU0lINTROI ...

  2. EF用导航熟悉遍历从表时,删除主表出错

    var entitys= Repository.Table.Where(a => ids.Contains(a.UUID)).ToList(); entitys.ForEach(a => ...

  3. [JavaWeb基础] 018.Struts2 Action通配符使用

    Struts2中有一个很牛逼的action通配符,可以用来简化action配置,以我们将要讲解的案例来说,如果我们要对一个学生信息进行增加,删除,修改,那么按照原来的做法,我们需要写3个Action来 ...

  4. 删除节点与插入节点 & innerHTML

    1.测试removeChild()方法: 删除节点dom9.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" &q ...

  5. require.js与IDEA的配合

    本文主要讲述在html中使用requirejs时,如何让IDEA更加智能识别javascript的方法. 测试时的目录结构,一种典型的 thinkphp 的结构,同时,在 a.thml 中通过 req ...

  6. ElementUi 全选功能实现

    每次使用官方的示例都会被坑一下(可能是我的理解不够透彻吧,不记录一下保不准下次依旧会忘), 故此今天做个Demo 记录一下.本次仍然使用官网给出的示例,只做理解性的说明. 1.此处先给出官方示例代码: ...

  7. mybatis精讲(七)--动态sql

    目录 常用标签 if元素 choose元素 trim元素 forearch bind元素 在我们传统的开发中我们会通过拼接sql达到数据库的操作.java中的拼接不仅效率低下而且代码很长不易维护.而M ...

  8. Rocket - tilelink - SourceShrinker

    https://mp.weixin.qq.com/s/1vyfhZuF4RyRE5Qjj6AGWA   简单介绍SourceShrinker的实现.   ​​   1. 基本介绍   用于把上游节点的 ...

  9. Redis 入门到分布式 (六)常见的持久化开发运维问题

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.常见问题目录 fork操作 进程外开销 AOF追加阻塞 单机多实例部署 二. fork 1.Fork ...

  10. Java实现蓝桥杯 历届试题 合根植物

    问题描述 w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列).每个格子里种了一株合根植物. 这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成 ...