ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java民宿管理系统:SSM框架实战与MySQL高并发避坑指南

Java民宿管理系统:SSM框架实战与MySQL高并发避坑指南 简介本资源是一份完整的本科毕业设计文档面向计算机专业学生及Java Web开发初学者聚焦民宿行业信息化管理痛点提供基于SSM框架的系统化解决方案。文档详细阐述了系统需求分析、技术选型SpringSpringMVCMyBatis、数据库设计MySQL、核心功能模块民宿信息管理、在线预订、客户关系、财务管理及安全机制实现特别强化了预订流程逻辑与数据自动化处理的设计说明。资源为单文件.docx格式共1个文件大小924KB内容结构完整含摘要、关键词、中英文目录、绪论、相关技术介绍SSM/B/S/MySQL、系统分析与设计等标准毕业论文章节附有可直接参考的代码架构思路与安全实践建议。目前已有58人学习下载适合课程设计参考、毕设开题借鉴或SSM实战项目复盘尤其利于理解传统服务业管理系统的技术落地路径与模块协同逻辑。1. 为什么一个“基于Java的民宿管理系统”能成为校招面试官眼里的加分项——它不是Demo而是B/S架构下SSM落地的完整闭环你可能在简历里写过“用Java做过学生管理系统”但面试官扫一眼就划走了而当你把“基于Java的民宿管理系统”拆开讲前端用VueElement UI跑在Chrome里后端是SpringSpringMVCMyBatis三层解耦数据库用MySQL 5.7建了12张表含订单状态机、房型库存锁、用户权限分级部署在阿里云ECS上跑通HTTPSNginx反向代理——他立刻坐直身体问你“库存扣减怎么防超卖管理员和房东权限怎么隔离订单超时未支付怎么自动释放房间”这不是课程设计作业而是真实业务逻辑的压缩包房东要审核、客人要评价、平台要抽佣、财务要对账、运维要查日志。它天然携带SSM框架的典型矛盾——比如MyBatis动态SQL写多了容易SQL注入Spring事务传播行为配错导致退款失败却没回滚或者MySQLSELECT ... FOR UPDATE在高并发预约时卡死连接池。适合谁刚学完Java基础MySQL语法的大三学生想用一个可演示、可调试、可延展的项目证明自己不是只会抄HelloWorld也适合转行者用这个系统串起Servlet生命周期、JDBC连接池、RESTful接口设计、前后端分离调试等硬技能节点。它不追求炫技但每一步都踩在企业开发的真实路基上B/S结构决定你必须理解HTTP状态码401/403的区别MySQL决定你得亲手写EXPLAIN看索引是否生效SSM框架逼你搞懂Transactional为什么不能加在private方法上。下面我们就从零开始把这份.docx标题变成可运行、可调试、可面试深挖的工程实体。2. 搭建SSM骨架用Maven精准控制依赖版本避开Spring与MyBatis的兼容雷区2.1 为什么不用Spring Boot而坚持SSM——这是对框架底层逻辑的主动选择很多新手看到“Java民宿系统”第一反应是“上Spring Boot”但本项目刻意回归SSMSpring SpringMVC MyBatis有明确目的面试验证点集中Spring的IoC容器如何管理Controller/Service/DAO三层BeanSpringMVC的RequestMapping如何映射URL到方法MyBatis的SqlSessionFactory怎么通过XML配置绑定Mapper接口这些全是Java开发岗高频手写题。可控性更强Spring Boot自动装配的DataSource可能默认HikariCP但你得手动配maxLifetime防MySQL 8小时断连而SSM中你直接写druid.properties参数一目了然。避坑成本低Spring Boot 2.7已弃用spring-boot-starter-web中的EnableWebMvc但SSM中你永远清楚mvc:annotation-driven/干了什么。提示本项目采用Spring 5.3.32 SpringMVC 5.3.32 MyBatis 3.4.6 MyBatis-Spring 1.3.2组合。这是经大量项目验证的稳定三角——Spring 5.3.x兼容JDK 8~17MyBatis 3.4.6支持SelectProvider动态SQL且无Jackson 2.15的CVE漏洞避免用MyBatis 3.5.x后因Param注解缺失导致的BindingException。2.2 Maven pom.xml核心依赖配置精确到小版本号的生存指南!-- Spring核心 -- dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.3.32/version /dependency !-- SpringMVC -- dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version5.3.32/version /dependency !-- MyBatis整合 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.4.6/version /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version1.3.2/version /dependency !-- MySQL驱动注意8.0驱动类名已变 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version5.1.47/version !-- 对应MySQL 5.7避免8.0驱动的sslMode报错 -- /dependency !-- 数据库连接池Druid比DBCP更稳 -- dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.16/version /dependency !-- JSTL用于JSP页面虽然后端推荐用Thymeleaf但本项目保留JSP兼容性 -- dependency groupIdjstl/groupId artifactIdjstl/artifactId version1.2/version /dependency关键参数说明mysql-connector-java 5.1.47若用MySQL 5.7.44当前主流生产版本必须用5.1.x系列驱动。若误用8.0.x驱动启动时会报java.sql.SQLException: The server time zone value XXX is unrecognized本质是时区协商失败。druid 1.2.16修复了1.1.23版本中removeAbandonedOnBorrowtrue导致连接池假死的问题民宿系统高峰期每秒订单请求超20次此参数直接影响可用性。所有Spring相关依赖统一用5.3.32避免spring-core与spring-webmvc版本不一致引发NoSuchMethodError——这是SSM项目启动失败的TOP3原因。2.3 web.xml与SpringMVC配置让DispatcherServlet真正接管请求web.xml是B/S结构的入口契约必须显式声明Servlet生命周期?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd version4.0 !-- 加载Spring根容器 -- context-param param-namecontextConfigLocation/param-name param-valueclasspath:spring/applicationContext.xml/param-value /context-param listener listener-classorg.springframework.web.context.ContextLoaderListener/listener-class /listener !-- 配置SpringMVC前端控制器 -- servlet servlet-namedispatcher/servlet-name servlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class init-param param-namecontextConfigLocation/param-name param-valueclasspath:spring/springmvc.xml/param-value /init-param load-on-startup1/load-on-startup /servlet servlet-mapping servlet-namedispatcher/servlet-name url-pattern//url-pattern !-- 注意不是/*.do/才能拦截静态资源 -- /servlet-mapping !-- 字符编码过滤器必须在所有Filter最前 -- filter filter-nameencodingFilter/filter-name filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param init-param param-nameforceEncoding/param-name param-valuetrue/param-value /init-param /filter filter-mapping filter-nameencodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping /web-app逻辑说明ContextLoaderListener加载applicationContext.xml创建IoC容器管理Service/DAO层BeanDispatcherServlet加载springmvc.xml创建MVC容器管理Controller层Beanurl-pattern//url-pattern意味着所有请求包括/css/app.css都经过DispatcherServlet因此必须在springmvc.xml中配置mvc:default-servlet-handler/放行静态资源否则页面CSS/JS全404CharacterEncodingFilter的forceEncodingtrue强制覆盖request的编码解决民宿订单中客人姓名含中文时乱码问题。3. MySQL数据库设计12张表如何支撑“房东审核-客人预订-订单履约”全链路3.1 核心业务表关系图用ER模型锁定数据一致性边界民宿系统不是CRUD堆砌而是状态机驱动。我们按业务域划分表组表名主键关键外键业务意义索引重点useruser_id—用户基础信息区分房东/客人/管理员idx_role_statusrole_type, status加速角色查询hosthost_iduser_id→user.user_id房东认证信息身份证、营业执照idx_audit_statusaudit_status查待审房东househouse_idhost_id→host.host_id民宿房源标题、描述、位置spatial idx_location经度纬度支持附近搜索room_typeroom_type_idhouse_id→house.house_id房型大床房/家庭房及价格idx_house_pricehouse_id, price查某民宿低价房型house_imageimage_idhouse_id→house.house_id房源图片轮播图idx_house_orderhouse_id, sort_order保序展示bookingbooking_iduser_id,room_type_id预订单入住时间、人数idx_user_statususer_id, status查用户历史订单orderorder_idbooking_id→booking.booking_id支付订单微信/支付宝idx_status_timestatus, create_time查超时未支付单reviewreview_idbooking_id,user_id客人评价含图片idx_house_scorehouse_id, score查高分民宿admin_loglog_id—后台操作日志谁删了哪条房源idx_admin_timeadmin_id, operate_time审计追溯messagemsg_idsender_id,receiver_id站内信房东与客人沟通idx_user_unreadreceiver_id, is_read查未读消息permissionperm_id—权限定义如“删除房源”—role_permissionidrole_id,perm_id角色-权限关联管理员可删房源房东不可uk_role_permrole_id, perm_id防重复授权为什么这样设计booking与order分离预订Booking是客人选房动作订单Order是支付动作。二者解耦后支持“先占房后付款”模式——客人提交预订即锁房2小时超时自动释放避免恶意占房。house与room_type一对多同一民宿可有多个房型如“观景大床房”“亲子套房”价格/库存独立管理满足差异化定价需求。user表用role_type字段1管理员2房东3客人而非单独角色表简化JOIN且角色不会频繁变更符合民宿系统读多写少特性。3.2 关键SQL脚本带事务控制的初始化与约束-- 创建数据库指定字符集防中文乱码 CREATE DATABASE homestay_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 用户表统一身份role_type决定权限 CREATE TABLE user ( user_id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, -- BCrypt加密后长度约60 real_name VARCHAR(30), phone VARCHAR(20) NOT NULL UNIQUE, email VARCHAR(100), role_type TINYINT NOT NULL DEFAULT 3 COMMENT 1:admin,2:host,3:guest, status TINYINT NOT NULL DEFAULT 1 COMMENT 0:disabled,1:enabled, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 房源表GIS坐标支持附近搜索 CREATE TABLE house ( house_id BIGINT PRIMARY KEY AUTO_INCREMENT, host_id BIGINT NOT NULL, title VARCHAR(100) NOT NULL, description TEXT, lng DECIMAL(10,8) NOT NULL COMMENT 经度, lat DECIMAL(10,8) NOT NULL COMMENT 纬度, address VARCHAR(200), audit_status TINYINT NOT NULL DEFAULT 0 COMMENT 0:draft,1:pending,2:approved,3:rejected, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_location (lng, lat) -- MySQL 5.7支持地理空间索引 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 订单表状态机设计支持幂等更新 CREATE TABLE order ( order_id VARCHAR(32) PRIMARY KEY COMMENT 雪花算法ID全局唯一, booking_id BIGINT NOT NULL, amount DECIMAL(10,2) NOT NULL, pay_channel TINYINT NOT NULL COMMENT 1:wechat,2:alipay, status TINYINT NOT NULL DEFAULT 0 COMMENT 0:unpaid,1:paid,2:refunded,3:closed, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, pay_time DATETIME NULL, INDEX idx_status_time (status, create_time), CONSTRAINT fk_order_booking FOREIGN KEY (booking_id) REFERENCES booking(booking_id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;参数说明VARCHAR(32)存订单ID不用自增主键改用Snowflake算法生成字符串ID避免暴露业务量如order_id1000001暗示已成交百万单DECIMAL(10,2)存金额金融计算必须用定点数FLOAT会导致0.10.2≠0.3ON DELETE CASCADE当预订单被删关联订单自动清除保证数据一致性INDEX idx_status_time查“超时未支付订单”时WHERE status0 AND create_time ?能走索引避免全表扫描。3.3 初始化测试数据用INSERT SELECT快速构造业务场景-- 插入管理员密码明文admin123实际项目需BCrypt加密 INSERT INTO user (username, password, real_name, phone, role_type, status) VALUES (admin, $2a$10$Zz9QvXqYbKjRcTfGhIeLmNpOqRsTuVwXyZaBcDfEgHiJkLmNoPqRs, 系统管理员, 13800138000, 1, 1); -- 插入测试房东需审核 INSERT INTO user (username, password, real_name, phone, role_type, status) VALUES (landlord1, $2a$10$AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz, 张三, 13900139000, 2, 1); INSERT INTO host (user_id, id_card, business_license, audit_status) VALUES (2, 110101199003072358, 92110101MA0000000A, 1); -- 待审核 -- 插入测试民宿北京三里屯 INSERT INTO house (host_id, title, description, lng, lat, address, audit_status) VALUES (1, 三里屯极简公寓, 步行5分钟到苹果旗舰店落地窗俯瞰国贸, 116.452345, 39.912345, 北京市朝阳区建国路87号, 2); -- 已审核 -- 插入房型大床房库存10间单价580 INSERT INTO room_type (house_id, name, price, stock, description) VALUES (1, 智能大床房, 580.00, 10, 戴森吹风机奈斯派索咖啡机);执行逻辑密码字段用BCrypt加密值$2a$10$...开头非明文存储符合等保要求host_id1对应user_id2的房东体现外键约束lng/lat填北京三里屯真实坐标后续可用ST_Distance_Sphere函数查“5公里内民宿”stock10为初始库存后续通过UPDATE room_type SET stock stock - 1 WHERE room_type_id ? AND stock 0实现乐观锁扣减。4. SSM核心功能实现从“房东发布房源”到“客人支付订单”的代码级落地4.1 房东发布房源MyBatis动态SQL与文件上传的协同需求场景房东登录后在表单填写民宿标题、描述、地址并上传3张实拍图。后端需保存房源基本信息到house表将图片存到服务器/upload/house/目录记录路径到house_image表若任一环节失败整个事务回滚。Controller层HouseController.javaController RequestMapping(/host/house) public class HouseController { Autowired private HouseService houseService; // 使用MultipartFile接收文件RequestParam(images)匹配HTML input name PostMapping(/publish) ResponseBody public Result publishHouse( RequestParam(title) String title, RequestParam(description) String description, RequestParam(lng) BigDecimal lng, RequestParam(lat) BigDecimal lat, RequestParam(address) String address, RequestParam(images) MultipartFile[] images) { // 接收多图 try { // 构建房源对象 House house new House(); house.setTitle(title); house.setDescription(description); house.setLng(lng); house.setLat(lat); house.setAddress(address); house.setAuditStatus(House.AUDIT_PENDING); // 待审核 // 调用服务层传入图片数组 houseService.publishHouse(house, images); return Result.success(发布成功等待审核); } catch (Exception e) { return Result.error(发布失败 e.getMessage()); } } }Service层HouseServiceImpl.javaService Transactional(rollbackFor Exception.class) // 声明式事务异常时回滚 public class HouseServiceImpl implements HouseService { Autowired private HouseMapper houseMapper; Autowired private HouseImageMapper houseImageMapper; Autowired private FileUploadUtil fileUploadUtil; // 自定义文件上传工具类 Override public void publishHouse(House house, MultipartFile[] images) throws IOException { // 1. 保存房源基本信息 houseMapper.insert(house); // 2. 上传图片并保存路径循环处理每张图 for (int i 0; i images.length; i) { MultipartFile image images[i]; if (!image.isEmpty()) { // 生成唯一文件名house_{houseId}_{timestamp}_{originalName} String fileName house_ house.getHouseId() _ System.currentTimeMillis() _ image.getOriginalFilename(); String filePath /upload/house/ fileName; // 保存到磁盘实际项目应存OSS此处本地模拟 fileUploadUtil.saveFile(image, filePath); // 3. 保存图片记录到数据库 HouseImage houseImage new HouseImage(); houseImage.setHouseId(house.getHouseId()); houseImage.setImgUrl(filePath); houseImage.setSortOrder(i 1); // 按上传顺序排序 houseImageMapper.insert(houseImage); } } } }Mapper层HouseMapper.xml!-- HouseMapper.xml -- insert idinsert parameterTypeHouse useGeneratedKeystrue keyPropertyhouseId INSERT INTO house ( host_id, title, description, lng, lat, address, audit_status, create_time ) VALUES ( #{hostId}, #{title}, #{description}, #{lng}, #{lat}, #{address}, #{auditStatus}, NOW() ) /insert关键点说明Transactional(rollbackFor Exception.class)确保houseMapper.insert()和houseImageMapper.insert()在同一个数据库事务中任一失败则全部回滚useGeneratedKeystrue让MySQL返回自增主键house_id供后续图片保存时关联文件名拼接houseId避免不同房源图片同名覆盖System.currentTimeMillis()防并发重名fileUploadUtil.saveFile()内部需检查image.getSize() 5 * 1024 * 10245MB限制防止恶意大文件上传。4.2 客人预订与库存扣减用MySQL行锁解决超卖问题痛点多个客人同时点击“立即预订”同一房型若用SELECT stock FROM room_type WHERE room_type_id ?再UPDATE stock stock - 1必然超卖。正确方案一条SQL完成“查库存扣减”利用MySQL行锁Service层BookingServiceImpl.javaService public class BookingServiceImpl implements BookingService { Autowired private RoomTypeMapper roomTypeMapper; Autowired private BookingMapper bookingMapper; Override public Booking createBooking(Long roomTypeId, Integer peopleNum, LocalDate checkIn, LocalDate checkOut) { // 1. 执行扣减SQL返回影响行数 int affected roomTypeMapper.decreaseStock(roomTypeId, peopleNum); if (affected 0) { throw new RuntimeException(库存不足请选择其他房型); } // 2. 创建预订单此时库存已扣减安全 Booking booking new Booking(); booking.setRoomTypeId(roomTypeId); booking.setPeopleNum(peopleNum); booking.setCheckIn(checkIn); booking.setCheckOut(checkOut); booking.setStatus(Booking.STATUS_CONFIRMED); booking.setCreateTime(new Date()); bookingMapper.insert(booking); return booking; } }Mapper层RoomTypeMapper.xml!-- RoomTypeMapper.xml -- update iddecreaseStock parameterTypemap UPDATE room_type SET stock stock - #{peopleNum} WHERE room_type_id #{roomTypeId} AND stock #{peopleNum} !-- 关键库存充足才更新 -- /update原理剖析UPDATE ... WHERE stock ?语句会为满足条件的行加排他锁X锁其他事务无法修改该行直到本事务提交若stock5两个请求同时peopleNum3第一个请求成功扣减stock2第二个请求因23为falseaffected0抛出库存不足异常不用SELECT ... FOR UPDATE避免在应用层判断库存后再更新减少网络往返且FOR UPDATE在RR隔离级别下可能引发间隙锁死锁。4.3 订单支付状态同步用定时任务补偿支付网关的异步通知现实问题微信/支付宝支付成功后会异步回调你的/api/pay/notify接口。但网络抖动可能导致回调丢失或你的服务器正在重启没收到。解决方案支付创建后启动定时任务每5分钟扫描order表中status0未支付且create_time超30分钟的订单调用微信订单查询API确认状态。定时任务配置spring-task.xml!-- spring-task.xml -- task:annotation-driven/ bean idpayCheckTask classcom.homestay.task.PayCheckTask/ task:scheduled-tasks task:scheduled refpayCheckTask methodcheckUnpaidOrders cron0 0/5 * * * ?/ !-- 每5分钟执行一次 -- /task:scheduled-tasks任务实现PayCheckTask.javaComponent public class PayCheckTask { Autowired private OrderService orderService; Autowired private WechatPayService wechatPayService; // 封装微信SDK public void checkUnpaidOrders() { // 查询30分钟前创建的未支付订单 Date cutoffTime DateUtils.addMinutes(new Date(), -30); ListOrder unpaidOrders orderService.findUnpaidBefore(cutoffTime); for (Order order : unpaidOrders) { try { // 调用微信订单查询接口 WechatOrderQueryResult result wechatPayService.queryOrder(order.getOrderId()); if (SUCCESS.equals(result.getTradeState())) { // 微信显示已支付更新本地订单状态 orderService.updateOrderStatus(order.getOrderId(), Order.STATUS_PAID, result.getSuccessTime()); } else if (NOTPAY.equals(result.getTradeState())) { // 仍为未支付跳过下次再查 continue; } else { // 其他状态如CLOSED标记为关闭 orderService.updateOrderStatus(order.getOrderId(), Order.STATUS_CLOSED, null); } } catch (Exception e) { // 记录错误日志不影响其他订单处理 log.error(查询订单{}状态失败, order.getOrderId(), e); } } } }关键设计cron0 0/5 * * * ?固定每5分钟触发不依赖服务器时间精度DateUtils.addMinutes(new Date(), -30)用Apache Commons Lang的DateUtils避免Calendar线程不安全问题try-catch包裹单个订单处理一个订单查询失败不影响其他订单提升鲁棒性微信trade_state为SUCCESS才更新状态NOTPAY保持原状避免误判。5. 避坑指南SSMMySQL民宿系统上线前必须排查的5个血泪问题5.1 现象Tomcat启动报错java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation原因spring-core与spring-webmvc版本不一致。例如spring-core用了5.3.32但spring-webmvc误用5.2.22后者没有findMergedAnnotation方法该方法在5.3.x新增。解决检查pom.xml中所有Spring依赖版本号是否完全一致用IDEA的Maven Helper插件可视化依赖树排除传递依赖冲突。5.2 现象民宿列表页地图坐标显示错位所有房源挤在北京六环外原因MySQL中lng经度、lat纬度字段类型为DECIMAL(10,8)但Java实体类中定义为Double插入时精度丢失。例如116.45234567存入Double变成116.45234567000001ST_Distance_Sphere计算距离时偏差放大。解决Java实体类中lng/lat字段必须用BigDecimalMyBatis TypeHandler确保BigDecimal与DECIMAL精准映射。5.3 现象房东后台上传图片后页面显示404但服务器/upload/house/目录下文件存在原因SpringMVC未配置静态资源映射。web.xml中url-pattern//url-pattern导致所有请求包括/upload/house/xxx.jpg都进入DispatcherServlet而DispatcherServlet找不到对应Controller返回404。解决在springmvc.xml中添加mvc:resources mapping/upload/** location/upload/ / mvc:default-servlet-handler/ !-- 放行所有静态资源 --并确保Tomcat的server.xml中Context docBase指向项目根目录使/upload/路径可被Web容器直接访问。5.4 现象高并发预约时room_type表出现大量Waiting for table metadata lock原因ALTER TABLE room_type ADD COLUMN xxx等DDL操作持有MDLMetadata Lock阻塞了所有DML如UPDATE stock。民宿系统上线后运维人员执行了在线DDL导致预订接口大面积超时。解决生产环境禁止直接执行DDL改用pt-online-schema-change工具应用层增加熔断机制当UPDATE room_type执行超时如2s立即返回“系统繁忙”避免线程池耗尽监控information_schema.PROCESSLIST发现StateWaiting for table metadata lock及时告警。5.5 现象MySQL慢查询日志中SELECT * FROM booking WHERE user_id ? ORDER BY create_time DESC LIMIT 0,10执行超5秒原因booking表数据量达50万user_id字段无索引ORDER BY create_time无法利用索引排序触发filesort。解决添加联合索引ALTER TABLE booking ADD INDEX idx_user_time (user_id, create_time);验证索引有效性EXPLAIN SELECT * FROM booking WHERE user_id 123 ORDER BY create_time DESC LIMIT 10;查看typeref且ExtraUsing index condition分页优化将LIMIT 0,10改为WHERE create_time ? ORDER BY create_time DESC LIMIT 10游标分页避免深度分页性能衰减。6. 进阶技巧用Redis缓存热点数据把民宿首页加载速度从2.3秒压到380毫秒6.1 识别缓存Key哪些数据适合放Redis——遵循“读多写少、实时性要求不高”原则民宿系统中以下数据天然适合缓存首页推荐民宿列表运营人员每周更新一次但用户每秒请求数百次热门城市房源数统计北京/上海/广州的在售民宿数量变化频率低房东认证状态host.audit_status为2已审核后基本不变用户权限菜单用户登录后其角色对应的菜单树如管理员看到“系统设置”房东看不到不适合缓存的数据room_type.stock库存实时变动缓存会导致超卖order.status支付状态需绝对准确不能有秒级延迟review.score新评价需即时反映在房源评分上。提示不要缓存SELECT * FROM house全量数据按业务场景缓存聚合结果如hot_houses_beijing北京热门民宿ID列表再用IN批量查详情避免大Value拖垮Redis。6.2 缓存策略落地用Spring Cache RedisTemplate实现两级缓存第一步配置Redis连接spring-redis.xml!-- 连接池配置 -- bean idjedisPoolConfig classredis.clients.jedis.JedisPoolConfig property namemaxTotal value100/ property namemaxIdle value20/ property nameminIdle value5/ property nametestOnBorrow valuetrue/ /bean !-- Redis连接工厂 -- bean idjedisConnectionFactory classorg.springframework.data.redis.connection.jedis.JedisConnectionFactory property namehostName value127.0.0.1/ property nameport value6379/ property namedatabase value0/ property namepool p a hrefhttps://download.csdn.net/download/python0328/90052670 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表