家居网购项目(权限验证+事务管理)

文章目录

    • 1.过滤器权限认证
        • 1.程序框架图
        • 2.web.xml
        • 3.编写AdminAuthorization
        • 4.编写MemberAuthorization
        • 5.细节
        • 6.结果展示
          • 1.未登录可以任意浏览商品
          • 2.点击添加购物车提示登录
          • 3.点击后台管理,提示管理员登录
          • 4.也做了其余资源的访问验证
    • 2.事务管理
        • 1.思路分析
        • 2.重写JDBCUtilsByDruid
          • 1.getConnection()方法
          • 2.commit()方法
          • 3.rollback()方法
          • 4.删除BasicDao中的所有关闭数据库连接的语句
          • 5.编写过滤器TransactionFilter
          • 6.配置web.xml
          • 7.查看调用可能出现问题的方法是不是抛出了异常
        • 3.结果展示
          • 1.将OrderDaoImpl中的sql故意写错
          • 2.执行保存订单操作
          • 3.查看数据库信息(回滚了,没有生成记录)
    • 3.统一错误页面
        • 1.需求分析
        • 2.修改web.xml
        • 3.导入两个页面
        • 4.修改TransactionFilter,将异常抛给tomcat
        • 5.结果展示
    • 4.会员订单管理—分页查询
        • 需求分析
        • 1.编写dao层
          • 1.修改OrderDao
          • 2.修改OrderDaoImpl
          • 3.单元测试
        • 2.编写service层
          • 1.修改OrderService
          • 2.修改OrderServiceImpl
          • 3.单元测试
        • 3.编写web层
          • 1.修改OrderServlet
          • 2.修改order_manage.jsp
            • 1.显示信息
            • 2.分页导航条
        • 4.结果演示
          • 1.会员登录
          • 2.会员点击订单管理只会显示当前会员的历史订单
    • 5.管理员订单管理—分页查询
        • 需求分析
        • 1.编写dao层
          • 1.修改OrderDao
          • 2.修改OrderDaoImpl
        • 2.编写service层
          • 1.修改OrderService
          • 2.修改OrderServiceImpl
        • 3.编写web层
          • 1.修改OrderServlet
          • 2.修改order_manage.jsp
            • 1.显示信息
            • 2.分页导航条
        • 4.结果展示

1.过滤器权限认证

1.程序框架图

image-20240211092524610

2.web.xml
    <filter>
        <filter-name>AdminAuthorization</filter-name>
        <filter-class>com.sxs.furns.filter.AdminAuthorization</filter-class>
        <init-param>
            <!--设置排除的uri-->
            <param-name>excludeUrls</param-name>
            <param-value>/jiaju_mail/views/manage/manage_login.jsp</param-value>
        </init-param>
    </filter>

    <!--除了登录的管理员页面都要进行管理员验证-->
    <filter-mapping>
        <filter-name>AdminAuthorization</filter-name>
        <url-pattern>/views/manage/*</url-pattern>
    </filter-mapping>
    <!--家居管理-->
    <filter-mapping>
        <filter-name>AdminAuthorization</filter-name>
        <url-pattern>/manage/furnServlet/*</url-pattern>
    </filter-mapping>


    <filter>
        <filter-name>MemberAuthorization</filter-name>
        <filter-class>com.sxs.furns.filter.MemberAuthorization</filter-class>
    </filter>

    <!--登录成功的界面,需要普通权限验证-->
    <filter-mapping>
        <filter-name>MemberAuthorization</filter-name>
        <url-pattern>/views/member/login_ok.jsp</url-pattern>
    </filter-mapping>
    <!--所有的购物车界面,需要普通权限验证-->
    <filter-mapping>
        <filter-name>MemberAuthorization</filter-name>
        <url-pattern>/views/cart/*</url-pattern>
    </filter-mapping>
    <!--购物车和订单servlet,需要普通权限验证-->
    <filter-mapping>
        <filter-name>MemberAuthorization</filter-name>
        <url-pattern>/orderServlet/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>MemberAuthorization</filter-name>
        <url-pattern>/cartServlet/*</url-pattern>
    </filter-mapping>
3.编写AdminAuthorization
package com.sxs.furns.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class AdminAuthorization implements Filter {
    private List<String> excludeUrlsList = new ArrayList<>(); //排除的资源
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //读取配置文件中的信息
        String excludeUrls = filterConfig.getInitParameter("excludeUrls");
        //按照,分割,并添加到集合中
        String[] split = excludeUrls.split(",");
        for (String s : split) {
            excludeUrlsList.add(s);
        }
        //放到servletContext中
        ServletContext servletContext = filterConfig.getServletContext();
        servletContext.setAttribute("excludeUrls", excludeUrlsList);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //查看session中的admin是否为true
        HttpSession session = ((HttpServletRequest) servletRequest).getSession();
        Object admin = session.getAttribute("admin");
        //获取uri
        String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
        //获取排除的uri
        List<String> excludeUrls = (List<String>) servletRequest.getServletContext().getAttribute("excludeUrls");
        //遍历并匹配
        for (String excludeUrl : excludeUrls) {
            System.out.println(excludeUrl);
            //如果匹配直接放行
            if (excludeUrl.equals(requestURI)) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
        }
        if (admin != null) {
            //放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            //重定向到管理员登录界面
            ((HttpServletResponse) servletResponse).sendRedirect("/jiaju_mail/views/manage/manage_login.jsp");
        }
    }

    @Override
    public void destroy() {

    }
}

4.编写MemberAuthorization
package com.sxs.furns.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 普通权限认证
 * @author 孙显圣
 * @version 1.0
 */
