首页 > 编程语言 >JavaWeb实战:基础CRUD+批量删除+分页+条件

JavaWeb实战:基础CRUD+批量删除+分页+条件

时间:2022-11-19 12:33:19浏览次数:74  
标签:resp JavaWeb 批量 int brand CRUD id import public

技术栈及相关参考资料:

目录

1、需求

  • 实现对品牌数据最基础的 CRUD 功能(文中仅演示了查询和添加)
  • 实现在所有数据页面对数据的批量删除功能
  • 实现分页展示功能
  • 实现条件查询功能

2、环境准备

2.1 工程准备

  • vue.js 和 element-ui 依赖

  • 引入 Axios.js 依赖

  • 包结构

  • Maven 依赖 pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>priv.dandelion</groupId>
      <artifactId>brand-case</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
      </properties>
    
      <dependencies>
        <!-- junit单元测试依赖 -->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
        <!--mybatis 依赖-->
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.5</version>
        </dependency>
        <!--mysql 驱动-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.46</version>
        </dependency>
        <!-- 添加slf4j日志api -->
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.20</version>
        </dependency>
        <!-- 添加logback-classic依赖 -->
        <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>1.2.3</version>
        </dependency>
        <!-- 添加logback-core依赖 -->
        <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-core</artifactId>
          <version>1.2.3</version>
        </dependency>
        <!-- servlet依赖 -->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
        </dependency>
        <!-- JSP依赖 -->
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.2</version>
          <scope>provided</scope>
        </dependency>
        <!-- JSTL依赖 -->
        <dependency>
          <groupId>jstl</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>
        <!-- JSTL标准标签库依赖 -->
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>standard</artifactId>
          <version>1.1.2</version>
        </dependency>
        <!-- JSON串和Java对象的相互转换 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.62</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <!-- tomcat插件 -->
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
          </plugin>
        </plugins>
      </build>
    </project>
    
  • MyBatis 核心配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--起别名-->
        <typeAliases>
            <package name="priv.dandelion.entity"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <!-- 采用JDBC的事务管理方式 -->
                <transactionManager type="JDBC"/>
                <!-- 数据库连接信息 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <!-- value的值一定不能换行,一定!一定!不能换行 -->
                    <property name="url" value="jdbc:mysql:///db1?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useServerPrepStmts=true"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <!-- 扫描mapper,加载SQL映射文件 -->
        <mappers>
            <package name="priv.dandelion.dao"/>
        </mappers>
    </configuration>
    
  • 创建 SqlSession 工厂工具类

    package priv.dandelion.utils;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class SqlSessionFactoryUtils {
    
        // 提升作用域,用于再方法内进行返回
        private static SqlSessionFactory sqlSessionFactory;
    
        // 静态代码块会随着类的加载自动执行且只执行一次
        static {
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }
    
        public static SqlSessionFactory getSqlSessionFactory() {
            return sqlSessionFactory;
        }
    }
    
  • 实体类 Brand.java

    package priv.dandelion.entity;
    
    public class Brand {
        // id 主键
        private Integer id;
        // 品牌名称
        private String brandName;
        // 企业名称
        private String companyName;
        // 排序字段
        private Integer ordered;
        // 描述信息
        private String description;
        // 状态:0:禁用  1:启用
        private Integer status;
    
        public Brand() {
        }
    
        public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
            this.id = id;
            this.brandName = brandName;
            this.companyName = companyName;
            this.ordered = ordered;
            this.description = description;
            this.status = status;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getBrandName() {
            return brandName;
        }
    
        public void setBrandName(String brandName) {
            this.brandName = brandName;
        }
    
        public String getCompanyName() {
            return companyName;
        }
    
        public void setCompanyName(String companyName) {
            this.companyName = companyName;
        }
    
        public Integer getOrdered() {
            return ordered;
        }
    
        public void setOrdered(Integer ordered) {
            this.ordered = ordered;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        @Override
        public String toString() {
            return "Brand{" +
                    "id=" + id +
                    ", brand_name='" + brandName + '\'' +
                    ", company_name='" + companyName + '\'' +
                    ", ordered=" + ordered +
                    ", description='" + description + '\'' +
                    ", status=" + status +
                    '}';
        }
    }
    
  • Mapper 映射文件和 Mapper 接口

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="priv.dandelion.dao.BrandMapper">
    
        <!-- 解决数据库与实体类命名不一致问题 -->
        <resultMap id="brandResultMap" type="brand">
            <result column="brand_name" property="brandName"></result>
            <result column="company_name" property="companyName"></result>
        </resultMap>
    
    </mapper>
    
  • 前端页面 brand.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .el-table .warning-row {
                background: oldlace;
            }
            .el-table .success-row {
                background: #f0f9eb;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <!--搜索表单-->
        <el-form :inline="true" :model="brand" class="demo-form-inline">
            <el-form-item label="当前状态">
                <el-select v-model="brand.status" placeholder="当前状态">
                    <el-option label="启用" value="1"></el-option>
                    <el-option label="禁用" value="0"></el-option>
                </el-select>
            </el-form-item>
    
            <el-form-item label="企业名称">
                <el-input v-model="brand.companyName" placeholder="企业名称"></el-input>
            </el-form-item>
    
            <el-form-item label="品牌名称">
                <el-input v-model="brand.brandName" placeholder="品牌名称"></el-input>
            </el-form-item>
    
            <el-form-item>
                <el-button type="primary" @click="onSubmit">查询</el-button>
            </el-form-item>
        </el-form>
    
        <!--按钮-->
        <!--
            @click="dialogVisible = true"
            单击时将dialogVisible设置为true,展示对话框
        -->
        <el-row>
            <el-button type="danger" plain>批量删除</el-button>
            <el-button type="primary" plain @click="dialogVisible = true">新增</el-button>
        </el-row>
    
        <!--添加数据对话框表单-->
        <el-dialog
                title="编辑品牌"
                :visible.sync="dialogVisible"
                width="30%">
            <el-form ref="form" :model="brand" label-width="80px">
                <el-form-item label="品牌名称">
                    <el-input v-model="brand.brandName"></el-input>
                </el-form-item>
    
                <el-form-item label="企业名称">
                    <el-input v-model="brand.companyName"></el-input>
                </el-form-item>
    
                <el-form-item label="排序">
                    <el-input v-model="brand.ordered"></el-input>
                </el-form-item>
    
                <el-form-item label="备注">
                    <el-input type="textarea" v-model="brand.description"></el-input>
                </el-form-item>
    
                <el-form-item label="状态">
                    <el-switch v-model="brand.status"
                               active-value="1"
                               inactive-value="0"
                    ></el-switch>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="addBrand">提交</el-button>
                    <el-button @click="dialogVisible = false">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    
        <!--表格-->
        <!--
    		其中<el-table-column></el-table-column>标签的prop属性值
    		需要和Vue核心对象返回tableData的对象属性名一致
    	-->
        <template>
            <!--
    			@selection-change="handleSelectionChange"
    			监听到复选框勾选时,获取行的记录
    			需要在Vue核心对象中实现handleSelectionChange函数
    		-->
            <el-table
                    :data="tableData"
                    style="width: 100%"
                    :row-class-name="tableRowClassName"
                    @selection-change="handleSelectionChange">
                <!--表格复选框-->
                <el-table-column
                        type="selection"
                        width="55">
                </el-table-column>
                <el-table-column
                        type="index"
                        width="50">
                </el-table-column>
                <el-table-column
                        prop="brandName"
                        label="品牌名称"
                        align="center">
                </el-table-column>
                <el-table-column
                        prop="companyName"
                        label="企业名称"
                        align="center">
                </el-table-column>
                <el-table-column
                        prop="ordered"
                        align="center"
                        label="排序">
                </el-table-column>
                <el-table-column
                        prop="status"
                        align="center"
                        label="当前状态">
                </el-table-column>
                <el-table-column
                        align="center"
                        label="操作">
                    <el-row>
                        <el-button type="primary">修改</el-button>
                        <el-button type="danger">删除</el-button>
                    </el-row>
                </el-table-column>
    
            </el-table>
        </template>
    
        <!--分页工具条-->
        <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="[5, 10, 15, 20]"
                :page-size="5"
                layout="total, sizes, prev, pager, next, jumper"
                :total="400">
        </el-pagination>
    
    </div>
    <script src="js/vue.js"></script>
    <script src="element-ui/lib/index.js"></script>
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <script>
        new Vue({
            el: "#app",
            methods: {
                tableRowClassName({row, rowIndex}) {
                    if (rowIndex === 1) {
                        return 'warning-row';
                    } else if (rowIndex === 3) {
                        return 'success-row';
                    }
                    return '';
                },
                // 复选框选中后执行的方法
                handleSelectionChange(val) {
                    this.multipleSelection = val;
    
                    console.log(this.multipleSelection)
                },
                // 查询方法
                onSubmit() {
                    console.log(this.brand);
                },
                // 添加数据
                addBrand(){
                    console.log(this.brand);
                },
                //分页
                handleSizeChange(val) {
                    console.log(`每页 ${val} 条`);
                },
                handleCurrentChange(val) {
                    console.log(`当前页: ${val}`);
                }
            },
            data() {
                return {
                    // 当前页码
                    currentPage: 4,
                    // 添加数据对话框是否展示的标记
                    dialogVisible: false,
    
                    // 品牌模型数据
                    brand: {
                        status: '',
                        brandName: '',
                        companyName: '',
                        id:"",
                        ordered:"",
                        description:""
                    },
                    // 复选框选中数据集合
                    multipleSelection: [],
                    // 表格数据
                    tableData: [{
                        brandName: '华为',
                        companyName: '华为科技有限公司',
                        ordered: '100',
                        status: "1"
                    }, {
                        brandName: '华为',
                        companyName: '华为科技有限公司',
                        ordered: '100',
                        status: "1"
                    }, {
                        brandName: '华为',
                        companyName: '华为科技有限公司',
                        ordered: '100',
                        status: "1"
                    }, {
                        brandName: '华为',
                        companyName: '华为科技有限公司',
                        ordered: '100',
                        status: "1"
                    }]
                }
            }
        })
    </script>
    </body>
    </html>
    

2.2 创建表

  • SQL脚本

    -- 删除tb_brand表
    drop table if exists tb_brand;
    -- 创建tb_brand表
    create table tb_brand
    (
        -- id 主键
        id           int primary key auto_increment,
        -- 品牌名称
        brand_name   varchar(20),
        -- 企业名称
        company_name varchar(20),
        -- 排序字段
        ordered      int,
        -- 描述信息
        description  varchar(100),
        -- 状态:0:禁用  1:启用
        status       int
    );
    -- 添加数据
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values 
           ('华为', '华为技术有限公司', 100, '万物互联', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
           ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
           ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
           ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
           ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
           ('华为', '华为技术有限公司', 100, '万物互联', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
           ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
           ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
           ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
           ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
           ('华为', '华为技术有限公司', 100, '万物互联', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
           ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
           ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
           ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
           ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
           ('华为', '华为技术有限公司', 100, '万物互联', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
           ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
           ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
           ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
           ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
           ('华为', '华为技术有限公司', 100, '万物互联', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
           ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
           ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
           ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
           ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
           ('华为', '华为技术有限公司', 100, '万物互联', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1),
           ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
           ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
           ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
           ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
           ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1)
            ;
       
    
    SELECT * FROM tb_brand;
    

3、查询所有功能

3.1 后端实现

3.1.1 Dao层方法实现

package priv.dandelion.dao;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Select;
import priv.dandelion.entity.Brand;

import java.util.List;


public interface BrandMapper {

    // 解决数据库与实体类明明不一致问题
    @ResultMap("brandResultMap")
    @Select("select * from tb_brand")
    List<Brand> selectAll();

}

3.1.2 Service层方法实现

  • 接口

    package priv.dandelion.service;
    
    import priv.dandelion.entity.Brand;
    
    import java.util.List;
    
    public interface BrandService {
        /**
         * 查询所有
         * @return
         */
        List<Brand> selectAll();
    }
    
  • 实现类

    package priv.dandelion.service.impl;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import priv.dandelion.dao.BrandMapper;
    import priv.dandelion.entity.Brand;
    import priv.dandelion.service.BrandService;
    import priv.dandelion.utils.SqlSessionFactoryUtils;
    
    import java.util.List;
    
    public class BrandServiceImpl implements BrandService {
    
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
    
        @Override
        public List<Brand> selectAll() {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
            List<Brand> brands = mapper.selectAll();
            sqlSession.close();
            return brands;
        }
    }
    

3.1.3 Servlet实现与Servlet优化

每个Servlet写一个类非常杂乱,不利于编写和管理

可以将其写到同一个类中,URL将更变为如http://localhost:8080/brand-case/brand/selectAll的形式

  1. 获取最后一段路径,即方法名称
  2. 通过反射获取方法对象,执行方法

注:

  • 不继承HttpServlet而进行自定义,并手动实现使用请求路径进行方法分发
  • 注意代码中this的使用方法(动态绑定
  • BaseServlet 负责替换 HttpServlet ,根据请求的最后一段路径进行方法分发,是 Servlet的父类

    package priv.dandelion.controller.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * 替换HttpServlet
     *
     * 根据请求的最后一段路径进行方法分发
     */
    public class BaseServlet extends HttpServlet {
        // 重写service,根据请求路径进行方法分发
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 1. 获取请求路径
            String requestURI = req.getRequestURI();    // /brand-case/brand/selectAll
            // 获取请求路径的最后一段,即方法名
            int index = requestURI.lastIndexOf('/');
            // substring(index)截取字符串为左闭右开区间,不需要斜杠,index需要+1
            String methodName = requestURI.substring(index + 1);
    
            // 2. 获取BrandServlet的字节码对象,并获取方法的Method对象
            // 此处的this为动态绑定(Servlet入口在子类中,子类调用父类方法,程序执行到此处时,this代表调用父类方法的子类对象)
            Class<? extends BaseServlet> cls = this.getClass();
            // 获取方法的Method对象
            try {
                Method method = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
    
                // 3. 执行方法
                method.invoke(this, req, resp);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    
  • BrandServlet 关于 Brand 的 Servlet 类,将多个 Servlet 写在一个类中

    package priv.dandelion.controller.servlet;
    
    import com.alibaba.fastjson.JSON;
    import priv.dandelion.entity.Brand;
    import priv.dandelion.service.BrandService;
    import priv.dandelion.service.impl.BrandServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.util.List;
    
    @WebServlet("/brand/*")
    public class BrandServlet extends BaseServlet{
    
        private BrandService brandService = new BrandServiceImpl();
    
        public void selectAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            List<Brand> brands = brandService.selectAll();
            // 将查询到的结果序列化为JSON
            String jsonString = JSON.toJSONString(brands);
            // 处理中文,使用utf-8
            resp.setContentType("text/json;charset=utf-8");
            // 写回数据
            resp.getWriter().write(jsonString);
        }
        
        // ...
        
    }
    

3.2 前端实现

  1. 页面加载完成后发送异步请求,获取列表数据(需要引入 Axios 的 JS 文件)
  2. 将数据设置到模型上
  • 代码

    <!--
    	...
    -->
    <script src="js/axios-0.18.0.js"></script>
    
    <script>
        new Vue({
            el: "#app",
            // 当页面加载完成后发送异步请求来获取数据
            mounted(){
                // 原生的this不能在Axios中使用,提升其生命周期
                var _this = this;
                // 使用Axios发送异步请求
                axios({
                    method:"get",
                    url:"http://localhost:8080/brand-case/selectAll"
                }).then(function (resp) {
                    _this.tableData = resp.data;
                })
            },
            
            // ...
            // ...
            // ...
        })
    </script>
    </body>
    </html>
    

4、添加功能

4.1 后端实现

4.1.1 Dao层方法实现

4.1.2 Service层方法实现

  • 添加接口

    /**
     * 添加数据
     */
    boolean addBrand(Brand brand);
    
  • 实现接口

    @Override
    public boolean addBrand(Brand brand) {
        // 自动提交事务
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    
        // 判断用户名是否不存在
        final boolean flag = (null == mapper.selectByBrandName(brand.getBrandName()));
        if (flag) mapper.addBrand(brand);
    
        sqlSession.close();
        return flag;
    }
    

4.1.3 Serlvet实现,在 BrandServlet 中添加方法

public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
    // 接收前端提交的数据
    BufferedReader reader = req.getReader();
    String params = reader.readLine();
    // 反序列化为Brand对象
    Brand brand = JSON.parseObject(params, Brand.class);
    // 调用Service进行添加
    if (brandService.addBrand(brand)) resp.getWriter().write("success");
}

4.2 前端实现

  1. 点击提交按钮时,发送AJAX请求携带表单数据
  2. 获取数据,判断添加是否成功,关闭窗口,重新加载数据
  • 代码

        <!--
            ......
        -->
    
    	<!--按钮-->
        <!--
            @click="dialogVisible = true"
            单击时将dialogVisible设置为true,展示对话框
        -->
        <el-row>
            <el-button type="danger" plain>批量删除</el-button>
            <el-button type="primary" plain @click="dialogVisible = true">新增</el-button>
        </el-row>
    
        <!--添加数据对话框表单-->
        <el-dialog
                title="编辑品牌"
                :visible.sync="dialogVisible"
                width="30%">
            <el-form ref="form" :model="brand" label-width="80px">
                <el-form-item label="品牌名称">
                    <el-input v-model="brand.brandName"></el-input>
                </el-form-item>
    
                <el-form-item label="企业名称">
                    <el-input v-model="brand.companyName"></el-input>
                </el-form-item>
    
                <el-form-item label="排序">
                    <el-input v-model="brand.ordered"></el-input>
                </el-form-item>
    
                <el-form-item label="备注">
                    <el-input type="textarea" v-model="brand.description"></el-input>
                </el-form-item>
    
                <el-form-item label="状态">
                    <el-switch v-model="brand.status"
                               active-value="1"
                               inactive-value="0"
                    ></el-switch>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="addBrand">提交</el-button>
                    <el-button @click="dialogVisible = false">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    
        <!--
            ......
        -->
    
    <script>
        new Vue({
            // ...
            // ...
            methods: {
                // 查询所有数据,抽出作为一个函数,降低耦合
                selectAll() {
                    // 原生的this不能在Axios中使用,提升其生命周期
                    var _this = this;
                    // 使用Axios发送异步请求
                    axios({
                        method:"get",
                        url:"http://localhost:8080/brand-case/selectAll"
                    }).then(function (resp) {
                        _this.tableData = resp.data;
                    })
                },
                
                // ...
                // ...
                // ...
                
                // 添加数据
                addBrand(){
                    //console.log(this.brand);
                    // 检验数据是否合法,判空细节不表
                    var flag = true;
                    // isNaN()函数 把空串 空格 以及NUll 按照0来处理,所以先去除。非数字类型返回true
                    if (this.brand.ordered == '' || this.brand.ordered == null || isNaN(this.brand.ordered)) {
                        flag = false;
                        this.$message({
                            message: '警告:排序不可为空且必须为一个数字',
                            type: 'warning'
                        });
                    }
                    // 原生的this不能在Axios中使用,提升其生命周期
                    var _this = this;
                    // 发送AJAX异步请求,添加数据
                    if (flag) {
                        axios({
                            method:"post",
                            url:"http://localhost:8080/brand-case/addBrand",
                            // Axios 内部不能使用原生的 this
                            data:_this.brand
                        }).then(function (resp){
                            if ("success" == resp.data) {
                                // 添加成功
                                // 关闭窗口
                                _this.dialogVisible = false;
                                // 重新查询数据
                                _this.selectAll();
                                // 显示成功提示
                                _this.$message({
                                    message: '品牌数据添加成功',
                                    type: 'success'
                                });
                            } else {
                                // 显示错误提示
                                _this.$message.error('该品牌已存在,添加失败');
                            }
                        })
                    }
                },
                // ...
                // ...
                // ...
    </script>
    </body>
    </html>
    

4、修改和删除功能

  • Dao

    @Update("update tb_brand " +
            "set brand_name = #{brandName}," +
            "company_name = #{companyName}," +
            "ordered = #{ordered}," +
            "description = #{description}," +
            "status = #{status} " +
            "where id = #{id};")
    void updateBrand(Brand brand);
    
    @Delete("delete from tb_brand where id = #{id};")
    void deleteBrand(@Param("id") String id);
    
  • Service 新增接口方法并实现

    @Override
    public boolean updateBrand(Brand brand) {
        // 自动提交事务
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    
        // 判断用户名是否不存在
        boolean flag = (null == mapper.selectByBrandName(brand.getBrandName()));
        if (flag) mapper.updateBrand(brand);
    
        sqlSession.close();
        return flag;
    }
    
    @Override
    public void deleteBrand(String id) {
        // 自动提交事务
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    
        mapper.deleteBrand(id);
    
        sqlSession.close();
    }
    
  • Servlet

    public void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        // 接收前端提交的数据
        BufferedReader reader = req.getReader();
        String params = reader.readLine();
        // 反序列化为Brand对象
        Brand brand = JSON.parseObject(params, Brand.class);
        // 调用Service进行修改
        if (brandService.addBrand(brand)) resp.getWriter().write("success");
    }
    
    public void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        // 接收前端提交的数据
        String id = req.getParameter("id");
        // 调用Service进行添加
        brandService.deleteBrand(id);
    }
    
  • 前端页面

    
    

5、批量删除功能

  • Dao

    • Mapper接口

      void deleteByIds(@Param("ids") int[] ids);
      
    • Mapper映射文件

      <!-- 批量删除,动态SQL -->
      <delete id="deleteByIds">
          <!-- delete from tb_brand where id in (?,?,...,?) -->
          delete from tb_brand where id in
          <foreach collection="ids" item="id" separator="," open="(" close=")">
              #{id}
          </foreach>
      </delete>
      
  • Service

    @Override
    public void deleteByIds(int[] ids) {
        // 自动提交事务
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    
        mapper.deleteByIds(ids);
        sqlSession.close();
    }
    
  • Servlet

    public void deleteByIds(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        // 接收前端提交的数据
        BufferedReader reader = req.getReader();
        String params = reader.readLine();
        // 反序列化为Brand对象
        int[] ids = JSON.parseObject(params, int[].class);
        brandService.deleteByIds(ids);
        resp.getWriter().write("success");
    }
    
  • 前端页面

    <!--
    	...
    -->
    
    <div id="app">
        
        <!--
    		...
    	-->
        
        <el-row>
            <el-button type="danger" plain @click="deleteByIds">批量删除</el-button>
            <el-button type="primary" plain @click="dialogVisible = true">新增</el-button>
        </el-row>
    
        <!--
    		...
    	-->
    
    </div>
    
    <!--
    	...
    -->
    
    <script>
        new Vue({
            el: "#app",
            // 当页面加载完成后发送异步请求来获取数据
            mounted(){
                this.selectAll();
            },
            methods: {
                // ...
                // ...
                // 批量删除
                deleteByIds() {
                    this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        this.$message({
                            type: 'success',
                            message: '正在删除...'
                        });
                        // 将id数据写入被选中的id数组模型
                        for (let i = 0; i < this.multipleSelection.length; i++) {
                            let selectionElem = this.multipleSelection[i];
                            this.selectedIds[i] = selectionElem.id;
                        }
                        console.log(this.multipleSelection);
                        console.log(this.selectedIds);
                        // 发送AJAX请求
                        var _this = this;
                        axios({
                            method:"post",
                            url:"http://localhost:8080/brand-case/brand/deleteByIds",
                            // Axios 内部不能使用原生的 this
                            data:_this.selectedIds
                        }).then(function (resp){
                            if ("success" == resp.data) {
                                // 重新查询数据
                                _this.selectAll();
                                // 显示成功提示
                                _this.$message({
                                    message: '删除成功',
                                    type: 'success'
                                });
                            } else {
                                // 显示错误提示
                                _this.$message.error('删除失败');
                            }
                        })
                    }).catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消删除'
                        });
                    });
                }
            },
            data() {
                return {
                    // ...
                    // ...
                    // 被选中的数据库id数组
                    selectedIds:[]
                }
            }
        })
    </script>
    </body>
    </html>
    

6、分页功能

  • 用于分页查询的 JavaBean

    package priv.dandelion.entity;
    
    import java.util.List;
    
    /**
     * 分页查询的JavaBean
     */
    public class PageBean<T> {
        // 总记录数
        private int totalCount;
        // 当前页数据
        private List<T> rows;
    
        public int getTotalCount() {
            return totalCount;
        }
    
        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }
    
        public List<T> getRows() {
            return rows;
        }
    
        public void setRows(List<T> rows) {
            this.rows = rows;
        }
    }
    
  • Dao

    // limit 开始索引, 查询的条目数
    // select * from tb limit 0, 5
    // 页面传递的参数为 起始条数和每一页显示的条数
    // 开始索引 = (当前页码 - 1) * 每一页显示的条数
    @Select("select * from tb_brand limit #{begin}, #{pageSize}")
    List<Brand> selectByPage(@Param("begin") int begin, @Param("pageSize") int pageSize);
    
    @Select("select count(*) from tb_brand")
    int selectTotalCount();
    
  • Service

    @Override
    public PageBean<Brand> selectByPage(int currentPage, int pageSize) {
    
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    
        // 计算开始索引
        int begin = (currentPage - 1) * pageSize;
    
        // 查询数据
        List<Brand> rows = mapper.selectByPage(begin, pageSize);
        int totalCount = mapper.selectTotalCount();
    
        // 封装数据
        PageBean<Brand> brandPageBean = new PageBean<>();
        brandPageBean.setRows(rows);
        brandPageBean.setTotalCount(totalCount);
    
        sqlSession.close();
        return brandPageBean;
    }
    
  • Servlet

    public void selectByPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        // 接收当前页码和每页展示条数
        int currentPage = Integer.parseInt(req.getParameter("currentPage"));
        int pageSize = Integer.parseInt(req.getParameter("pageSize"));
        // 调用对应的Service进行查询
        PageBean<Brand> brandPageBean = brandService.selectByPage(currentPage, pageSize);
        // 序列化为JSON
        String jsonString = JSON.toJSONString(brandPageBean);
        // 写回数据
        resp.setContentType("text/json;charset=utf-8");
        resp.getWriter().write(jsonString);
    }
    
  • 页面

    <!--
    	...
    -->
    
        <!--分页工具条,绑定Model-->
        <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="[5, 10, 15, 20]"
                :page-size="pageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="totalCount">
        </el-pagination>
    
    <!--
    	...
    -->
    
    <script>
        new Vue({
            el: "#app",
            // 当页面加载完成后发送异步请求来获取数据
            mounted(){
                this.selectAll();
            },
            methods: {
                // 查询所有数据,抽出作为一个函数,降低耦合
                selectAll() {
                    // 原生的this不能在Axios中使用,提升其生命周期
                    var _this = this;
                    // 使用Axios发送异步请求
                    axios({
                        method:"get",
                        // URL改为分页查询所需的URL
                        url:"http://localhost:8080/brand-case/brand/selectByPage?currentPage="+ _this.currentPage +"&pageSize="+ _this.pageSize
                    }).then(function (resp) {
                        _this.tableData = resp.data.rows;
                        _this.totalCount = resp.data.totalCount;
                    })
                },
                // ...
                // ...
                // ...
            },
            data() {
                return {
                    // 每页记录数
                    pageSize: 5,
                    // 当前页码
                    currentPage: 1,
                    // 总记录数
                    totalCount: 100,
                    // ...
                    // ...
                }
            }
        })
    </script>
    </body>
    </html>
    

