图书系统小案例

目前就实现了分页查询,修改,删除功能

这个小案例练习到了很多技能,比如前后端交互、异步请求、三层架构思想、后端连接数据库、配置文件、基础业务crud等等

感兴趣的小伙伴可以去做一个试试

准备工作

1、使用maven构建一个web工程

打开idea软件点击new project

选中构建为web项目

设置工程名字为book-code,设置工程路径位置

设置自己maven的地址,跟maven仓库的地址(可能会跟我不一样)

然后点击Finish创建工程

如果一切顺利的话会生成下面这些目录

没有生成也不要紧,咱可以自己手动生成(成功可以跳过1~16步,从17步开始看)

  1. 首先你应该会有应该下面的这些基本文件

  2. 右击你的工程名称,也就是book-code

  3. 然后鼠标移动到第一个new,右边会继续显示选择项,然后点击directory,创建目录

  4. 然后会显示一个弹框,让你建目录

  5. 然后把弹框里面,下面的四个目录都选中(可以按住ctrl键然后鼠标一个个点)

  6. 然后按回车,左边目录就会帮你生成缺的目录

  7. 鼠标移到main目录下,右击选择new,然后再选择directory,创建目录

  8. 在弹出的框里写webapp,回车,创建目录

  9. 然后在webapp目录里面再创建两个目录,分别是js跟WEB-INF

  10. 然后在js目录里放jquery.js文件(这个文件可以直接从网上找)

  11. 然后右击WEB-INF目录,选择文件file

  12. 然后创建一个web.xml文件

  13. 把下面的内容复制到web.xml文件里

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app
        version="4.0"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
      <display-name>book-code</display-name>
    </web-app>

    像这个样子

  14. 然后右击webapp目录新建一个jsp文件

  15. 创建一个index的jsp主页面

  16. 创建完成后是这个样子的

  17. 然后在body标签中间写以下内容

    <h1>hello</h1>

2、测试web工程是否能正常运行

创建一个tomcat

  1. 点击add configuration

  1. 会弹出如下的框

  1. 然后点击左上角的+

  1. 然后在弹出的菜单滚动到tomc server这,然后选中local创建tomcat

  1. 然后会弹出如下界面,接着把name改为book-name

  1. 然后选中deployment,点击左上角的+,再点artifact

  1. 然后默认选择第一个就好,然后点ok

  1. 然后滚轮滚到最下面,把application context里的内容改为一个\

  1. 然后点apply,再点ok就好了

  1. 点完后的界面应该如下

  1. 然后点上面的绿色的小三角,来测试web工程是否正常运行

  1. 如果成功进入浏览器,界面输出了hello那就是成功啦

3、补全web工程的各个目录

现在补全的是最基本的目录

4、添加依赖

  1. 首先再modelVersion标签下面添加一行packaging标签

    <packaging>war</packaging>
  1. 然后再下图位置的地方把下面文本里的内容复制进去

    <dependencies>
            <!-- servlet -->
            <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!-- jsp -->
            <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.1</version>
                <scope>provided</scope>
            </dependency>
            <!-- jstl -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.19</version>
            </dependency>
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.1</version>
            </dependency>
            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
                <scope>provided</scope>
            </dependency>
            <!-- 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>5.2.0</version>
            </dependency>
            <!-- fastjaon -->
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.73</version>
            </dependency>
            <!-- junit测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    ​
        <build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
    ​
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
  1. 然后点右边蓝色的m,pom.xml里的依赖就配置好了

5、添加配置文件

  1. 右击resources目录,新建一个resources bundle

  1. 然后名字叫db,点ok

  1. 然后会打开dp.properties

  1. 把下面文本内容复制到dp.properties

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://127.0.0.1:3306/bank?useUnicode=true&serverTimezone=UTC
    jdbc.username=root
    jdbc.password=123456
  1. 然后再右击resources目录,新建文件

  1. 建一个mybatis-config.xml文件

  1. 然后把下面的文本复制到mybatis-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>
        <!-- 导入properties文件 -->
        <properties resource="db.properties"/>
        <settings>
            <!-- 开启Mybatis的日志功能-->
            <setting name="logImpl" value="STDOUT_LOGGING"/>
            <!-- 开启驼峰命名规则 -->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
            <!-- 一级缓存 -->
            <setting name="localCacheScope" value="SESSION"/>
        </settings>
        <typeAliases>
            <!-- 扫描包下所有类,自动映射 -->
            <package name="com.bk.pojo"/>
        </typeAliases>
        <!-- 分页插件 -->
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
        </plugins>
        <!-- 数据库的环境 -->
        <environments default="dev">
            <environment id="dev">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"/>
                    <property name="url" value="${jdbc.url}"/>
                    <property name="username" value="${jdbc.username}"/>
                    <property name="password" value="${jdbc.password}"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
    <!--        <mapper resource="com/cwb/mapper/StudentMapper.xml"/>-->
            <package name="com.bk.mapper"/>
        </mappers>
    </configuration>

