图书系统小案例

news2024/11/28 11:58:12

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

这个小案例练习到了很多技能,比如前后端交互、异步请求、三层架构思想、后端连接数据库、配置文件、基础业务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: 这是一个类似于图书系统的小项目,对图书进行增删改查大家可以去下载看看

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度理解进程的概念(Linux)

目录 一、冯诺依曼体系 二、操作系统(OS) 设计操作系统的目的 核心功能 系统调用 三、进程的概念与基本操作 简介 查看进程 通过系统调用获取进程标识符 通过系统调用创建进程——fork() 四、进程的状态 操作系统中的运行、阻塞和挂起 理解linux内核链表 Linux的进…

自媒体图文视频自动生成软件|03| 页面和结构介绍

代码获取方式在文本末尾&#x1f51a; *代码获取方式在文本末尾&#x1f51a; *代码获取方式在文本末尾&#x1f51a; *代码获取方式在文本末尾&#x1f51a; 视频图片生成器 一个基于 Python 和 Web 的工具&#xff0c;用于生成带有文字和语音的视频以及图片。支持多种尺寸、…

STM32的一些知识技巧

STM32的一些知识技巧 STM32命名规则 查看代码编译所占用的flash和SRAM的大小 单位为字节&#xff08;Byte&#xff09; 1、使用keil编译结果进行计算 2、查看.map文件 STM32启动模式 主闪存启动地址为0x08000000 查看程序段/函数执行时间 global.prop文件 保存字体配置&…

我们来学mysql -- EXPLAIN之rows(原理篇)

EXPLAIN之rows 题记rows 题记 书接上文《 EXPLAIN之ref》2024美国大选已定&#xff0c;川普剑登上铁王座&#xff0c;在此过程中出谋划策的幕僚很重要&#xff0c;是他们决定了最终的执行计划在《查询成本之索引选择》中提到&#xff0c;explain的输出&#xff0c;就是优化器&…

【AI系统】昇腾 AI 核心单元

昇腾 AI 核心单元 本文将深入介绍昇腾 AI 处理器的核心单元——AI Core&#xff0c;以及其背后的达芬奇架构。昇腾 AI 处理器是华为针对 AI 领域设计的专用处理器&#xff0c;其核心 AI Core 采用了特定域架构&#xff08;Domain Specific Architecture&#xff0c;DSA&#x…

Hadoop生态圈框架部署(九)- Hive部署

文章目录 前言一、Hive部署&#xff08;手动部署&#xff09;下载Hive1. 上传安装包2. 解压Hive安装包2.1 解压2.2 重命名2.3 解决guava冲突 3. 配置Hive3.1 配置Hive环境变量3.2 修改 hive-site.xml 配置文件3.3 配置MySQL驱动包3.3.1 下在MySQL驱动包3.3.2 上传MySQL驱动包3.…

RHCE——SELinux

SELinux 什么是SELinux呢&#xff1f;其实它是【Security-Enhanced Linux】的英文缩写&#xff0c;字母上的意思就是安全强化Linux的意思。 SELinux是由美国国家安全局(NSA)开发的&#xff0c;当初开发的原因是很多企业发现&#xff0c;系统出现问题的原因大部分都在于【内部…

Vue3的通灵之术Teleport

前言 近期Vue3更新了一些新的内容&#xff0c;我都还没有一个一个仔细去看&#xff0c;但是还是有必要去解读一下新内容的。就先从Teleport 开始吧。 官方对 Teleport 的解释是&#xff1a;<Teleport> 是一个内置组件&#xff0c;它可以将一个组件内部的一部分模板“传…

介绍一下atof(arr);(c基础)

hi , I am 36 适合对象c语言初学者 atof(arr)&#xff1b;是返回浮点数(double型)&#xff0c;浮点数数是arr数组中字符中数字 格式 #include<stdio.h> atof(arr); 返回值arr数组中的数 未改变arr数组 #include<stdio.h> //atof(arr) 返 <stdlib> int…

