20220722_JavaWeb最终案例

本文档展示了使用MyBatis框架完成的一个JavaWeb项目,包括页面效果展示、代码结构、数据库操作及功能实现。涉及BrandMapper、service层、servlet类和前端页面的详细设计,涵盖增删查改和分页查询等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于本案例工程较为复杂,原本按功能分开写的后端代码都被整合在一个文件里了,无法按照分段思路将步骤依次记录在此,所以直接给出所有代码文件的最终形式
完成后的结构图,其中old包下的代码文件丢弃不用,UserServlet文件也是测试简化Servlet功能的临时测试类,可以丢弃
请添加图片描述
完成后的网页效果,页面中所有按键功能实现
请添加图片描述
下面上代码

文章目录


前期准备
先来一个数据库的表

use mybatis;

show tables ;

-- 删除tb_brand表
drop table if exists brand_pro;
-- 创建tb_brand表
create table brand_pro
(
    -- 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 brand_pro (brand_name, company_name, ordered, description, status)
values 
       ('马大帅', '马大帅打工子弟小学', 100, '一个情字儿活一生', 1),
       ('依然范德彪', '维多利亚玉乐广场', 50, '我曾经年少轻狂', 1),
       ('罗翔说刑法', '厚大法考', 30, '女生宿舍居然有哑铃', 1),
       ('布飘零半生', '虎牢关', 10, '我平生不好斗,只好解斗', 1),
       ('青梅煮酒', '曹氏集团暨刘关张集团', 50, '玄德久历四方,必知当世英雄', 0),
       ('王司徒', '两军阵前', 5, '来者可是诸葛孔明', 0),
       ('张麻子', '鹅城县衙', 40, '翻译翻译什么tomato叫惊喜', 1),
       ('冯斯妥洛夫斯基', '加州旅馆天津分馆', 5, '王秘书,把三悬拿来', 0),
       ('马大帅', '马大帅打工子弟小学', 100, '一个情字儿活一生', 1),
       ('依然范德彪', '维多利亚玉乐广场', 50, '我曾经年少轻狂', 1),
       ('罗翔说刑法', '厚大法考', 30, '女生宿舍居然有哑铃', 1),
       ('布飘零半生', '虎牢关', 10, '我平生不好斗,只好解斗', 1),
       ('青梅煮酒', '曹氏集团暨刘关张集团', 50, '玄德久历四方,必知当世英雄', 0),
       ('王司徒', '两军阵前', 5, '来者可是诸葛孔明', 0),
       ('张麻子', '鹅城县衙', 40, '翻译翻译什么tomato叫惊喜', 1),
       ('冯斯妥洛夫斯基', '加州旅馆天津分馆', 5, '王秘书,把三悬拿来', 0),
       ('马大帅', '马大帅打工子弟小学', 100, '一个情字儿活一生', 1),
       ('依然范德彪', '维多利亚玉乐广场', 50, '我曾经年少轻狂', 1),
       ('罗翔说刑法', '厚大法考', 30, '女生宿舍居然有哑铃', 1),
       ('布飘零半生', '虎牢关', 10, '我平生不好斗,只好解斗', 1),
       ('青梅煮酒', '曹氏集团暨刘关张集团', 50, '玄德久历四方,必知当世英雄', 0),
       ('王司徒', '两军阵前', 5, '来者可是诸葛孔明', 0),
       ('张麻子', '鹅城县衙', 40, '翻译翻译什么tomato叫惊喜', 1),
       ('冯斯妥洛夫斯基', '加州旅馆天津分馆', 5, '王秘书,把三悬拿来', 0),
       ('马大帅', '马大帅打工子弟小学', 100, '一个情字儿活一生', 1),
       ('依然范德彪', '维多利亚玉乐广场', 50, '我曾经年少轻狂', 1),
       ('罗翔说刑法', '厚大法考', 30, '女生宿舍居然有哑铃', 1),
       ('布飘零半生', '虎牢关', 10, '我平生不好斗,只好解斗', 1),
       ('青梅煮酒', '曹氏集团暨刘关张集团', 50, '玄德久历四方,必知当世英雄', 0),
       ('王司徒', '两军阵前', 5, '来者可是诸葛孔明', 0),
       ('张麻子', '鹅城县衙', 40, '翻译翻译什么tomato叫惊喜', 1),
       ('冯斯妥洛夫斯基', '加州旅馆天津分馆', 5, '王秘书,把三悬拿来', 0),	  
       ('马大帅', '马大帅打工子弟小学', 100, '一个情字儿活一生', 1),
       ('依然范德彪', '维多利亚玉乐广场', 50, '我曾经年少轻狂', 1),
       ('罗翔说刑法', '厚大法考', 30, '女生宿舍居然有哑铃', 1),
       ('布飘零半生', '虎牢关', 10, '我平生不好斗,只好解斗', 1),
       ('青梅煮酒', '曹氏集团暨刘关张集团', 50, '玄德久历四方,必知当世英雄', 0),
       ('王司徒', '两军阵前', 5, '来者可是诸葛孔明', 0),
       ('张麻子', '鹅城县衙', 40, '翻译翻译什么tomato叫惊喜', 1),
       ('冯斯妥洛夫斯基', '加州旅馆天津分馆', 5, '王秘书,把三悬拿来', 0),
       ('马大帅', '马大帅打工子弟小学', 100, '一个情字儿活一生', 1),
       ('依然范德彪', '维多利亚玉乐广场', 50, '我曾经年少轻狂', 1),
       ('罗翔说刑法', '厚大法考', 30, '女生宿舍居然有哑铃', 1),
       ('布飘零半生', '虎牢关', 10, '我平生不好斗,只好解斗', 1),
       ('青梅煮酒', '曹氏集团暨刘关张集团', 50, '玄德久历四方,必知当世英雄', 0),
       ('王司徒', '两军阵前', 5, '来者可是诸葛孔明', 0),
       ('张麻子', '鹅城县衙', 40, '翻译翻译什么tomato叫惊喜', 1),
       ('冯斯妥洛夫斯基', '加州旅馆天津分馆', 5, '王秘书,把三悬拿来', 0)	   
        ;
SELECT * FROM brand_pro;

-- from index 0, select 8 brand
select * from brand_pro limit 0,8;

select count(*) from brand_pro;

后续功能测试中数据条目有增有减,依据需要复制insert语句的部分代码添加条目即可
请添加图片描述

element-ui包官网下载,js包里准备的js文件也一样
其他的自己写
我之前项目里也有准备,所以基本复制即可,代码如下
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>org.example</groupId>
    <artifactId>JavaWeb_last</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>18</maven.compiler.source>
        <maven.compiler.target>18</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <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>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!--JSON-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.7</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>

</project>

mybtis-config.xml文件

<?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>
        <!--配置别名之后,javabean全限名的包名就可以省略了-->
        <package name="com.diy.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库链接信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSl=false&amp;useServerPrepStmts=true"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--此处加载sql的映射文件-->
        <package name="com.diy.mapper"/>
    </mappers>
</configuration>

创建SQL会话工厂的工具类

package com.diy.util;

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 {
        //静态代码块会随着类的加载而自动执行,且只执行一次

        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

指派servlet中方法调用的父类servlet

package com.diy.web.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * replace HttpServlet, according request path tail, decide which method be invoked
 */

public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //get req path
        String URI = req.getRequestURI();// /JavaWeb_last/brand/queryAll
//        System.out.println(URI);
        // split last part
        int index = URI.lastIndexOf('/');
        String methodName = URI.substring(index + 1);
//        System.out.println(methodName);
        /**
         * execute method,
         * but we just got the name of method, it is a string, can not be invoked
         * we must get the Class file of brand servlet, then we can invoke the method
         */
        //System.out.println(this);//if we visit service by brand servlet, "this" will present brand servlet
        /**
         * so we can get Class file just by this, then we get the method
         */
        Class<? extends BaseServlet> cls = this.getClass();
        try {
            //get the method, and need the general args req and resp
            Method mth = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //finally, invoking
            mth.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

}

文章目录


然后开始就是只能在实现各功能过程中渐进写全的代码了
包括原本分开写的代码都写到一个类里了,所以直接贴完成态

BrandMapper.xml

<?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="com.diy.mapper.BrandMapper">

    <!--resolve the brand_name with brandName problem, type is the table name in database-->
    <resultMap id="BrandResultMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>
    <delete id="deleteByIds">
        delete from mybatis.brand_pro where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>


    <select id="selectByPageWithCondition" resultMap="BrandResultMap" resultType="com.diy.pojo.Brand">
        select *
        from mybatis.brand_pro
        <where>
            <if test="brand.brandName != null and brand.brandName != ''">
                and 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}, #{size}
    </select>

    <select id="selectTotalCountWithCondition" resultType="java.lang.Integer">
        select COUNT(*)
        from mybatis.brand_pro
        <where>
            <if test="brandName != null and  brandName != ''">
                and brand_name like #{brandName}
            </if>
            <if test="companyName != null and  companyName != ''">
                and company_name like #{companyName}
            </if>
            <if test="status != null">
                and status = #{status}
            </if>
        </where>
    </select>

</mapper>

BrandMapper.java代理接口

package com.diy.mapper;

import com.diy.pojo.Brand;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface BrandMapper {

    /**
     * query all brands
     */
    @Select("select * from mybatis.brand_pro")
    @ResultMap("BrandResultMap")
    List<Brand> queryAll();


    /**
     * add new brand
     */
    @Insert("insert into mybatis.brand_pro values (null, #{brandName},#{companyName},#{ordered},#{description},#{status})")
    void add(Brand brand);

    /**
     * update edited brand info
     */
    @Update("update mybatis.brand_pro set brand_name = #{brandName}, company_name = #{companyName},ordered = #{ordered},description = #{description} where id = #{id}")
    void update(Brand brand);

    /**
     * delete one brand by id
     */
    @Delete("delete from mybatis.brand_pro where id = #{id}")
    void deleteById(int id);

    /**
     * delete many brand by many ids
     * here we need to use dynamic sql, so we don't use annotation sql
     */
    void deleteByIds(@Param("ids")int[] ids);

    /**
     * query by pagination
     */
    @Select("select * from mybatis.brand_pro limit #{begin}, #{size}")
    @ResultMap("BrandResultMap")
    List<Brand> selectByPage(@Param("begin")int begin, @Param("size") int size);
    @Select("select count(*) from mybatis.brand_pro")
    int selectTotalCount();

    /**
     * query by condition box
     * and match pagination also
     * dynamic sql, use xml file write sql statement
     */
    List<Brand> selectByPageWithCondition(@Param("begin")int begin, @Param("size") int size, @Param("brand") Brand brand);
    int selectTotalCountWithCondition(Brand brand);


}

Brand类

package com.diy.pojo;

/**
 * 品牌实体类
 */

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, String description) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.description = description;
    }

    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 String getStatusStr() {

        if(this.status == 1){
            return "Enable";
        }

        return "Disable";
    }
    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