准备工作就结束啦,可以愉快的敲代码了

敲代码阶段

基础代码

  1. 右击pojo目录建一个class类

  1. 建一个book实体类

  1. 然后把参考下面的代码写到你自己的代码里(你也可以全选我的代码替换你的所有代码)

    package com.bk.pojo;
    ​
    import lombok.AllArgsConstructor;
    import lombok.Data;
    ​
    import java.io.Serializable;
    ​
    /**
     * @Author 27435
     * @Date 2024/11/1116:57
     * @Version 1.0
     */
    @Data
    @AllArgsConstructor
    public class Book implements Serializable {
        private Integer id; // 编号
        private String name; // 名字
        private String author; // 作者
        private Float price; // 价格
        private Integer typeId; // 类型编号
    ​
        public Book(String name, String author, Float price, Integer typeId) {
            this.name = name;
            this.author = author;
            this.price = price;
            this.typeId = typeId;
        }
    ​
        public Book() {
        }
    }
    ​
    1. 接着右击utils目录建一个类,类名为MybatisUtils,然后把参考下面的代码写到你自己的代码里(你也可以全选我的代码替换你的所有代码)

      package com.bk.utils;
      ​
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
      ​
      import java.io.InputStream;
      ​
      /**
       * @Author 27435
       * @Date 2024/11/2017:20
       * @Version 1.0
       */
      ​
      /**
       * Mybatis工具类,用于提供SqlSessionFactory和SqlSession对象
       */
      public class MybatisUtils {
      ​
          // SqlSessionFactory对象,用于生成SqlSession
          private static SqlSessionFactory factory = null;
      ​
          // 静态代码块,用于初始化SqlSessionFactory
          static {
      ​
              // 读取MyBatis配置文件
              InputStream is = MybatisUtils.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
              // 使用SqlSessionFactoryBuilder构建SqlSessionFactory
              factory = new SqlSessionFactoryBuilder().build(is);
      ​
          }
      ​
          /**
           * 获取SqlSession对象
           *
           * @return SqlSession对象,用于执行SQL语句
           */
          public static SqlSession getSqlSession(){
              SqlSession sqlSession = null;
              if (factory != null){
                  // 自动提交事务为true,打开SqlSession
                  sqlSession = factory.openSession(true);
              }
              return sqlSession;
          }
      ​
      }

mapper层

编写数据访问层

package com.bk.mapper;
​
import com.bk.pojo.Book;
import org.apache.ibatis.annotations.Param;
​
import java.util.List;
​
/**
 * @Author 27435
 * @Date 2024/11/2015:31
 * @Version 1.0
 */
​
public interface BookMapper {
​
    /**
     * 查询所有的图书
     * @return
     */
    List<Book> selectBooks();
​
    /**
     * 根据id删除图书
     * @param id
     * @return
     */
    int deleteBookById(@Param("id") int id);
​
    /**
     * 根据id查询图书
     * @param id
     * @return
     */
    Book selectBookById(@Param("id") int id);
​
    /**
     * 更新图书
     * @param book
     * @return
     */
    int updateBookById(Book book);
}

编写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="com.bk.mapper.BookMapper">
    <!-- 启用二级缓存 -->
    <cache/>
    <resultMap id="book" type="com.bk.pojo.Book">
        <id property="id" column="book_id" />
        <result property="name" column="book_name" />
        <result property="author" column="book_author" />
        <result property="price" column="book_price" />
        <result property="typeId" column="book_type" />
    </resultMap>
​
    <update id="updateBookById">
        update book
        <set>
            <if test="name != null">
                book_name = #{name},
            </if>
            <if test="author != null">
                book_author = #{author},
            </if>
            <if test="price != null">
                book_price = #{price},
            </if>
            <if test="typeId != null">
                book_type = #{typeId},
            </if>
        </set>
        where book_id = #{id}
    </update>