7、条件查询

  • Dao

    • Mapper接口

      List<Brand> selectByPageAndCondition(@Param("begin") int begin, @Param("pageSize") int pageSize, @Param("brand") Brand brand);
      int selectTotalCount();
      
    • Mapper映射文件

      <!-- 条件查询 -->
      <select id="selectByPageAndCondition" resultMap="brandResultMap">
          select * from tb_brand
          <where>
              <if test="brand.brandName != null and brand.brandName != ''">
                  brand_name like #{brand.brandName}
              </if>
              <if test="brand.companyName != null and brand.companyName != ''">
                  and company_name like #{brand.companyName}
              </if>
              <if test="brand.status != null">
                  and status = #{brand.status}
              </if>
          </where>
          limit #{begin}, #{pageSize}
      </select>
      
      <select id="selectTotalCountByCondition" resultType="java.lang.Integer">
          select count(*) from tb_brand
          <where>
              <if test="brand.brandName != null and brand.brandName != ''">
                  brand_name like #{brand.brandName}
              </if>
              <if test="brand.companyName != null and brand.companyName != ''">
                  and company_name like #{brand.companyName}
              </if>
              <if test="brand.status != null">
                  and status = #{brand.status}
              </if>
          </where>
      </select>
      
  • Service

    @Override
    public PageBean<Brand> selectByPageAndCondition(int currentPage, int pageSize, Brand brand) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    
        // 计算开始索引
        int begin = (currentPage - 1) * pageSize;
        // 模糊查询准备
        String brandName = brand.getBrandName();
        String companyName = brand.getCompanyName();
        if (brandName != null && brandName.length() > 0)
            brand.setBrandName("%"+ brandName +"%");
        if (companyName != null && companyName.length() > 0)
            brand.setCompanyName("%"+ companyName +"%");
    
        // 查询数据
        List<Brand> rows = mapper.selectByPageAndCondition(begin, pageSize, brand);
        int totalCountByCondition = mapper.selectTotalCountByCondition(brand);
    
        // 封装数据
        PageBean<Brand> brandPageBean = new PageBean<>();
        brandPageBean.setRows(rows);
        brandPageBean.setTotalCount(totalCountByCondition);
    
        sqlSession.close();
        return brandPageBean;
    }
    
  • Servlet

    public void selectByPageAndCondition(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        // 接收当前页码和每页展示条数
        int currentPage = Integer.parseInt(req.getParameter("currentPage"));
        int pageSize = Integer.parseInt(req.getParameter("pageSize"));
        // 获取查询条件对象
        BufferedReader reader = req.getReader();
        String params = reader.readLine();
        Brand brand = JSON.parseObject(params, Brand.class);
    
        // 调用对应的Service进行查询
        PageBean<Brand> brandPageBean = brandService.selectByPageAndCondition(currentPage, pageSize, brand);
        // 序列化为JSON
        String jsonString = JSON.toJSONString(brandPageBean);
        // 写回数据
        resp.setContentType("text/json;charset=utf-8");
        resp.getWriter().write(jsonString);
    }
    
  • 页面

    <!--
    	...
    -->
    <div id="app">
        <!--搜索表单-->
        <el-form :inline="true" :model="brand" class="demo-form-inline">
            <!--
            	...
        	-->
    
            <el-form-item>
                <el-button type="primary" @click="onSubmit">查询</el-button>
            </el-form-item>
        </el-form>
    	<!--
            ...
        -->
        
    </div>
    <!--
    	...
    -->
    
    <script>
        new Vue({
            el: "#app",
            // 当页面加载完成后发送异步请求来获取数据
            mounted(){
                this.selectAll();
            },
            methods: {
                // 查询所有数据,抽出作为一个函数,降低耦合
                selectAll() {
                    // 原生的this不能在Axios中使用,提升其生命周期
                    var _this = this;
                    // 使用Axios发送异步请求
                    axios({
                        method:"post",
                        url:"http://localhost:8080/brand-case/brand/selectByPageAndCondition?currentPage="+ _this.currentPage +"&pageSize="+ _this.pageSize,
                        data:_this.brand
                    }).then(function (resp) {
                        _this.tableData = resp.data.rows;
                        _this.totalCount = resp.data.totalCount;
                    })
                },
                
                // ...
                // ...
                
                // 查询方法
                onSubmit() {
                    this.selectAll();
                },
                // ...
                // ...
            },
            // ...
        })
    </script>
    </body>
    </html>
    