PageBean类,这是给分页和条件查询传数据的类

package com.diy.pojo;

import java.util.List;

/**
 * it is a class for create ob deposit data that pagination need
 */
public class PageBean<T> {
    // you can use long instead of int
    private int totalCount;

    private List<T> rowsInPage;

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public List<T> getRowsInPage() {
        return rowsInPage;
    }

    public void setRowsInPage(List<T> rowsInPage) {
        this.rowsInPage = rowsInPage;
    }
}

service层接口类,现在开始不直接创service类,而用多态的方式创建,为将来框架的使用做准备

package com.diy.service;

import com.diy.pojo.Brand;
import com.diy.pojo.PageBean;

import java.util.List;


/**
 * in service layer, we use an interface, instead of service class directly
 */
public interface BrandService {

    /**
     * query all brands
     */
    List<Brand> queryAll();

    /**
     * add new brand
     */
    void add(Brand brand);

    /**
     * update edited brand info
     */
    void update(Brand brand);

    /**
     * delete one brand by id
     */
    void deleteById(int id);

    /**
     * delete many brand by many ids
     */
    void deleteByIds(int[] ids);

    /**
     * query by pagination
     */
    PageBean<Brand> selectByPage(int currentPage, int pageSize);
//    int selectTotalCount();//no need this, the impl Class can invoke it directly by mapper