​
    <delete id="deleteBookById">
        delete from book where book_id = #{id}
    </delete>
​
    <select id="selectBooks" resultMap="book">
        select * from book
    </select>
​
    <select id="selectBookById" resultMap="book">
        select * from book where book_id = #{id}
    </select>
​
</mapper>

service层

编写业务访问层的接口

package com.bk.service;
​
import com.bk.pojo.Book;
​
import java.util.List;
​
/**
 * @Author 27435
 * @Date 2024/11/2015:28
 * @Version 1.0
 */
​
​
public interface BookService {
​
    /**
     * 查询所有的图书
     * @return
     */
    List<Book> getBooks();
​
    /**
     * 根据id删除图书
     * @param id
     * @return
     */
    int deleteBookById(int id);
​
    /**
     * 根据id查询图书
     * @param id
     * @return
     */
    Book selectBookById(int id);
​
    /**
     * 更新图书
     * @param book
     * @return
     */
    int updateBookById(Book book);
​
}

编写实现类

package com.bk.service.impl;
​
import com.bk.mapper.BookMapper;
import com.bk.pojo.Book;
import com.bk.service.BookService;
import com.bk.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
​
import java.util.List;
​
/**
 * @Author 27435
 * @Date 2024/11/2015:29
 * @Version 1.0
 */
​
public class BookServiceImpl implements BookService {
​
    // 使用Mybatis工具类获取SqlSession,并从中获取BookMapper接口的实现
    private BookMapper mapper = MybatisUtils.getSqlSession().getMapper(BookMapper.class);
​
    /**
     * 查询所有的图书
     * @return
     */
    @Override
    public List<Book> getBooks() {
        // 调用数据访问层查询所有图书的方法
        return mapper.selectBooks();
    }
​
    /**
     * 根据id删除图书
     * @param id
     * @return
     */
    @Override
    public int deleteBookById(int id) {
        // 调用数据访问层删除图书的方法
        return mapper.deleteBookById(id);
    }
​
    /**
     * 根据id查询图书
     * @param id
     * @return
     */
    @Override
    public Book selectBookById(int id) {
        // 调用数据访问层根据id查询图书的方法
        return mapper.selectBookById(id);
    }
​
    /**
     * 更新图书
     * @param book
     * @return
     */
    @Override
    public int updateBookById(Book book) {
        // 调用数据访问层更新图书的方法
        return mapper.updateBookById(book);
    }
}

servlet层

编写查询所有图书的servlet类

package com.bk.servlet;
​
import com.alibaba.fastjson.JSON;
import com.bk.pojo.Book;
import com.bk.service.BookService;
import com.bk.service.impl.BookServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
​
/**
 * @Author 27435
 * @Date 2024/11/2015:16
 * @Version 1.0
 */
​
@WebServlet(urlPatterns = {"/books"})
public class BookServlet extends HttpServlet {
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码
        req.setCharacterEncoding("UTF-8");
        // 设置响应编码
        resp.setCharacterEncoding("UTF-8");
        // 设置响应类型
        resp.setContentType("application/json;charset=UTF-8");
        // 获取当前页码
        String pageNum = req.getParameter("pageNum");
        // 响应流
        PrintWriter out = resp.getWriter();
        // 设置分页参数
        PageHelper.startPage(Integer.valueOf(pageNum),3);
        // 调用业务层查询所有图书的方法
        BookService bookService = new BookServiceImpl();
        // 获取图书列表
        List<Book> books = bookService.getBooks();
        // 获取分页信息
        PageInfo<Book> pageInfo = new PageInfo<>(books);
        // 将数据转换为JSON格式
        String jsonString = JSON.toJSONString(pageInfo);
        // 输出JSON字符串到客户端
        out.print(jsonString);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
​
}

编写删除图书的servlet类

package com.bk.servlet;
​
import com.bk.service.BookService;
import com.bk.service.impl.BookServiceImpl;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.text.html.HTML;
import java.io.IOException;
import java.io.PrintWriter;
​
/**
 * @Author 27435
 * @Date 2024/11/2519:19
 * @Version 1.0
 */
​
@WebServlet(urlPatterns = {"/deleteBook"})
public class DeleteBookServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码
        req.setCharacterEncoding("UTF-8");
        // 设置响应编码
        resp.setCharacterEncoding("UTF-8");
        // 设置响应类型
        resp.setContentType("text/html;charset=UTF-8");
        // 获取要删除数据的id
        String id = req.getParameter("id");
        // 响应流
        PrintWriter out = resp.getWriter();
        // 调用业务层查询所有图书的方法
        BookService bookService = new BookServiceImpl();
        // 根据id删除图书
        int i = bookService.deleteBookById(Integer.valueOf(id));
        // 判断是否删除成功
        if (i > 0) {
            out.print("删除成功");
        }else {
            out.print("删除失败");
        }
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