STM32 USART配置库函数

单片机学习&#xff01; 目录 一、USART配置函数 1.1 USART_DeInit函数 1.2 USART_Init函数 1.3 USART_StructInit函数 二、配置同步时钟输出函数 2.1 USART_ClockInit函数 2.2 USART_ClockStructInit函数 三、USART的外设与中断函数 3.1 USART_Cmd函数 3.2 USART_IT…

通俗理解人工智能、机器学习和深度学习的关系

最近几年人工智能成为极其热门的概念和话题&#xff0c;可以说彻底出圈了。但人工智能的概念在1955年就提出来了&#xff0c;可以说非常古老。我在上小学的时候《科学》课本上就有人工智能的概念介绍&#xff0c;至今还有印象&#xff0c;但那些年AI正处于“寒冬”&#xff0c;…

2024数学建模亚太赛【C题】赛题详细解析

目录 &#x1f4d1;一、竞赛时间 &#x1f5dd;️二、奖项设置 ✏️三、选题思路 &#x1f50d;阶段一&#xff1a;【数据预处理与探索性分析】 1.【数据清洗与预处理】 2.【探索性数据分析&#xff08;EDA&#xff09;】 &#x1f50d;阶段二&#xff1a;【时间序列建模…

数据结构 【堆实现】

上文提到堆是一种特殊的二叉树&#xff0c;其中它的父结点均不大于或者不小于其子结点的值。堆总是一棵完全二叉树。其中&#xff0c;堆的父节点全部不小于它的子结点时称为大堆&#xff0c;堆的父结点全部不大于其子结点的堆称为小堆。 堆可以由两种结构来实现&#xff0c;分别…

【AI绘画】Midjourney进阶:色调详解(下)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调纯色调灰色调暗色调 &#x1f4af…

[代码随想录Day24打卡] 93.复原IP地址 78.子集 90.子集II

93.复原IP地址 一个合法的IP地址是什么样的&#xff1a; 有3个’.分割得到4个数&#xff0c;每个数第一个数不能是0&#xff0c;不能含有非法字符&#xff0c;不能大于255。 这个是否属于合法IP相当于一个分割问题&#xff0c;把一串字符串分割成4部分&#xff0c;分别判断每…

“harmony”整合不同平台的单细胞数据之旅

其实在Seurat v3官方网站的Vignettes中就曾见过该算法&#xff0c;但并没有太多关注&#xff0c;直到看了北大张泽民团队在2019年10月31日发表于Cell的《Landscap and Dynamics of Single Immune Cells in Hepatocellular Carcinoma》&#xff0c;为了同时整合两类数据&#xf…

贴代码PasteForm框架之框架核心帮助类PasteFormHelper说明

简介 PasteForm是贴代码推出的 “新一代CRUD” &#xff0c;基于ABPvNext&#xff0c;目的是通过对Dto的特性的标注&#xff0c;从而实现管理端的统一UI&#xff0c;借助于配套的PasteBuilder代码生成器&#xff0c;你可以快速的为自己的项目构建后台管理端&#xff01;目前管…

杂7杂8学一点之ZC序列

重要的放在前面&#xff0c;优秀文章链接&#xff1a;5GNR漫谈13&#xff1a;Zadoff –Chu&#xff08;ZC&#xff09;序列性质 目录 1. ZC序列 1.1 ZC序列的表达式 1.2 ZC序列的特点 2. PRACH中的ZC序列 2.1 为什么要有逻辑根序列与物理根序列的概念 1. ZC序列 ZC序列&…

matlab代码--卷积神经网络的手写数字识别

1.cnn介绍 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是一种深度学习的算法&#xff0c;在图像和视频识别、图像分类、自然语言处理等领域有着广泛的应用。CNN的基本结构包括输入层、卷积层、池化层&#xff08;Pooling Layer&#xff09;、全连…

【Linux】—简单实现一个shell(myshell)

大家好呀&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流哦&#xff01; 本文由&#xff1a;残念ing原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&…