基于Java web的用户管理系统开发(可直接跳到实现步骤)(小白也行)

前言_下载资源说明

作者:BSXY_陈永跃
BSXY_信息学院
注:未经允许禁止转发任何内容

该system是可以自己按步骤一步一步完成的(可直接查看第3大点实现步骤及其方法),如需源码也可自行下载点击以下链接下载:
在这里插入图片描述
[资源中包括了system的源码+相应的SQL文件+system导入运行辅助教学视频(文档)+Navicat免费免安装软件_根据图片找到对应的资源即可]

公众号(小猿网),回复“b02”即可
资源为收费资源,如不符合您的消费观,还请您见谅

由于公众号可能目前没有太大的曝光度,搜索时可能
不是置顶的公众号。这时可以多往下滑一下找到该公
众号,或者直接到文章结尾处获取公众号二维码即可

比较适合刚刚学完java web的知识点,又刚好想做一下项目的人员,该system比较的基础
在这里插入图片描述

1、业务及其需求分析

1、实现以下功能

1、用户的查询功能
2、用户的添加功能
2、用户的登录功能
3、用户的删除功能
4、用户的修改功能
5、用户的批量删除功能

2、使用以下技术

JSP+Servlet(request、response、session)+javaBean+druid连接池技术+JdbcTemplate+MySQL+MVC开发模式(开发工具为IDEA)
请添加图片描述

2、简单成品展示

1、登录功能与简单界面

在这里插入图片描述
在这里插入图片描述

2、页面查询功能

在这里插入图片描述

3、添加功能

在这里插入图片描述

4、单个用户删除功能

在这里插入图片描述

5、用户修改功能

在这里插入图片描述

6、选中批量删除功能

在这里插入图片描述

3、实现步骤及其方法(重点必看)(一步一步对应实现)*****

1、用户查询功能

请添加图片描述
代码结构:
请添加图片描述

1、封装User 类
package com.entity;

public class User {
    private int id;
    private String name;
    private String gender;
    private int age;
    private String address;
    private String qq;
    private String email;
setter and getter方法
toString方法
}
2、改造的index.jsp并去到servlet中
 <a
 href="${pageContext.request.contextPath}/userListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息
    </a>
3、创建userListServlet(什么都不干)和UserService 接口
public interface UserService {
    /**
     * 查询所有用户信息
     */
    public List<User> findAll();
}
4、service中创建子包impl定义接口实现 类 (UserServiceImpl)
public class UserServiceImpl implements UserService {
    public List<User> findAll(){
        //调用dao完成查询
        return ;
    }
}
5、dao中创建 接口 UserDao
/**
 * 用户操作的dao
 */
public interface UserDao {
    public List<User> findAll();
}
6、dao中的子包impl中创建定义接口实现的 类 (UserDaoImpl)
public class UserDaoImpl implements UserDao {
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
    @Override
    public List<User> findAll() {
       //使用jdbc操作数据库
        //1、定义sql
        String sql="select*from user";
        List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
        return users;
    }
}
7、UserServiceImpl中创建new实现类
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();
    @Override
    public List<User> findAll(){
        //调用dao完成查询
        return dao.findAll();
    }

}
8、再来userListServlet中
doPost中:
    
    //1、调用UserService完成查询
        UserService service=new UserServiceImpl();
        List<User> users = service.findAll();
        //2、将list存入request中
        request.setAttribute("users",users);
        //3、转发到list.jsp
       request.getRequestDispatcher("/list.jsp").forward(request,response);
9、jsp的list.jsp显示页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<body>
<div class="container">
    <h3 style="text-align: center">用户信息列表</h3>
    <form id="form" action="" method="post">
        <table align="center" cellpadding="2px" cellspacing="2px" border="1">
            <tr>
                <td><input type="checkbox"></td>
                <th>编号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>籍贯</th>
                <th>QQ</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            
            <c:forEach items="${users}" var="user" varStatus="s">
                <tr>
                    <td><input type="checkbox"></td>
                    <td>${s.count}</td>
                    <td>${user.name}</td>
                    <td>${user.gender}</td>
                    <td>${user.age}</td>
                    <td>${user.address}</td>
                    <td>${user.qq}</td>
                    <td>${user.email}</td>
                    <td><a class="btn btn-default btn-sm" href="#">修改</a>&nbsp;<a
                            class="btn btn-default btn-sm" href="#">删除</a></td>
                </tr>
            </c:forEach>

        </table>
    </form>