编写根据id查询图书的servlet类

package com.bk.servlet;
​
import com.alibaba.fastjson.JSON;
import com.bk.pojo.Book;
import com.bk.service.BookService;
import com.bk.service.impl.BookServiceImpl;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
​
/**
 * @Author 27435
 * @Date 2024/11/2611:06
 * @Version 1.0
 */
​
@WebServlet(urlPatterns = {"/selectBookById"})
public class SelectBookByIdServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码
        req.setCharacterEncoding("UTF-8");
        // 设置响应编码
        resp.setCharacterEncoding("UTF-8");
        // 设置响应类型
        resp.setContentType("text/html;charset=UTF-8");
        // 获取要删除数据的id
        String id = req.getParameter("id");
        // 响应流
        PrintWriter out = resp.getWriter();
        // 调用业务层查询所有图书的方法
        BookService bookService = new BookServiceImpl();
        // 根据id查询图书
        Book book = bookService.selectBookById(Integer.valueOf(id));
        // 将数据转换为JSON格式
        String jsonString = JSON.toJSONString(book);
        // 输出JSON字符串到客户端
        out.print(jsonString);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

编写修改图书的servlet类

package com.bk.servlet;
​
import com.bk.pojo.Book;
import com.bk.service.BookService;
import com.bk.service.impl.BookServiceImpl;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
​
/**
 * @Author 27435
 * @Date 2024/11/2613:26
 * @Version 1.0
 */
​
@WebServlet(urlPatterns = {"/updateBook"})
public class UpdateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码
        req.setCharacterEncoding("UTF-8");
        // 设置响应编码
        resp.setCharacterEncoding("UTF-8");
        // 设置响应类型
        resp.setContentType("text/html;charset=UTF-8");
        // 响应流
        PrintWriter out = resp.getWriter();
        // 获取id
        String id = req.getParameter("id");
        // 获取name
        String name = req.getParameter("name");
        // 获取author
        String author = req.getParameter("author");
        // 获取price
        String price = req.getParameter("price");
        // 获取typeId
        String typeId = req.getParameter("typeId");
        // 实例化Book对象
        Book book = new Book(Integer.valueOf(id), name, author, Float.valueOf(price), Integer.valueOf(typeId));
        // 调用业务层查询所有图书的方法
        BookService bookService = new BookServiceImpl();
        // 根据id修改图书
        int i = bookService.updateBookById(book);
        // 判断是否修改成功
        if (i > 0) {
            out.print("修改成功");
        }else {
            out.print("修改失败");
        }
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

index页面编码

编写主页面代码

<%--
  Created by IntelliJ IDEA.
  User: 27435
  Date: 2024/11/20
  Time: 15:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
    <!-- 引入 Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        table, th, tr, td {
            padding: 0; /*内边距*/
            margin: 0; /*外边距*/
            border: solid 1px #ccc; /*边框*/
        }
        table {
            width: 800px; /*宽*/
            margin: 50px auto; /*外边距*/
            /*border-collapse: collapse;*/ /*合并边框*/
        }
        td, th {
            text-align: center; /*文字居中*/
        }
        .pages {
            width: 800px; /*宽*/
            height: 40px; /*高*/
            line-height: 40px; /*行高*/
            margin: 0 auto; /*外边距*/
            text-align: center; /*文字居中*/
        }
        .pages a {
            margin-right: 15px; /*右外边距*/
        }
        .pages .active {
            color: red; /*字体颜色*/
        }
    </style>
</head>
<body>
    <table>
        <tr>
            <th>编号</th>
            <th>名称</th>
            <th>作者</th>
            <th>价格</th>
            <th>类型</th>
            <th>操作</th>
        </tr>
        <tbody id="bookList">
​
        </tbody>
    </table>
    <div class="pages">
​
    </div>