    /**
     * query by condition and match pagination
     */
    PageBean<Brand> selectByPageWithCondition(int currentPage, int pageSize, Brand brand);


}

service层实现类,所有真正被调用的数据库方法都在这里,其中的queryAll和selectByPage方法将被最终的selectByPageWithCondition方法取代,但代码依然保留

package com.diy.service.Impl;

import com.diy.mapper.BrandMapper;
import com.diy.pojo.Brand;
import com.diy.pojo.PageBean;
import com.diy.service.BrandService;
import com.diy.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

public class BrandServiceImpl implements BrandService {

    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();

    /**
     * query all brands
     */
    @Override
    public List<Brand> queryAll() {

        SqlSession Session = factory.openSession();

        BrandMapper mapper = Session.getMapper(BrandMapper.class);

        List<Brand> brands = mapper.queryAll();

        Session.close();

        return brands;

    }

    /**
     * add new brand
     */
    @Override
    public void add(Brand brand) {
        SqlSession sess = factory.openSession();

        BrandMapper mapper = sess.getMapper(BrandMapper.class);

        mapper.add(brand);

        sess.commit();

        sess.close();
    }

    @Override
    public void update(Brand brand) {
        SqlSession sess = factory.openSession();

        BrandMapper mapper = sess.getMapper(BrandMapper.class);

        mapper.update(brand);

        sess.commit();

        sess.close();
    }