</div>
</body>

2、登录功能及其验证码的加载及其切换

1、加载验证码,超链接形式点击切换
//在session中存入当前的code码,便于验证
        request.getSession().setAttribute("checkCode",code);

加载好验证码后实现切换:

<script type="text/javascript">
   //切换验证码
        function refreshCode(){//超链接的方法
            //1.获取验证码图片对象
            var img = document.getElementById("checkCode");
            //2.设置其src属性,加时间戳
 img.src = "${pageContext.request.contextPath}/checkCodeServlet?time="+new Date().getTime();
        }
    </script>


<a href="javascript:refreshCode();">
  <img src="${pageContext.request.contextPath}/checkCodeServlet" title="看不清点击刷新" id="checkCode"/></a>
2、创建LoginServlet
逻辑:
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取数据  
//3.验证码校验
//4.封装User对象
//5.调用Service查询
//6、判断是否登录成功

doPost中的代码:

//1.设置编码
        request.setCharacterEncoding("utf-8");
        //2.获取数据
        //2.1获取用户填写验证码
        String verifycode = request.getParameter("verifycode");//jsp中验证码的name
        //3、验证码的校验
        HttpSession session = request.getSession();
        String code = (String)session.getAttribute("checkCode");//CheckCodeServlet中的值
        session.removeAttribute("checkCode");//确保验证码一次性

        if (!code.equalsIgnoreCase(verifycode)){
            //验证码不正确
            //提示信息
            request.setAttribute("login_msg","验证码错误!");
            request.getRequestDispatcher("/login.jsp").forward(request,response);
            return;
        }

        Map<String, String[]> map = request.getParameterMap();


        //4、封装User对象
        User user=new User();
        try {
            BeanUtils.populate(user,map);//JavaBean
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //5、调用service查询
        UserServiceImpl service = new UserServiceImpl();
        User loginUser=service.login(user);

      //编写到这里后报错,原因service中没有这个方法,接下来到service中创建方法

        //6、判断是否登录成功
        if (loginUser!=null){
            //登录成功
            //将用户存入session
            session.setAttribute("user",loginUser);
            //跳转页面
            response.sendRedirect(request.getContextPath()+"/index.jsp");

        }else {
            //登录失败
            request.setAttribute("login_msg","用户名或密码错误!");
            request.getRequestDispatcher("/login.jsp").forward(request,response);
         } 
3、来到service下的UserService中创建接口
public interface UserService {
    /**
     * 登录方法
     */
 User login(User user);
}
4、、来到service下impl中的UserServiceImpl中实现类
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();

   public User login(User user) {
        return dao.findUserByUsernameAndPassword(user.getUsername(),user.getPassword());
    }
    //现在应该返回null(要在dao中的接口中创建接口才行),这里省略,一步到位了
}
5、dao中的UserDao中创建接口
/**
 * 用户操作的dao
 */