​
    <!-- 模态框 -->
    <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">修改</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form>
                        <div class="mb-3">
                            <label for="id" class="form-label">编号</label>
                            <input type="text" class="form-control" id="id" name="id">
                        </div>
                        <div class="mb-3">
                            <label for="name" class="form-label">名称</label>
                            <input type="text" class="form-control" id="name" name="name">
                        </div>
                        <div class="mb-3">
                            <label for="author" class="form-label">作者</label>
                            <input type="text" class="form-control" id="author" name="author">
                        </div>
                        <div class="mb-3">
                            <label for="price" class="form-label">价格</label>
                            <input type="text" class="form-control" id="price" name="price">
                        </div>
                        <div class="mb-3">
                            <label for="typeId" class="form-label">类型</label>
                            <input type="text" class="form-control" id="typeId" name="typeId">
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
                    <button type="button" class="btn btn-primary">保存修改</button>
                </div>
            </div>
        </div>
    </div>
​
    <!-- 引入 Bootstrap JS 和 Popper.js -->
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js"></script>
    <script src="js/jquery.js"></script>
    <script>
        var pageNum = 1; // 当前页码
​
        // 渲染列表
        function createBookList(books){
            $("#bookList").empty(); // 清空tbody
            $.each(books,function (index,book){ // 遍历books
                var tr = $("<tr></tr>"); // 创建一行
​
                var idTd = $("<td></td>"); // 创建一列
                idTd.text(book.id); // 将book对象的编号写入td中
                tr.append(idTd); // 将idTd追加到tr中
​
                var nameTd = $("<td></td>"); // 创建一列
                nameTd.text(book.name); // 将book对象的名称写入td中
                tr.append(nameTd); // 将nameTd追加到tr中
​
                var authorTd = $("<td></td>"); // 创建一列
                authorTd.text(book.author); // 将book对象的作者写入td中
                tr.append(authorTd); // 将authorTd追加到tr中
​
                var priceTd = $("<td></td>"); // 创建一列
                priceTd.text(book.price); // 将book对象的价格写入td中
                tr.append(priceTd); // 将priceTd追加到tr中
​
                var typeTd = $("<td></td>"); // 创建一列
                typeTd.text(book.typeId); // 将book对象的类别写入td中
                tr.append(typeTd); // 将typeTd追加到tr中
​
                var actionTd = $("<td></td>"); // 创建一列
                var updateBtn = $("<input/>") // 创建修改按钮
                var delBtn = $("<input/>") // 创建删除按钮
                updateBtn.attr("type","button").attr("value","修改").attr("class","up_btn")
                         .attr("data-bs-toggle","modal").attr("data-bs-target","#exampleModal"); // 设置修改按钮的属性
                delBtn.attr("type","button").attr("value","删除").attr("class","del_btn"); // 设置删除按钮的属性
                actionTd.append(updateBtn) // 将修改按钮追加到actionTd中
                actionTd.append(delBtn) // 将删除按钮追加到actionTd中
                tr.append(actionTd); // 将actionTd追加到tr中
​
                // 将这一行追加到tbody中
                $("#bookList").append(tr);
            })
        }
​
        // 渲染分页
        function createPages(data){
            // data 就是分页信息对象
            $(".pages").empty(); // 清空分页
​
            // 检查是否有上一页
            if (data.hasPreviousPage) { // 如果有上一页
                // 创建上一页链接元素
                var pre_a = $("<a>上一页</a>")
                // 设置链接的默认行为是跳转到当前页面
                pre_a.attr("href", "#")
                // 为上一页链接添加类名,用于CSS样式定制
                pre_a.attr("class", "pre")
                // 将上一页链接添加到页面的.pages容器中
                $(".pages").append(pre_a)
            }
​
            // 遍历页面编号数组,生成分页链接
            $.each(data.navigatepageNums, function (index,num){
                // 创建一个新的<a>元素
                var a = $("<a></a>")
                // 设置链接默认属性
                a.attr("href", "#")
                // 根据当前页面编号设置链接的样式
                if (num == data.pageNum) {
                    // 如果是当前页面,则添加 active 类以红色显示
                    a.attr("class", "active a1")
                }else {
                    // 否则,仅添加 a1 类
                    a.attr("class", "a1")
                }
                // 设置链接文本为页面编号
                a.text(num)
                // 将生成的链接添加到 .pages 容器中
                $(".pages").append(a)
            })
​
            // 检查是否存在下一页
            if (data.hasNextPage) { // 如果有下一页
                // 创建下一页的链接元素
                var next_a = $("<a>下一页</a>")
                // 设置链接的默认行为是跳转到当前页面
                next_a.attr("href", "#")
                // 为下一页添加类名,用于CSS样式定制
                next_a.attr("class", "next")
                // 将下一页链接添加到页面的.pages容器中
                $(".pages").append(next_a)
            }
        }