    @Override
    public void deleteById(int id) {
        SqlSession sess = factory.openSession();

        BrandMapper mapper = sess.getMapper(BrandMapper.class);

        mapper.deleteById(id);

        sess.commit();

        sess.close();

    }

    @Override
    public void deleteByIds(int[] ids) {
        SqlSession sess = factory.openSession();

        BrandMapper mapper = sess.getMapper(BrandMapper.class);

        mapper.deleteByIds(ids);

        sess.commit();

        sess.close();
    }

    /**
     * query by pagination
     */
    @Override
    public PageBean<Brand> selectByPage(int currentPage, int pageSize) {
        SqlSession sess = factory.openSession();
        BrandMapper mapper = sess.getMapper(BrandMapper.class);

        //get args for invoking
        int size = pageSize;
        int begin = (currentPage -1) * pageSize;
        //invoke method
        List<Brand> rowsInPage = mapper.selectByPage(begin, size);
        int count = mapper.selectTotalCount();
        //deposit result into a pageBean ob
        PageBean<Brand> pageBean = new PageBean<>();
        pageBean.setRowsInPage(rowsInPage);
        pageBean.setTotalCount(count);

        sess.close();

        return pageBean;
    }

    /**
     * query by condition and match pagination
     */
    @Override
    public PageBean<Brand> selectByPageWithCondition(int currentPage, int pageSize, Brand brand) {
        SqlSession sess = factory.openSession();
        BrandMapper mapper = sess.getMapper(BrandMapper.class);

        //get args for invoking
        int size = pageSize;
        int begin = (currentPage -1) * pageSize;

        //handle query by fuzzy match, when user input part of brand name or company name
        String brandName = brand.getBrandName();
        if (brandName != null && brandName.length() >0) {
            brand.setBrandName("%"+brandName+"%");
        }
        String companyName = brand.getCompanyName();
        if (companyName != null && companyName.length() >0) {
            brand.setCompanyName("%"+companyName+"%");
        }

        List<Brand> rowsInPage = mapper.selectByPageWithCondition(begin, size, brand);
        int totalCount = mapper.selectTotalCountWithCondition(brand);

        //wrap into a page bean ob
        PageBean<Brand> pageBean = new PageBean<>();
        pageBean.setRowsInPage(rowsInPage);
        pageBean.setTotalCount(totalCount);

        sess.close();

        return pageBean;
    }


}

服务器收到网页功能请求,提供相应方法的servlet类
之前分散写的servlet全写在一起了,其中方法指派通过自创的父类servlet,当网页请求资源时,会通过父类的service方法,调用相应的子类servlet方法

package com.diy.web.servlet;