public interface UserDao {
    User findUserByUsernameAndPassword(String username, String password);
}
6、dao中impl中实现类方法(操作数据库库的sql)
public class UserDaoImpl implements UserDao {
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
    public User findUserByUsernameAndPassword(String username, String password) {
        try {
            String sql = "select * from user where username = ? and password = ?";
            User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
            return user;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
//如果不try catch用户名或密码错误会报500的错误

再次回来LoginServlet中编写

3、用户添加功能

逻辑图
在这里插入图片描述

1、修改按钮跳转页面
<a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
2、添加表单提交的action
<form action="${pageContext.request.contextPath}/addUserServlet" method="post">
3、创建AddUserServlet
doPost中:
//1、设置编码
    request.setCharacterEncoding("utf-8");
     //2、获取参数
     Map<String, String[]> map = request.getParameterMap();
    //3、封装对象
    User user=new User();
    try {
    BeanUtils.populate(user,map);
  } catch (IllegalAccessException e) {
    e.printStackTrace();
   } catch (InvocationTargetException e) {
    e.printStackTrace();
   }

   //4、调用Service保存
   UserService service=new UserServiceImpl();
   service.addUser(user);//到这里会报错,也可以接在写

   //5、跳转到userListServlet
   response.sendRedirect(request.getContextPath()+"/userListServlet");
4、在service下的UserService中创建接口
public interface UserService {
    /**
     *保存User方法
     */
    void addUser(User user);
}
5、在service下impl包的UserServiceImpl中实现类
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();
    @Override
    public void addUser(User user) {
        dao.add(user);
    }
}
6、dao下的UserDao中创建接口
public interface UserDao {
    void add(User user);
}
7、dao下impl包的UserDaoImpl实现类
public class UserDaoImpl implements UserDao {
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
    
    @Override
    public void add(User user) {
        //1、定义sql
        String sql="insert into user values(null,?,?,?,?,?,?,null,null)";
        //2、执行sql
  template.update(sql,user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail());

    }
}

3、删除功能

在这里插入图片描述

1、修改访问路径(根据id删除数据)
<a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/delUserServlet?id=${user.id}">删除</a>
2、创建DelUserServlet
doPost:
//1、获取id
        String id=request.getParameter("id");
        //2、调用service删除
        UserService service=new UserServiceImpl();
        service.deleteUser(id);
        //跳转到查询所有的UserListServlet
        response.sendRedirect(request.getContextPath()+"/userListServlet");
3、在service下的UserService中创建接口
public interface UserService {
    /**
     * 根据id删除
     */
    void deleteUser(String id);
}
4、在service下impl包的UserServiceImpl中实现类
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();
    @Override
    public void deleteUser(String id) {
        dao.delete(Integer.parseInt(id));//转为数字类型
    }
}
5、dao下的UserDao中创建接口
public interface UserDao {
    void delete(int i);
}
6、dao下impl包的UserDaoImpl实现类
public class UserDaoImpl implements UserDao {
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
    
    @Override
    public void delete(int id) {
        //1、定义sql
        String sql="delete from user where id=?";
        template.update(sql,id);
    }
}
7、增强用户体验感(删除是给出提示框)
<script>
        function deleteUser(id) {
            //用户安全提示
            if (confirm("您确定删除吗?")){
                location.href="${pageContext.request.contextPath}/delUserServlet?id="+id;
            }
        }
    </script>

<td>
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id}); ">删除</a>
</td>

5、修改功能

逻辑图:
在这里插入图片描述
回显信息:

1、修改按钮的页面跳转
<td>
<a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>&nbsp;
</td>
2、编写FindUserServlet
doPost:
        //1、获取id
        String id = request.getParameter("id");
        //2、调用service查询
        UserService service = new UserServiceImpl();
        User user=service.findUserById(id);

        //3、将user存入request
        request.setAttribute("user",user);
        //4、转发到update.jsp
        request.getRequestDispatcher("/update.jsp").forward(request,response);
3、service中UserService创建 接口 方法
public interface UserService {
    /**
     * 根据id查询
     * @param id
     */
    User findUserById(String id);
}
4、service中impl下UserServiceImpl创建实现 类 的方法
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();
    @Override
    public User findUserById(String id) {
        return dao.findById(Integer.parseInt(id));//转为数字类型
    }
}
5、Dao中UserDao创建接口方法
public interface UserDao {
    User findById(int i);
}
6、创建对应的实现类
public class UserDaoImpl implements UserDao {
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
    @Override
    public User findById(int id) {
        String sql="select*from user where id=?";
        return template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),id);
    }
}
7、去update中回显信息(重点看value和c:if中的代码)
<div class="form-group">
            <label for="name">姓名:</label>
            <input type="text" class="form-control" id="name" name="name"  value="${user.name}" readonly="readonly" placeholder="请输入姓名" />
          </div>

          <div class="form-group">
            <label>性别:</label>
              <c:if test="${user.gender == '男'}">
                  <input type="radio" name="gender" value="男" checked />男
                  <input type="radio" name="gender" value="女"  />女
              </c:if>

              <c:if test="${user.gender == '女'}">
                  <input type="radio" name="gender" value="男"  />男
                  <input type="radio" name="gender" value="女" checked  />女
              </c:if>


          </div>

          <div class="form-group">
            <label for="age">年龄:</label>
            <input type="text" class="form-control" value="${user.age}" id="age"  name="age" placeholder="请输入年龄" />
          </div>

          <div class="form-group">
            <label for="address">籍贯:</label>
             <select name="address" id="address" class="form-control" >
                 <c:if test="${user.address == '陕西'}">
                    <option value="陕西" selected>陕西</option>
                    <option value="北京">北京</option>
                    <option value="上海">上海</option>
                 </c:if>

                 <c:if test="${user.address == '北京'}">
                     <option value="陕西" >陕西</option>
                     <option value="北京" selected>北京</option>
                     <option value="上海">上海</option>
                 </c:if>

                 <c:if test="${user.address == '上海'}">
                     <option value="陕西" >陕西</option>
                     <option value="北京">北京</option>
                     <option value="上海" selected>上海</option>
                 </c:if>
            </select>
          </div>

          <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="text" id="qq" class="form-control" value="${user.qq}" name="qq" placeholder="请输入QQ号码"/>
          </div>

          <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" id="email" class="form-control" value="${user.email}" name="email" placeholder="请输入邮箱地址"/>
          </div>