​
        // 为类名为"pages"的元素内部的".a1"类元素添加点击事件监听器
        $(".pages").on("click", ".a1", function (even){
            // 阻止默认事件行为,防止页面刷新或跳转
            even.preventDefault();
            // 将点击的元素的文本内容转换为整数并赋值给pageNum变量
            pageNum = parseInt($(this).text());
            // console.log("当前页" + pageNum)
            // 调用getBooks方法,传入当前页码,刷新数据
            getBooks(pageNum)
        })
​
        // 上一页
        // 为类名为"pages"的元素绑定点击事件,事件针对的是类名为"pre"的子元素
        $(".pages").on("click", ".pre", function (even){
            // 阻止默认事件行为,防止页面刷新或跳转
            even.preventDefault();
            // 减少当前页码值,实现翻页到上一页,并把值赋给pageNum变量
            pageNum = pageNum - 1;
            // console.log(pageNum)
            // 调用getBooks方法,传入当前页码,刷新数据
            getBooks(pageNum)
            // getBooks($(this).attr("pre"))
        })
​
        // 下一页
        // 为类名为"pages"的元素绑定点击事件,事件针对的是类名为"next"的子元素
        $(".pages").on("click", ".next", function (even){
            // 阻止默认事件行为,防止页面刷新或跳转
            even.preventDefault();
            // 增加当前页码值,实现翻页到下一页,并把值赋给pageNum变量
            pageNum = pageNum + 1;
            // console.log("下一页" + pageNum)
            // 调用getBooks方法,传入当前页码,刷新数据
            getBooks(pageNum)
            // getBooks($(this).attr("next"))
        })
​
        // 删除数据
        $("#bookList").on("click", ".del_btn", function (even){
            // 阻止默认事件行为
            even.preventDefault();
            // 弹出确认框
            var r = confirm("确定删除吗?")
            // 如果用户取消删除,则不执行后续操作
            if (!r) {
                return;
            }
            // 获取当前点击的删除按钮所在行的第一个子元素(即书籍ID)
            var id = $(this).parent().parent().children(":first").text();
            console.log(id)
            // 调用deleteBookById函数删除指定ID的书籍
            deleteBookById(id);
        })
​
        // 点击修改按钮,弹出修改框
        $("#bookList").on("click", ".up_btn", function (even){
            // 阻止默认事件行为
            even.preventDefault();
            var id = $(this).parent().parent().children(":first").text();
            // 根据id查询对应的数据,并把数据用bootstrap模态框的形式弹出来,供用户修改,用ajax向servlet请求数据
            $.ajax({
                url: "selectBookById", // 请求的url
                type: "get", // 请求的方式
                dataType: "json", // 预计从服务器返回的数据
                data: "id=" + id, // 发给服务器的数据(id信息)
                success: function (data){
                    // 弹出模态框
                    // 把数据回显到模态框
                    $("#id").val(data.id);
                    $("#name").val(data.name);
                    $("#author").val(data.author);
                    $("#price").val(data.price);
                    $("#typeId").val(data.typeId);
                }
            })
        })
​
        // 点击按钮进行数据修改,提交数据到servlet,用ajax提交
        $(".btn-primary").click(function (){
            var id = $("#id").val(); // 编号
            var name = $("#name").val(); // 名字
            var author = $("#author").val(); // 作者
            var price = $("#price").val(); // 价格
            var typeId = $("#typeId").val(); // 类型
            // 关闭模态款
            $("#exampleModal").modal("hide")
            $.ajax({
                url: "updateBook", // 请求的url
                type: "post", // 请求的方式
                dataType: "text", // 预计从服务器返回的数据
                data: "id=" + id + "&name=" + name + "&author=" + author + "&price=" + price + "&typeId=" + typeId, // 发给服务器的数据
                success: function (row){
                    // 提示用户
                    alert(row)
                    // 刷新数据
                    getBooks(pageNum)
                }
            })
        })
​
​
        /**
         * 根据id删除图书
         * @param id
         */
        function deleteBookById(id){
            $.ajax({
                url: "deleteBook", // 请求的url
                type: "get", // 请求的方式
                dataType: "text", // 预计从服务器返回的数据
                data: "id=" + id, // 发给服务器的数据(id信息)
                success: function (row){
                    alert(row) // 提示用户
                    getBooks(pageNum) // 刷新数据
​
                    // 检查当前页是否为空
                    var books = $("#bookList tr"); // 获取当前页的所有行元素
                    if (books.length === 1 && pageNum > 1) {
                        getBooks(pageNum - 1); // 如果当前页为空且不是第一页,则跳转到前一页
                    }
                }
            })
        }