import com.alibaba.fastjson.JSON;
import com.diy.pojo.Brand;
import com.diy.pojo.PageBean;
import com.diy.service.BrandService;
import com.diy.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 BS = new BrandServiceImpl();

    /**
     * see all brand's info on page
     */
    public void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("brand queryAll~~~");
        resp.setContentType("text/json;charset=utf-8");

        //use service invoke method ,get return ob
        List<Brand> brands = BS.queryAll();

        //convert it to json
        String jbs = JSON.toJSONString(brands);

        //output
        resp.getWriter().write(jbs);
    }

    /**
     * add a new brand
     */
    public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("brand add~~~");
        //receive request
        BufferedReader brd = req.getReader();
        //reader request params, json string, no matter how long it is ,it is one line
        String params = brd.readLine();
        //convert to a brand ob
        Brand brand = JSON.parseObject(params,Brand.class);
        //invoke add method
        BS.add(brand);
        //response a msg means success
        resp.getWriter().write("bingo");

    }

    /**
     * edit a brand
     */
    public void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // solve garbled char problem first
        req.setCharacterEncoding("utf-8");
        //get params in JSON from req
        BufferedReader reader = req.getReader();
        String params = reader.readLine();//no matter how long, it is one line
        //get a brand ob from json
        Brand brand = JSON.parseObject(params, Brand.class);
        //invoke update method put brand in ()
        BS.update(brand);

        //till now no problem, resp a bingo
        resp.getWriter().write("bingo");

    }

    /**
     * delete only one brand
     */
    public void deleteById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this parameter is transited by GET way, so no need JSON.parseObject
        String sid = req.getParameter("id");
        //convert to int
        int id = Integer.parseInt(sid);

        BS.deleteById(id);

        resp.getWriter().write("bingo");
    }

    /**
     * delete many brands
     */
    public void deleteByIds(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // solve garbled char problem first, in case
//        req.setCharacterEncoding("utf-8");
        //get params in JSON from req
        BufferedReader reader = req.getReader();
        String params = reader.readLine();//no matter how long, it is one line
        //get an array from json
        int[] ids = JSON.parseObject(params, int[].class);

        BS.deleteByIds(ids);

        resp.getWriter().write("bingo");

    }

    /**
     * for pagination query
     */
    public void selectByPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // receive current page and it's size  ===> URL:/selectByPage?currentPage=1&pageSize=5
        String _currentPage = req.getParameter("currentPage");
        String _pageSize = req.getParameter("pageSize");

        int currentPage = Integer.parseInt(_currentPage);
        int pageSize = Integer.parseInt(_pageSize);

        //use service invoke method ,get return ob
        PageBean<Brand> pageBean = BS.selectByPage(currentPage, pageSize);

        //convert it to json
        String jpb = JSON.toJSONString(pageBean);

        //output
        resp.setContentType("text/json;charset=utf-8");
        resp.getWriter().write(jpb);
    }

    /**
     * query by condition and match pagination
     */
    public void selectByPageWithCondition(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // receive current page and it's size  ===> URL:/selectByPage?currentPage=1&pageSize=5
        String _currentPage = req.getParameter("currentPage");
        String _pageSize = req.getParameter("pageSize");

        int currentPage = Integer.parseInt(_currentPage);
        int pageSize = Integer.parseInt(_pageSize);

        //get condition params from post request body
        BufferedReader reader = req.getReader();
        String params = reader.readLine();
        //convert params to a brand ob
        Brand brand = JSON.parseObject(params, Brand.class);

        //use service invoke method ,get return ob
        PageBean<Brand> pageBean = BS.selectByPageWithCondition(currentPage, pageSize,brand);

        //convert it to json
        String jpb = JSON.toJSONString(pageBean);

        //output
        resp.setContentType("text/json;charset=utf-8");
        resp.getWriter().write(jpb);
    }
}

最重头的,网页代码,前端所有的功能和视图都在这里了
brand.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>鬼畜英雄好汉谱</title>
    <style>
        .el-table .warning-row {
            background: oldlace;
        }

        .el-table .success-row {
            background: #f0f9eb;
        }
    </style>

