• Spring boot+Mybatisplus用AR模式实现逻辑删除操作


    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进行更新

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

    好了,完成

  • 相关阅读:
    Bzoj 3173: [Tjoi2013]最长上升子序列 平衡树,Treap,二分,树的序遍历
    Bzoj 1657: [Usaco2006 Mar]Mooo 奶牛的歌声 单调栈
    Bzoj 1391: [Ceoi2008]order 网络流,最大权闭合图
    Bzoj 1674: [Usaco2005]Part Acquisition dijkstra,堆
    Bzoj 3110: [Zjoi2013]K大数查询 树套树
    Cogs 309. [USACO 3.2] 香甜的黄油 dijkstra,堆,最短路,floyd
    面试题24:二叉排序树的后序遍历序列
    面试题23:从上往下打印二叉树
    面试题22:栈的压入、弹出序列
    面试题21:包含min函数的栈
  • 原文地址:https://www.cnblogs.com/andrew3/p/13166154.html
Copyright © 2020-2023  润新知