​
        /**
         * 根据页码获取图书列表
         * @param pageNum
         */
        function getBooks(pageNum){
            $.ajax({
                url: "books", // 请求的url
                type: "get", // 请求的方式
                dataType: "JSON", // 预计从服务器返回的数据
                data: "pageNum=" + pageNum, // 发给服务器的数据(页码信息)
                success: function (data){ // 请求成功执行的回调函数
                    // console.log(data)
                    pageNum = data.pageNum; // 更新当前页码
                    createBookList(data.list) // 创建图书列表
                    createPages(data) // 创建分页信息
                }
            })
        }
​
        // 当文档加载完成后,执行以下函数
        $(function (){
            // 调用getBooks方法,传入当前页码,初始化页面数据
            getBooks(pageNum)
        })
    </script>
</body>
</html>

到此就可以运行代码继续测试

这是运行的效果,所有源码再gitee仓库:book-CRUD-demo: 这是一个类似于图书系统的小项目,对图书进行增删改查大家可以去下载看看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/924213.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

延时系统建模,整数延时与分数延时,连续传函与离散传函,Pade近似与Thiran近似,Matlab实现

连续传递函数 严格建模&#xff1a;指数形式 根据拉普拉斯变换的性质&#xff0c; [ f ( t ) ↔ F ( s ) ] ⇔ [ f ( t − t 0 ) ↔ e − s t 0 F ( s ) ] \left[ {f\left( t \right) \leftrightarrow F\left( s \right)} \right] \Leftrightarrow \left[ {f\left( {t - {t_0…

3.14MayBeSomeStack

栈指针是sp 静态数据在内存中位置不改变 码距就是相邻两个合法的数据之间的差距&#xff0c;如果为2的话&#xff0c;相邻两个合法的数据之间存在一个冗余的数据&#xff0c;这个数据肯定是出错的&#xff0c;但是无法判断是哪个合法的数产生的&#xff1b; 如果码距是3的话&…

NLP 2、机器学习简介

人生的苦难不过伏尔加河上的纤夫 —— 24.11.27 一、机器学习起源 机器学习的本质 —— 找规律 通过一定量的训练样本找到这些数据样本中所蕴含的规律 规律愈发复杂&#xff0c;机器学习就是在其中找到这些的规律&#xff0c;挖掘规律建立一个公式&#xff0c;导致对陌生的数…

springboot视频网站系统的设计与实现(代码+数据库+LW)

摘 要 使用旧方法对视频信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在视频信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的视频网站系统管理员功…

探索Python网页解析新纪元:requests-html库揭秘

文章目录 **探索Python网页解析新纪元&#xff1a;requests-html库揭秘**1. 背景介绍&#xff1a;为何选择requests-html&#xff1f;2. requests-html库是什么&#xff1f;3. 如何安装requests-html库&#xff1f;4. 五个简单的库函数使用方法4.1 发起HTTP请求4.2 解析HTML内容…

DataWhale—PumpkinBook(TASK05决策树)

课程开源地址及相关视频链接&#xff1a;&#xff08;当然这里也希望大家支持一下正版西瓜书和南瓜书图书&#xff0c;支持文睿、秦州等等致力于开源生态建设的大佬✿✿ヽ(▽)ノ✿&#xff09; Datawhale-学用 AI,从此开始 【吃瓜教程】《机器学习公式详解》&#xff08;南瓜…

爱尔兰杀菌剂数据分析_1

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

捉虫笔记(七)-再探谁把系统卡住了

捉虫笔记&#xff08;七&#xff09;-再探谁把系统卡住 1、内核调试 在实体物理机上&#xff0c;内核调试的第一个门槛就是如何建立调试链接。 这里我选择的建立网络连接进行内核调试。 至于如何建立网络连接后续文章再和大家分享。 2、如何分析 在上一篇文章中&#xff0c;我们…

linux(redhat8)如何安装mysql8.0之rpmtar双版本(最新版)(内网)(离线)