</head>
<body>
<div id="app">

    <!--Search Form-->
    <el-form :inline="true" :model="brand" class="demo-form-inline">
        <el-form-item label="Status Now">
            <el-select v-model="brand.status" placeholder="Status Now">
                <el-option label="Enable" value="1"></el-option>
                <el-option label="Disable" value="0"></el-option>
            </el-select>
        </el-form-item>

        <el-form-item label="Company">
            <el-input v-model="brand.companyName" placeholder="Company"></el-input>
        </el-form-item>

        <el-form-item label="Brand">
            <el-input v-model="brand.brandName" placeholder="Brand"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="onSubmit">Query</el-button>
        </el-form-item>
    </el-form>

    <el-row>
        <el-button type="danger" @click="deleteByIds" plain>Batch Delete</el-button>
        <el-button type="primary" @click="dialogVisible = true" plain>Add New</el-button>
    </el-row>
    <!--add dialog form-->
    <el-dialog title="Add Brand" :visible.sync="dialogVisible" width="30%">

        <el-form ref="form" :model="brand" label-width="120px">
            <el-form-item label="Brand">
                <el-input v-model="brand.brandName"></el-input>
            </el-form-item>
            <el-form-item label="Company">
                <el-input v-model="brand.companyName"></el-input>
            </el-form-item>
            <el-form-item label="Ordered">
                <el-input v-model="brand.ordered"></el-input>
            </el-form-item>
            <el-form-item label="Remark">
                <el-input type="textarea" v-model="brand.description"></el-input>
            </el-form-item>
            <el-form-item label="Status">
                <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">Create</el-button>
                <el-button @click="dialogVisible = false">Cancel</el-button>
            </el-form-item>
        </el-form>
    </el-dialog>


    <template>
        <el-table
                :data="tableData"
                style="width: 100%"
                :row-class-name="tableRowClassName"
                @selection-change="handleSelectionChange">
            <el-table-column
                    type="selection"
                    align="center"
                    width="55">
            </el-table-column>
            <el-table-column
                    type="index"
                    width="50">
            </el-table-column>
            <el-table-column
                    prop="brandName"
                    label="Brand"
                    align="center"
                    >
            </el-table-column>
            <el-table-column
                    prop="companyName"
                    label="Company"
                    align="center"
                    >
            </el-table-column>
            <el-table-column
                    prop="ordered"
                    label="Ordered"
                    align="center"
                    >
            </el-table-column>
            <el-table-column
                    prop="statusStr"
                    label="Status"
                    align="center">
            </el-table-column>

            <el-table-column

                    label="Operation"
                    align="center">

                <template slot-scope="scope">
                    <el-row>
                        <el-button type="primary" @click="startEdit(scope.row)">Edit</el-button>
                        <el-button type="danger" @click="deleteById(scope.row)">Delete</el-button>
                    </el-row>
                </template>

            </el-table-column>
        </el-table>
    </template>
    <!-- edit brand dialog ,this position and surrounded by template same slot-scope with edit button-->
    <el-dialog title="Edit Brand" :visible.sync="editDialogVisible" width="30%">
        <template slot-scope="scope">
        <el-form ref="form" :model="brandEdition" label-width="120px">
            <el-form-item label="Brand">
                <el-input v-model="brandEdition.brandName"></el-input>
            </el-form-item>
            <el-form-item label="Company">
                <el-input v-model="brandEdition.companyName"></el-input>
            </el-form-item>
            <el-form-item label="Ordered">
                <el-input v-model="brandEdition.ordered"></el-input>
            </el-form-item>
            <el-form-item label="Remark">
                <el-input type="textarea" v-model="brandEdition.description"></el-input>
            </el-form-item>
            <el-form-item label="Status">
                <el-switch v-model="brandEdition.status" :active-value="1" :inactive-value="0"></el-switch>
            </el-form-item>

            <el-form-item>
                <el-button type="primary" @click="confirmEdit" >Confirm</el-button>
                <el-button @click="cancelEdit">Cancel</el-button>
            </el-form-item>
        </el-form>
        </template>
    </el-dialog>

    <!--pagination-->
    <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page.sync="currentPage"
            :page-sizes="[5,10,15,30,50]"
            :page-size="10"
            layout="total, sizes, prev, pager, next, jumper"
            :total="totalCount">
    </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 src="js/axios-0.18.0.js"></script>