用户修改:

8、表单提交方式及其隐藏域(一定要有)
<form action="${pageContext.request.contextPath}/updateUserServlet" method="post">
            <!--  隐藏域 提交id-->
            <input type="hidden" name="id" value="${user.id}">
    //注意影藏域
          <div class="form-group">
            <label for="name">姓名:</label>
            <input type="text" class="form-control" id="name" name="name"  value="${user.name}" readonly="readonly" placeholder="请输入姓名" />
          </div>

          <div class="form-group">
            <label>性别:</label>
              <c:if test="${user.gender == '男'}">
                  <input type="radio" name="gender" value="男" checked />男
                  <input type="radio" name="gender" value="女"  />女
              </c:if>

              <c:if test="${user.gender == '女'}">
                  <input type="radio" name="gender" value="男"  />男
                  <input type="radio" name="gender" value="女" checked  />女
              </c:if>


          </div>

          <div class="form-group">
            <label for="age">年龄:</label>
            <input type="text" class="form-control" value="${user.age}" id="age"  name="age" placeholder="请输入年龄" />
          </div>

          <div class="form-group">
            <label for="address">籍贯:</label>
             <select name="address" id="address" class="form-control" >
                 <c:if test="${user.address == '陕西'}">
                    <option value="陕西" selected>陕西</option>
                    <option value="北京">北京</option>
                    <option value="上海">上海</option>
                 </c:if>

                 <c:if test="${user.address == '北京'}">
                     <option value="陕西" >陕西</option>
                     <option value="北京" selected>北京</option>
                     <option value="上海">上海</option>
                 </c:if>

                 <c:if test="${user.address == '上海'}">
                     <option value="陕西" >陕西</option>
                     <option value="北京">北京</option>
                     <option value="上海" selected>上海</option>
                 </c:if>
            </select>
          </div>

          <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="text" id="qq" class="form-control" value="${user.qq}" name="qq" placeholder="请输入QQ号码"/>
          </div>

          <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" id="email" class="form-control" value="${user.email}" name="email" placeholder="请输入邮箱地址"/>
          </div>

             <div class="form-group" style="text-align: center">
                <input class="btn btn-primary" type="submit" value="提交" />
                <input class="btn btn-default" type="reset" value="重置" />
                <input class="btn btn-default" type="button" value="返回"/>
             </div>
        </form>
9、创建UpdateUserServlet
doPost中:
request.setCharacterEncoding("utf-8");
        //2、获取map
        Map<String, String[]> map = request.getParameterMap();
        //3、封装对象
        User user=new User();
        try {
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //4、调用Service修改
        UserService service=new UserServiceImpl();
        service.updateUser(user);
        //5、跳转到查询所有Servlet
        response.sendRedirect(request.getContextPath()+"/userListServlet");
10、service中UserService创建 接口 方法
public interface UserService {
    /**
     * 修改用户信息
     * @param user
     */
    void updateUser(User user);
}
11、service中impl下UserServiceImpl创建实现 类 的方法(注意没有返回值)
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();
    @Override
    public void updateUser(User user) {
        dao.update(user);
    }
}
12、Dao中UserDao创建接口方法
public interface UserDao {
    void update(User user);
}
13、dao下impl包的UserDaoImpl实现类(没有返回值)
public class UserDaoImpl implements UserDao {
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
 
    @Override
    public void update(User user) {
        String sql="update user set name=?,gender=?,age=?,address=?,qq=?,email=? where id=?";
  template.update(sql,user.getName(),user.getGender(),user.getAge(),user.getAddress(),user.getQq(),user.getEmail(),user.getId());
    }
}

6、选中批量删除

逻辑:
在这里插入图片描述