public class MemberAuthorization implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpSession session = ((HttpServletRequest) servletRequest).getSession();
        //进行普通权限认证
        Object username = session.getAttribute("username");
        Object admin = session.getAttribute("admin");
        if (username != null || admin != null) {
            System.out.println("普通权限验证成功!");
            //放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            //重定向到用户登录界面
            ((HttpServletResponse) servletResponse).sendRedirect("/jiaju_mail/views/member/login.jsp");
        }
    }

    @Override
    public void destroy() {

    }
}

5.细节

如果想要过滤一个文件夹下除了某个资源的其余资源,可以将排除的资源URI其放在init-param中,然后通过filter的init方法将其放到servletContext中,然后在doFilter中直接放行

6.结果展示
1.未登录可以任意浏览商品

image-20240211114953238

2.点击添加购物车提示登录

image-20240211115035714

image-20240211115041741

3.点击后台管理,提示管理员登录

image-20240211115128144

image-20240211115115218

4.也做了其余资源的访问验证

2.事务管理

1.思路分析

image-20240211142121222

image-20240211142140091

2.重写JDBCUtilsByDruid
1.getConnection()方法
    private static ThreadLocal<Connection> threadLocalConn = new ThreadLocal<>(); //用于存放本线程的连接

    //重写getConnection方法,使其每个线程获取的是同一个连接
    public static Connection getConnection() {
        try {
            Connection connection = threadLocalConn.get(); //从threadlocal中获取当前线程的连接
            //如果没有获取到,则放入一个连接
            if (connection == null) {
                connection = dataSource.getConnection();
                connection.setAutoCommit(false); //取消自动提交
                threadLocalConn.set(connection);
            }
            return connection;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
2.commit()方法
    //提交事务
    public static void commit() {
        //获取连接
        Connection connection = threadLocalConn.get();
        //如果连接有效则提交事务并关闭连接
        if (connection != null) {
            try {
                connection.commit();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        //清除threadlocal的连接
        threadLocalConn.remove();
    }
3.rollback()方法
    //回滚事务
    public static void rollback() {
        Connection connection = threadLocalConn.get();
        if (connection != null) {
            try {
                connection.rollback();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        threadLocalConn.remove();
    }
4.删除BasicDao中的所有关闭数据库连接的语句

原因:数据库连接的关闭,交给最后提交事务或者回滚事务的时候再执行

image-20240211152822089

5.编写过滤器TransactionFilter
package com.sxs.furns.filter;

import com.sxs.furns.utils.JDBCUtilsByDruid;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class TransactionFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){
        //首先放行
        try {
            filterChain.doFilter(servletRequest, servletResponse);
            JDBCUtilsByDruid.commit();
        } catch (Exception e) {
            //如果在这次线程中有异常发生,则回滚
            System.out.println("发现异常,事务回滚!");
            JDBCUtilsByDruid.rollback();
        }

    }

    @Override
    public void destroy() {

    }
}

6.配置web.xml
    <!--在权限验证之后再编写事务过滤器-->
    <filter>
        <filter-name>TransactionFilter</filter-name>
        <filter-class>com.sxs.furns.filter.TransactionFilter</filter-class>
    </filter>
    <!--对所有请求进行过滤-->
    <filter-mapping>
        <filter-name>TransactionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
7.查看调用可能出现问题的方法是不是抛出了异常

所有的servlet都是basicservlet反射调用的,并且都抛出了异常,这个异常最后会经过过滤器,所以可以在过滤器中捕获到异常

image-20240211153711602

3.结果展示
1.将OrderDaoImpl中的sql故意写错

image-20240211154703922

2.执行保存订单操作

image-20240211165406002

image-20240211165420900

image-20240211165433434

3.查看数据库信息(回滚了,没有生成记录)

image-20240211165458599

image-20240211165508047

3.统一错误页面

1.需求分析

image-20240211170301996

2.修改web.xml
    <!--配置错误页面-->
    <error-page>
        <error-code>404</error-code>
        <location>/views/error/404.jsp</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/views/error/500.jsp</location>
    </error-page>
3.导入两个页面

image-20240211171312340

4.修改TransactionFilter,将异常抛给tomcat

image-20240211171629237

5.结果展示

image-20240211171404475

image-20240211171743485

4.会员订单管理—分页查询

需求分析

可以返回已登录的会员的历史订单信息

1.编写dao层
1.修改OrderDao
    //3.获取当前页需要展示的数据
    public List<Order> getPageItems(int begin, int pageSize, String id);
    //4.获取一共的记录条数
    public Integer getTotalRow(String id);
2.修改OrderDaoImpl
    /**
     * 分页查询订单
     * @param begin
     * @param pageSize
     * @return
     */
    @Override
    public List<Order> getPageItems(int begin, int pageSize, String id) {

        String sql = "select id, create_time as createTime, price, status, member_id as memberId from `order` where id like ? limit ?, ?";
        return queryMulti(sql, Order.class, "%-" + id , begin, pageSize);
    }

    /**
     * 获取总记录条数
     * @return
     */
    @Override
    public Integer getTotalRow(String id) {
        String sql = "select count(*) from `order` where id like ?";
        return ((Number) queryScalar(sql,"%-" + id)).intValue();
    }
3.单元测试
    @Test
    public void getPageItems() {
        //查询id为1的会员的订单信息
        List<Order> pageItems = orderDao.getPageItems(0, 3, "1");
        for (Order pageItem : pageItems) {
            System.out.println(pageItem);
        }
    }

    @Test
    public void getTotalRow() {
        System.out.println("总的记录数为:" + orderDao.getTotalRow("1"));
    }

image-20240211193017269

image-20240211200733207

2.编写service层
1.修改OrderService
    //3.分页显示订单
    public Page<Order> getPageItems(int pageNo, int pageSize, String username);
2.修改OrderServiceImpl
    /**
     * 根据当前页号和分页的大小返回对应的page对象
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<Order> getPageItems(int pageNo, int pageSize, String username) {
        //根据姓名获取用户id
        Member member = memberDao.queryMemberByUsername(username);
        //获取总记录数
        Integer totalRow = orderDao.getTotalRow(member.getId().toString());
        //计算总页数
        Integer pageTotalCount = totalRow / pageSize;
        if (totalRow % pageSize > 0) {
            pageTotalCount ++;
        }
        //计算begin
        int begin = (pageNo - 1) * pageSize;

        //获取当页的所有数据
        List<Order> pageItems = orderDao.getPageItems(begin, pageSize, member.getId().toString());
        //填充page
        Page<Order> orderPage = new Page<>();
        orderPage.setPageNo(pageNo);
        orderPage.setPageSize(pageSize);
        orderPage.setPageTotalCount(pageTotalCount);
        orderPage.setTotalRow(totalRow);
        orderPage.setItems(pageItems);
        return orderPage;
    }
3.单元测试
    OrderService orderService = new OrderServiceImpl();
    @Test
    public void getPageItems() {
        Page<Order> pageItems = orderService.getPageItems(1, 3, "admin");
        System.out.println(pageItems);
    }

image-20240211194809877

3.编写web层
1.修改OrderServlet
    //分页显示订单
    public void showPageItems(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取数据
        Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"), 1); //默认第一页
        Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"), 6); //默认六条记录
        String username = req.getParameter("username");
        //获取page对象
        Page<Order> page = orderService.getPageItems(pageNo, pageSize, username);
        //请求转发
        req.setAttribute("page", page);
        req.getRequestDispatcher("/views/order_manage/order_manage.jsp").forward(req, resp);
    }
2.修改order_manage.jsp
1.显示信息

image-20240211201128675

2.分页导航条

image-20240211201147642

4.结果演示
1.会员登录

image-20240211202317112

2.会员点击订单管理只会显示当前会员的历史订单

image-20240211202415806

5.管理员订单管理—分页查询

需求分析

管理员的订单管理,显示的是所有会员的订单

1.编写dao层
1.修改OrderDao
    //5.管理员获取总体的记录条数
    public Integer getTotalRow();
    //6.管理员获取当前页需要展示的数据
    public List<Order> getPageItems(int begin, int pageSize);
2.修改OrderDaoImpl
    @Override
    public Integer getTotalRow() {
        String sql = "select count(*) from `order`";
        return ((Number) queryScalar(sql)).intValue();
    }

    @Override
    public List<Order> getPageItems(int begin, int pageSize) {
        String sql = "select id, create_time as createTime, price, status, member_id as memberId from `order` limit ?, ?";
        return queryMulti(sql, Order.class, begin, pageSize);
    }
2.编写service层
1.修改OrderService
    //4.管理员分页显示订单
    public Page<Order> getPageItems(int pageNo, int pageSize);
2.修改OrderServiceImpl
    @Override
    public Page<Order> getPageItems(int pageNo, int pageSize) {

        //获取总记录数
        Integer totalRow = orderDao.getTotalRow();
        //计算总页数
        Integer pageTotalCount = totalRow / pageSize;
        if (totalRow % pageSize > 0) {
            pageTotalCount ++;
        }
        //计算begin
        int begin = (pageNo - 1) * pageSize;

        //获取当页的所有数据
        List<Order> pageItems = orderDao.getPageItems(begin, pageSize);
        //填充page
        Page<Order> orderPage = new Page<>();
        orderPage.setPageNo(pageNo);
        orderPage.setPageSize(pageSize);
        orderPage.setPageTotalCount(pageTotalCount);
        orderPage.setTotalRow(totalRow);
        orderPage.setItems(pageItems);
        return orderPage;
    }
3.编写web层
1.修改OrderServlet
    //管理员分页显示订单
    public void showAllPageItems(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取数据
        Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"), 1); //默认第一页
        Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"), 6); //默认六条记录
        //获取page对象
        Page<Order> page = orderService.getPageItems(pageNo, pageSize);
        //请求转发
        req.setAttribute("page", page);
        req.getRequestDispatcher("/views/manage/order_manage.jsp").forward(req, resp);
    }
2.修改order_manage.jsp
1.显示信息

image-20240211211148413

2.分页导航条

image-20240211211203728

4.结果展示

image-20240211211304583

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

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

相关文章

Python数据容器(一)

一.数据容器入门 1.Python中的数据容器&#xff1a;一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为1个元素&#xff0c;每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等。 2.数据容器根据特点的不同&#xff0c;如&#…

2A大电流线性稳压器具备两种输出电压范围

概述 PCD3931 是一款低噪声、低压差线性稳压器 (LDO)&#xff0c;可提供 2A 输出电流&#xff0c;最大压降仅为 160mV。该器件提供两种输出电压范围。 PCD3931 的输出电压可通过外部电阻分压器在 0.5V 至 5.5V 范围内进行调节。PCD3931 集低噪声、高 PSRR 和高输出电流能力等特…

24年重庆三支一扶报名照不通过怎么处理?

24年重庆三支一扶报名照不通过怎么处理&#xff1f;

消化内科专科护士理论考试案例选择题及答案

电大搜题 多的用不完的题库&#xff0c;支持文字、图片搜题&#xff0c;包含国家开放大学、广东开放大学、超星等等多个平台题库&#xff0c;考试作业必备神器。 公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#…

鸿蒙 UI预览报错

SyntaxError: Unexpected end of JSON input 删除entry下的.preview文件 重新刷新预览

python爬虫------- Selenium下篇(二十三天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

MySQL表空间管理与优化(8/16)

表空间管理和优化 innodb_file_per_table参数&#xff08;此参数在分区表章节中还会出现&#xff09;&#xff1a; 这个参数决定了InnoDB表数据的存储方式。当参数设置为ON时&#xff0c;每个InnoDB表的数据会单独存储在一个以.ibd为后缀的文件中&#xff0c;这有利于管理和回收…

4、XTuner 微调个人小助手(笔记)

视频地址&#xff1a; https://b23.tv/QUhT6ni 课程文档&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/xtuner/readme.md 作业文档&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/xtuner/homework.md 1、Finetune 简介 两种Finetune范式 …

JavaEE企业开发新技术5

目录 2.18 综合应用-1 2.19 综合应用-2 2.20 综合应用-3 2.21 综合应用-4 2.22 综合应用-5 Synchronized &#xff1a; 2.18 综合应用-1 反射的高级应用 DAO开发中&#xff0c;实体类对应DAO的实现类中有很多方法的代码具有高度相似性&#xff0c;为了提供代码的复用性,降低…

【STL】迭代器iterator详解

前言 本篇文章以对string的操作来演示迭代器的操作。 一、什么是迭代器iterator&#xff1f; 迭代器&#xff08;iterator&#xff09;是一种可以遍历容器元素的数据类型。迭代器是一个变量&#xff0c;相当于容器和操纵容器的算法之间的中介。C迭代器是一种用于遍历容器中元的…

【Modelsim】保持波形格式重编译and波形的保存与查看

文章目录 保持原波形格式重编译波形的保持与查看保存波形打开工程查看波形 保持原波形格式重编译 Modelsim 仿真设置好波形格式后&#xff0c;若需要修改代码并保持原波形格式重新查看波形&#xff0c;只需将文件重新编译后仿真即可。 1.修改代码后Project页面的代码状态变成…

lua学习笔记20(lua中一些自带库的学习)

print("*****************************lua中一些自带库的学习*******************************") print("*************时间***************") --系统时间 print(os.time()) --自己传入参数得到时间 print(os.time({year2011,month4,day5})) --os.data(&qu…

包装类初识泛型

一.包装类 在Java中, 基本类型不继承于Object类. 所以为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型.(包装类型相当于引用类型) 1.基本类型对应的包装类 byte -- Byteshort -- Shortint -- Integerlong -- Longfloat -- Floatdouble -- Doublech…

Vue2 基础学习-案例实践

数据管理信息的增删改查的实践 主要应用&#xff1a; 数据插值&#xff1a; {{xxx}}双向绑定&#xff1a;v-model点击事件函数&#xff1a;click列表xxx的增删改实现 xxx.push(row) 增加xxx.splice(id,1) 删除 一行{x,y} xxx[id]; 编辑 <!DOCTYPE html> <html la…

蓝桥杯 2019 省A 糖果 动态规划/二进制

#include <bits/stdc.h> // 包含标准库中的所有头文件 using namespace std;int main() {int n,m,k; // 定义变量n&#xff08;糖果包数&#xff09;、m&#xff08;口味数&#xff09;、k&#xff08;每包糖果的个数&#xff09;cin>>n>>m>>k; // 输入…

[lesson31]完善的复数类

完善的复数类 完善的复数类 复数类应该具有的操作 运算&#xff1a;&#xff0c;-&#xff0c;*&#xff0c;/比较&#xff1a;&#xff0c;!赋值&#xff1a;求模&#xff1a;modulus 利用操作符重载 统一复数与实数的运算方式统一复数与实数的比较方式 注意事项 C规定赋…

Day 25 组合(优化)216.组合总和III 17.电话号码的字母组合

组合&#xff08;优化&#xff09; 先给出组合问题的回溯部分代码&#xff1a; vector<vector<int>> result; // 存放符合条件结果的集合vector<int> path; // 用来存放符合条件结果void backtracking(int n, int k, int startIndex) {if (path.size() k) …

洛谷P1305 新二叉树

Java 代码 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();char arr[][] new char[n][3];for (int i 0; i < n; i) {String strsc.next();char arr1[]str.toCharArray()…

【计算机考研】跨考计算机,需要准备多久才来得及?

9个月跨考计算机&#xff0c;如果选择是408的话&#xff0c;时间稍微有点紧张&#xff0c;前期感觉不大&#xff0c;后期数学408堆在一起会感觉很难受... 很多确定考408的同学都是一开始先从数据结构开始复习的&#xff0c;这样到了中后期觉得自己时间不够了再去转自命题也来得…

UE5数字孪生系列笔记(四)

场景的切换 创建一个按钮的用户界面UMG 创建一个Actor&#xff0c;然后将此按钮UMG添加到组件Actor中 调节几个全屏的背景 运行结果 目标点切换功能制作 设置角色到这个按钮的位置效果 按钮被点击就进行跳转 多个地点的切换与旋转 将之前的目标点切换逻辑替换成旋转的逻…