一.环境 系统版本&#xff1a;Red Hat 8.5.0-20 Java环境&#xff1a;build 1.8.0_181-b13 MYSQL&#xff1a;8.x版本 二、查看内核版本 #查看内核版本&#xff0c;根据内核版本下载对应的安装包 cat /proc/version 三、安装方式 一、rpm包方式 一、下载安装包 1. 登录网…

【WRF后处理】WRF模拟效果评价及可视化:MB、RMSE、IOA、R

【WRF后处理】模拟效果评价及可视化 准备工作模型评价指标Python实现代码Python处理代码:导入站点及WRF模拟结果可视化图形及评价指标参考在气象和环境建模中(如使用 WRF 模型进行模拟),模型性能评价指标是用于定量评估模拟值与观测值之间偏差和拟合程度的重要工具。 本博客…

深度学习基础2

目录 1.损失函数 1.1 线性回归损失函数 1.1.1 MAE损失 1.1.2 MSE损失 1.1.3 SmoothL1Loss 1.2 CrossEntropyLoss 1.3 BCELoss 1.4. 总结 2.BP算法 2.1 前向传播 2.2 反向传播 2.2.1 原理 2.2.2. 链式法则 2.4 重要性 2.5 案例 2.5.1 数据准备 2.5.2 神经元计算…

STM32的CAN波特率计算

公式&#xff1a; CAN波特率 APB总线频率 / &#xff08;BRP分频器 1&#xff09;/ (SWJ BS1 BS2) SWJ一般为1。 例如STM32F407的&#xff0c;CAN1和CAN2都在在APB1下&#xff0c;频率是42000000 如果想配置成1M波特率&#xff0c;则计算公式为&#xff1a;

⭐ Unity 资源管理解决方案:Addressable_ Demo演示

一、使用Addressable插件的好处&#xff1a; 1.自动管理依赖关系 2.方便资源卸载 3.自带整合好的资源管理界面 4.支持远程资源加载和热更新 二、使用步骤 安装组件 1.创建资源分组 2.将资源加入资源组 3.打包资源 4.加载资源 三种方式可以加载 using System.Collections…

uniapp实现APP版本升级

App.vue 直接上代码 <script>export default {methods: {//APP 版本升级Urlupload() {// #ifdef APP-PLUSplus.runtime.getProperty(plus.runtime.appid, (info) > {// 版本号变量持久化存储getApp().globalData.version info.version;this.ToLoadUpdate(info.versi…

spark 写入mysql 中文数据 显示?? 或者 乱码

目录 前言 Spark报错&#xff1a; 解决办法&#xff1a; 总结一下&#xff1a; 报错&#xff1a; 解决&#xff1a; 前言 用spark写入mysql中&#xff0c;查看中文数据 显示?? 或者 乱码 Spark报错&#xff1a; Sat Nov 23 19:15:59 CST 2024 WARN: Establishing SSL…

欧科云链研究院:比特币还能“燃”多久?

出品&#xff5c; OKG Research 作者&#xff5c;Hedy Bi 本周二&#xff0c;隔夜“特朗普交易” 的逆转趋势波及到比特币市场。比特币价格一度冲高至约99,000美元后迅速回落至93,000美元以下&#xff0c;最大跌幅超6%。这是由于有关以色列和黎巴嫩有望达成停火协议的传闻引发…

27加餐篇:gRPC框架的优势与不足之处

gRPC作为一个现代的、开源的远程过程调用(RPC)框架,在多个方面都展现了其优雅之处,同时也存在一些不足之处。这篇文章我们就相对全面的分析一下gRPC框架那些优雅的地方和不足的地方。 优雅的地方 gRPC作为一个RPC框架,在编码、传输协议已经支持多语言方面都比较高效,下…

Spring MVC练习(前后端分离开发实例)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:二十五弦弹夜月&#xff0c;不胜清怨却飞来&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

重构项目架构

前言 我们上篇文章对整个项目进行一个整体的规划&#xff0c;其中对于APP类规划了类&#xff0c;本篇文章我们就来实现这个规划&#xff1b; class App {//加载页面constructor() {}//获取位置_getPosition() {}//接受位置_loadMap() {}//在地图上点击展现表单_showForm() {}/…

哈希C++

文章目录 一.哈希的概念1.直接定址法2.负载因子 二.哈希函数1.除法散列法 / 除留余数法2.乘法散列法3.全域散列法&#xff08;了解&#xff09; 三.处理哈希冲突哈希冲突&#xff1a;1.开放定址法&#xff08;1&#xff09;线性探测&#xff1a;&#xff08;2&#xff09;二次探…