<script>
    new Vue({
        el: "#app",
        mounted(){
            this.queryAll()
        },
        methods: {
            /**
             *for every time we need to reload the page and see all brands info
             */
            queryAll() {
                // var _this = this
                // axios({
                //     method: "get",
                //     url: "http://localhost:8080/JavaWeb_last/brand/queryALl"
                // }).then(function (resp) {
                //     _this.tableData = resp.data;
                //
                // })

                /*from select All change to select all in one page*/
/*                var _this = this
                axios({
                    /!*
                    * for condition query, here use both data:{} and url? to transit params
                    * and, all query through selectByPageWithCondition method
                    * and, "this" in then(), need use "_this", but just in axios, just "this" will be OK
                    *!/
                    method: "post",
                    url: "http://localhost:8080/JavaWeb_last/brand/selectByPageWithCondition?currentPage="+this.currentPage+"&pageSize="+this.pageSize,
                    data:this.brand
                }).then(function (resp) {
                    //data for table
                    _this.tableData = resp.data.rowsInPage;//{ rowsInPage : [], totalCount : int }
                    _this.totalCount = resp.data.totalCount;
                })*/

                axios({
                    /*
                    * for condition query, here use both data:{} and url? to transit params
                    * and, all query through selectByPageWithCondition method
                    * and, "this" in then(), need use "_this", but just in axios, just "this" will be OK
                    */
                    method: "post",
                    url: "http://localhost:8080/JavaWeb_last/brand/selectByPageWithCondition?currentPage="+this.currentPage+"&pageSize="+this.pageSize,
                    data:this.brand
                }).then(resp => {
                    //data for table
                    this.tableData = resp.data.rowsInPage;//{ rowsInPage : [], totalCount : int }
                    this.totalCount = resp.data.totalCount;
                })

            },

            //分页
            handleSizeChange(val) {
                // console.log(`每页 ${val} 条`);

                //重新设置当每页显示的条数
                this.pageSize=val;
                this.queryAll();
            },
            handleCurrentChange(val) {
                // console.log(`当前页: ${val}`);

                //重新设置当前页码
                this.currentPage=val;
                this.queryAll();

            },

            /* change the color of every row*/
            tableRowClassName({row, rowIndex}) {
                if ((rowIndex - 1) % 4 === 0) {
                    return 'warning-row';
                } else if ((rowIndex - 3) % 4 === 0) {
                    return 'success-row';
                }
                return '';
            },
            /*multi selection be selected , do this method*/
            handleSelectionChange(val) {
                this.multipleSelection = val;
                /*output the multiple selection see how it is, on browser F12 page*/
                //console.log(this.multipleSelection)//you can see it is an array []
            },
            /*for search form, click submit button, see output on browser F12 page */
            onSubmit() {
                // console.log(this.brand);
                this.queryAll()
            },

            addBrand() {
                // console.log(this.brand)
                // var _this = this
                axios({
                    method: "post",
                    url: "http://localhost:8080/JavaWeb_last/brand/add",
                    data: this.brand
                }).then(resp => {
                    if (resp.data === "bingo") {
                        //close dialog box
                        this.dialogVisible = false
                        //reload the page
                        this.queryAll()

                        //msg pop box

                        this.$message({
                            message: 'Congrats, addition succeed.',
                            type: 'success'
                        });
                    }
                })
            },

            startEdit(row) {
                // 获取改行已经有的数据,以供填入修改框
                // var _this = this

                this.brandEdition = JSON.parse(JSON.stringify(row));
                // 弹出修改框
                this.editDialogVisible = true;
            },
            confirmEdit() {
                // var _this = this
                //axios transit ajax request
                axios({
                    method: "post",
                    url: "http://localhost:8080/JavaWeb_last/brand/update",
                    data: this.brandEdition
                }).then(resp =>  {
                    if (resp.data === "bingo") {
                        this.editDialogVisible = false
                        this.queryAll()
                        this.$message({
                            message: 'Congrats, edition succeed.',
                            type: 'success'
                        });
                    }
                })
            },
            cancelEdit() {
                this.editDialogVisible = false
                this.queryAll()
            },

            deleteById(row) {
                //get data from row
                this.brand.id = row.id
                //pop up confirm dialog
                this.$confirm('此操作将删除该数据, 是否继续?', '提示', {
                    confirmButtonText: 'Confirm',
                    cancelButtonText: 'Cancel',
                    type: 'warning'
                }).then(() => {
                    //when confirm clicked
                    //axios transit ajax request
                    axios({
                        method: "get",
                        url: "http://localhost:8080/JavaWeb_last/brand/deleteById?id=" + this.brand.id
                    }).then(resp => {
                        if (resp.data === "bingo") {
                            //remove OK
                            //reload page, but if we reload the page, the success msg has no time display
                            // location.reload();
                            this.queryAll();
                            //pop up OK msg
                            this.$message({
                                message: 'Congrats, deletion succeed.',
                                type: 'success'
                            });
                        }
                    })
                }).catch(() => {
                    //when cancel clicked
                    this.$message({
                        type: 'info',
                        message: 'Deletion stop'
                    });
                })

            },
            //delete many brands
            deleteByIds(){
                //1.get a int[] include ids from multipleSelection
                for (let i = 0; i < this.multipleSelection.length; i++) {
                    let selectedOne = this.multipleSelection[i];
                    this.selectedIds[i] = selectedOne.id
                }
                //2.transit request async by ajax by axios
                if (this.selectedIds != null && this.selectedIds.length > 0){

                    this.$confirm('此操作将删除多条数据, 是否继续?', '提示', {
                        confirmButtonText: 'Confirm',
                        cancelButtonText: 'Cancel',
                        type: 'warning'
                    }).then(() => {
                        //when confirm clicked
                        //axios transit ajax request
                        axios({
                            method: "post",
                            url: "http://localhost:8080/JavaWeb_last/brand/deleteByIds",
                            data:this.selectedIds
                        }).then(resp => {
                            if (resp.data === "bingo") {
                                //remove OK
                                //reload page, but if we reload the page, the success msg has no time display
                                // location.reload();
                                this.queryAll();
                                //pop up OK msg
                                this.$message({
                                    message: 'Congrats, multiple deletion succeed.',
                                    type: 'success'
                                });
                            }
                        })
                    }).catch(() => {
                        //when cancel clicked
                        this.$message({
                            type: 'info',
                            message: 'Deletion stop'
                        });
                    })

                } else {
                    this.$message({
                        type: 'warning',
                        message: 'Incorrect operation'
                    });
                }

            },

        },

        data() {
            return {
                /*for pagination ,here are all initial value*/
                currentPage: 1,
                totalCount : 60,
                pageSize : 10,

                /*for pop add new dialog form, we put this data model here it disappears smoothly*/
                dialogVisible: false,

                /*for pop edit brand dialog, we put this data model here it disappears smoothly*/
                editDialogVisible: false,

                /*selected by multiple selection box*/
                selectedIds:[],

                /*for search form data, and for form in dialog*/
                brand: {
                    id: '',
                    brandName: '',
                    companyName: '',
                    ordered: '',
                    description: '',
                    status: ''
                },

                brandEdition:{
                    id: '',
                    brandName: '',
                    companyName: '',
                    ordered: '',
                    description: '',
                    status: ''
                },

                /*for multi selection box */
                multipleSelection:[],

                tableData:  []
                /*{
                    brandName: 'IDEA',
                    companyName: 'JetBrain',
                    ordered: 'No. 189',
                    status: '1'
                }, {
                    brandName: 'IDEA',
                    companyName: 'JetBrain',
                    ordered: 'No. 189',
                    status: '1'
                }, {
                    brandName: 'IDEA',
                    companyName: 'JetBrain',
                    ordered: 'No. 189',
                    status: '1'
                }, {
                    brandName: 'IDEA',
                    companyName: 'JetBrain',
                    ordered: 'No. 189',
                    status: '1'
                }*/

            }
        }

    })

</script>

</body>
</html>

回顾一下这一页的最终效果
请添加图片描述

文章目录


接下来稍微贴一下各个功能的效果展示
(一)首先网页加载本身就会查询一次数据库,获得显示数据请添加图片描述
(二)添加功能
对话框忘了截图,和编辑功能差不多,但不会有既定数据
请添加图片描述

请添加图片描述
(三)编辑功能
请添加图片描述
请添加图片描述
(四)单个删除
还没能做到提示框显示删除条目名称
请添加图片描述
(五)批量删除
请添加图片描述
请添加图片描述
请添加图片描述
一个未选时误触批量删除
请添加图片描述
(六)实现自由分页功能,控制台输出的代码后来注释掉了
请添加图片描述
(七)最后的条件查询,自由输入单个或多个条件,但是没解决状态选择后还原到未选中的功能,只能刷新页面

请添加图片描述
请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值