1、给提交数据加form和复选框加name
<form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post">
        <table border="1" class="table table-bordered table-hover">

            <tr class="success">
                <td><input type="checkbox" id="firstCb"></td>
                <th>编号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>籍贯</th>
                <th>QQ</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            <c:forEach items="${users}" var="user" varStatus="s">
                <tr>
                    <td><input type="checkbox" name="uid" value="${user.id}"></td>
                    <%--value就是这条数据的id--%>
                    <td>${s.count}</td>
                    <td>${user.name}</td>
                    <td>${user.gender}</td>
                    <td>${user.age}</td>
                    <td>${user.address}</td>
                    <td>${user.qq}</td>
                    <td>${user.email}</td>
                    <td>
                        <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>&nbsp;
                        <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id}); ">删除</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
    </form>
2、给删除选中绑定单击事件
 <script>
window.οnlοad=function () {
          //给删除选中按钮添加单机事件
          document.getElementById("delSelected").οnclick=function () {
              //提交表单
              document.getElementById("form").submit();
          }
</script>


<div style="float: right;margin: 5px;">
      <a class="btn btn-primary" href="javascript:void(0);" id="delSelected">删除选中</a><%--绑定事件--%>

  </div>
3、创建编写DelSelectedServlet
 //1、获取所有id
      String[] ids = request.getParameterValues("uid");
      //2、调用service删除
      UserService service=new UserServiceImpl();
      service.delSelectedUser(ids);;

      //3、跳转到查询所有Servlet
      response.sendRedirect(request.getContextPath()+"/userListServlet");
4、service中UserService创建 接口 方法
public interface UserService {
    /**
     * 批量删除用户
     * @param ids
     */
    void delSelectedUser(String[] ids);
}
5、service中impl下UserServiceImpl创建实现 类 的方法
public class UserServiceImpl implements UserService {
    private UserDao dao=new UserDaoImpl();

    @Override
    public void delSelectedUser(String[] ids) {
        if (ids!=null&&ids.length>0){//防止空指针异常
            //1、遍历数组
            for (String id:ids){
                //2、调用dao删除
                dao.delete(Integer.parseInt(id));
                //删除的dao已经有了
            }
        }

    }

}
6、实现全选
<script>
        window.οnlοad=function () {
            //给删除选中按钮添加单机事件
            document.getElementById("delSelected").οnclick=function () {
                if (confirm("您确定要删除选中条目吗?")){
                    var flag=false;
                    //判断是否有选中条目,防止一条都没有选中出现空指针异常
                    var cbs=document.getElementsByName("uid");
                    for (var i=0;i<cbs.length;i++){//
                        if (cbs[i].checked){
                            //有一条选中了
                           flag=true;
                            break;
                        }
                    }
                    if (flag){//有条目被选中才执行以下操作
                        //完成表单提交
                        document.getElementById("form").submit();
                    }
                }
            }

            //1、获取第一个cb,实现全选
            document.getElementById("firstCb").οnclick=function () {
                //2、获取下边列表的所有cb
                var cbs=document.getElementsByName("uid");
                //3、遍历
                for(var i=0;i<cbs.length;i++){
                    //4、设置这些cbs[i]的checked状态=firstCb.checked
                    cbs[i].checked=this.checked;
                }
            }
        }
    </script>

<form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post">
        <table border="1" class="table table-bordered table-hover">

            <tr class="success">
                <td><input type="checkbox" id="firstCb"></td>
                <%--让以下的复选框状态都和第一个保持一致--%>
                <th>编号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>籍贯</th>
                <th>QQ</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            <c:forEach items="${users}" var="user" varStatus="s">
                <tr>
                    <td><input type="checkbox" name="uid" value="${user.id}"></td>
                    <%--value就是这条数据的id--%>
                    <td>${s.count}</td>
                    <td>${user.name}</td>
                    <td>${user.gender}</td>
                    <td>${user.age}</td>
                    <td>${user.address}</td>
                    <td>${user.qq}</td>
                    <td>${user.email}</td>
                    <td>
                        <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>&nbsp;
                        <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id}); ">删除</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
    </form>

4、数据库字段部分

在这里插入图片描述

5、结语

该管理系统所用到的技术也就是上述中提到的技术,主要完成的的功能就是对数据的一些增、删、改、查。对于java web的开发是最基本的操作。该管理系统主要适合小白,对于java大神当然可以忽略了,
在学习的过程中重点提醒做笔记,推荐的做笔记软件是typora
只用记录重点自己看得到懂的就好了eg:
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