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{ // 主键自增 @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{ }
service
@Service public class ItemsService extends ServiceImpl{ @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){ Listitems = 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="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){ 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进行更新
进行了两次删除之后,后台也打印了两条日志
好了,完成