标签:resp,JavaWeb,批量,int,brand,CRUD,id,import,public
From: https://www.cnblogs.com/dandelion-000-blog/p/16905865.html

相关文章

  • UE4 UE5 Unreal Engine 编辑器开发 批量给模型添加材质
    这部分主要使用的是蓝图的编辑器开发。具体的蓝图代码如下图所示:   ......
  • jquery简单crud操作
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metaname="viewport"c......
  • 第2-3-6章 打包批量下载附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云
    目录5.6接口开发-根据文件id打包下载附件5.6.1接口文档5.6.2代码实现5.6.3接口测试5.7接口开发-根据业务类型/业务id打包下载5.7.1接口文档5.7.2代码实现5.7.3接口......
  • Mysql批量更新性能优化学习
    转自:https://juejin.cn/post/70435968558290698611.更新对表做多行更新的时候通常会遇到以下两种情况:单语句批量更新(updatea=a+1wherepk>500)多语句批量更新(updat......
  • Mysql批量插入性能优化学习
    转自:https://www.cnblogs.com/myseries/p/11191134.html1.批量insert1.1一条sql将单条insert改为批量insert,其实个人认为改为replaceinto更好,批量insert时,如果其中一......
  • JavaWeb-06-Servlet
    6.Servlet6.1Servlet简介Servlet就是sun公司开发动态web的一门技术Sun公司在这些API中提供了一个接口叫作:Servlet,如果要开发一个Servlet程序,只需要完成两个步骤:编......
  • jmeter,批量注册账号并写到本地
    日常jmeter使用比较繁琐,日常记录,方便自己查阅;1.请求一个添加用户接口,并随机字符串入参,批量注册账号大致json报文如下:{"username":"${abc}","password":"${pas}","co......
  • SOLIDWORKS如何批量拆分多配置
    SOLIDWORKS的配置功能让我们可以在单一的文件中对零件或装配体生成多个设计变化。在零件文档中,配置可以生成具有不同尺寸、特征和属性的零件系列。在装配体文件中,配置可以......
  • bash脚本批量启动停止jar包
    #!/bin/sh#端口号PORTS=(100868380858088890080878089)#系统模块MODULES=(registrygatewayuserwelcowisdomauthresources)#系统模块名称MODULE_NAMES=(注册......
  • 使用Python批量对文本文件编码互转
    在Windows下写C语言默认是GB2312,放到Linux上就会乱码,因为Linux和MacOS默认是UTF-8,因此写了个Python小脚本对指定路径下的文件进行转换。fromsysimportargvimportosf......