了解公司的网站南京需要做网站的公司

张小明 2025/12/29 18:49:03
了解公司的网站,南京需要做网站的公司,手机建站图片,网站地址查询网苍穹外卖项目复习笔记 一、 MyBatis-Plus (MP) 核心应用 这部分是开发数据持久层的核心#xff0c;重点在于理解MP如何简化开发以及如何处理复杂场景。 1. 基础 CRUD 与架构关系 BaseMapper vs ServiceImpl : BaseMapperT: 位于DAO层。提供了最底层的数据库原子操作重点在于理解MP如何简化开发以及如何处理复杂场景。1. 基础 CRUD 与架构关系BaseMapper vs ServiceImpl :BaseMapperT: 位于DAO层。提供了最底层的数据库原子操作insert, deleteById, update, selectList等。直接操作数据库。ServiceImplM, T: 位于Service层。实现了IServiceT接口内部默认注入了BaseMapper。它在BaseMapper的基础上进行了封装提供了更高级的业务逻辑支持如批量操作、链式调用。总结: 简单SQL直接调Mapper复杂业务逻辑或批量操作调Service。2. 分页查询单表分页:配置: 必须配置MybatisPlusInterceptor并添加PaginationInnerInterceptor拦截器否则分页无效只会查全部。实现: 使用PageT对象作为参数传入BaseMapper的查询方法中。多表关联分页查询:难点: MP的Wrapper主要针对单表。解决: 手写SQLXML或注解。关键: 只要Service方法定义的第一个参数是Page对象MP拦截器会自动拦截该SQL执行SELECT count(0)查询总数然后注入LIMIT语句无需手动写分页逻辑。具体实现自定义 SQL (XML 方式) —— 推荐核心思路编写一个 SQL使用LEFT JOIN连接菜品表和分类表直接查出你需要的所有字段让 MP 帮你做分页。定义 DishVO, 确保你的 DishVO 里有 categoryName 字段。DatapublicclassDishVOextendsDish{// 继承了 Dish 的所有属性// 额外添加分类名称privateStringcategoryName;// 可能还需要口味列表根据你的业务需求决定是否在这里查或者分开查// private ListDishFlavor flavors;}修改 Mapper 接口在DishMapper.java中定义一个方法。 注意入参必须包含 IPageMP 会自动识别它并进行分页拦截。返回值也是 IPage。MapperpublicinterfaceDishMapperextendsBaseMapperDish{/** * 自定义分页查询 DishVO * param page MP 分页对象必须作为第一个参数 * param dishPageQueryDTO 查询条件 * return 分页结果 */PageDishVOpageQuery(IPageDishVOpage,Param(dto)DishPageQueryDTOdishPageQueryDTO);}编写 Mapper XML在DishMapper.xml中编写 SQL。mapper namespacecom.sky.mapper.DishMapper select idpageQuery resultTypecom.sky.vo.DishVO SELECT d.*, c.name AS category_name FROM dish d LEFT JOIN category c ON d.category_id c.id where if testdto.name ! null and dto.name ! AND d.name LIKE CONCAT(%, #{dto.name}, %) /if if testdto.categoryId ! null AND d.category_id #{dto.categoryId} /if if testdto.status ! null AND d.status #{dto.status} /if /where ORDER BY d.create_time DESC /select /mapperService 层调用直接调用 Mapper 即可非常简洁。Override public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) { // 1. 准备分页对象 PageDishVO page new Page(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize()); // 2. 调用 Mapper 自定义方法 // MP 会自动执行两条 SQL // 第一条SELECT COUNT(*) ... LEFT JOIN ... // 第二条SELECT d.*, c.name ... LEFT JOIN ... LIMIT ?, ? PageDishVO voPage dishMapper.pageQuery(page, dishPageQueryDTO); // 3. 封装结果 return new PageResult(voPage.getTotal(), voPage.getRecords()); }3. 批量操作与链式调用 (Point 6)批量操作: 使用IService接口提供的方法如saveBatch(ListT)或updateBatchById(ListT)。底层是基于JDBC的batch操作性能优于循环调用Mapper。链式调用 (LambdaQueryChainWrapper):场景: 避免创建繁琐的Wrapper对象。写法:lambdaQuery().eq(User::getId, id).one();优点: 代码更优雅可读性更强。4. 公共字段填充 (Point 4)MP 原生方式 (MetaObjectHandler):原理: 实现MetaObjectHandler接口重写insertFill和updateFill方法。配置: 在实体类字段上添加TableField(fill FieldFill.INSERT)等注解。场景: 适用于纯数据库层面的统一赋值如create_time, update_time。为什么推荐 MetaObjectHandler更底层 它直接介入 MyBatis-Plus 的 CRUD 操作是专门为数据填充设计的。更简单 避免了复杂的 AOP 反射和切入点配置。更清晰 逻辑集中在一个处理器类中明确区分了插入和更新两种场景。实现步骤步骤 1创建元对象处理器创建一个类继承自com.baomidou.mybatisplus.core.handlers.MetaObjectHandler并实现insertFill和updateFill方法。importcom.baomidou.mybatisplus.core.handlers.MetaObjectHandler;importorg.apache.ibatis.reflection.MetaObject;importorg.springframework.stereotype.Component;importjava.time.LocalDateTime;ComponentpublicclassMyMetaObjectHandlerimplementsMetaObjectHandler{// 假设您有一个工具类来获取当前用户IDprivateLonggetCurrentUserId(){// 实际应用中从 ThreadLocal 或 SecurityContext 获取当前登录用户IDreturn1L;// 示例值}/** * 插入操作时自动填充 */OverridepublicvoidinsertFill(MetaObjectmetaObject){// 1. 填充创建时间if(metaObject.hasSetter(createTime)){this.strictInsertFill(metaObject,createTime,LocalDateTime.class,LocalDateTime.now());}// 2. 填充创建人if(metaObject.hasSetter(createUser)){this.strictInsertFill(metaObject,createUser,Long.class,getCurrentUserId());}// 3. 插入时通常也填充更新时间和更新人if(metaObject.hasSetter(updateTime)){this.strictInsertFill(metaObject,updateTime,LocalDateTime.class,LocalDateTime.now());}if(metaObject.hasSetter(updateUser)){this.strictInsertFill(metaObject,updateUser,Long.class,getCurrentUserId());}}/** * 更新操作时自动填充 */OverridepublicvoidupdateFill(MetaObjectmetaObject){// 1. 填充更新时间if(metaObject.hasSetter(updateTime)){this.strictUpdateFill(metaObject,updateTime,LocalDateTime.class,LocalDateTime.now());}// 2. 填充更新人if(metaObject.hasSetter(updateUser)){this.strictUpdateFill(metaObject,updateUser,Long.class,getCurrentUserId());}}}步骤2在实体类上添加注解在您的实体类如Employee中只需在需要自动填充的字段上添加TableField注解指定填充策略。importcom.baomidou.mybatisplus.annotation.FieldFill;importcom.baomidou.mybatisplus.annotation.TableField;importjava.time.LocalDateTime;publicclassEmployee{// ... 其他字段TableField(fillFieldFill.INSERT)privateLocalDateTimecreateTime;TableField(fillFieldFill.INSERT)privateLongcreateUser;// 插入和更新时都需要填充TableField(fillFieldFill.INSERT_UPDATE)privateLocalDateTimeupdateTime;TableField(fillFieldFill.INSERT_UPDATE)privateLongupdateUser;}AOP 方式:原理: 自定义注解 Aspect切面。在切面中通过反射给参数对象的属性赋值。场景: 适用于需要获取上下文信息如从ThreadLocal获取当前登录用户的ID并填充到实体的场景。苍穹外卖中常结合两者使用。苍穹外卖中AOP机制的分析切面配置使用了前置通知和一个非常精确的 切入点表达式。A. 切面类AutoFillAspect在项目中AutoFillAspect 是一个使用 Aspect 注解的 Spring Bean。它很可能使用了 前置通知 (Before) 来实现公共字段填充。执行逻辑 在 Mapper 方法执行之前通过反射获取方法参数通常是实体对象然后根据当前操作类型INSERT 或 UPDATE和当前登录的用户信息为实体对象的 createTime、createUser、updateTime、updateUser 字段赋值。B. 切入点表达式解析切入点表达式是com.sky.mapper.*.*(..) annotation(com.sky.annotation.autoFill)\text{com.sky.mapper.*.*(..) \\ annotation(com.sky.annotation.autoFill)}com.sky.mapper.*.*(..) annotation(com.sky.annotation.autoFill)方法匹配部分com.sky.mapper.*.*(..)com.sky.mapper.*: 匹配 com.sky.mapper 包下的所有类 (通常是 Mapper 接口)。.*(…): 匹配这些类中的所有方法 (方法名和参数数量不限)。效果 限制了切面只在 mapper 包下的方法上查找连接点。注解匹配部分annotation(com.sky.annotation.autoFill)annotation(...): 匹配所有被括号内指定的注解标注的方法。效果 只有当 com.sky.mapper 包下的某个方法同时被AutoFill注解标记时切面才会被织入。总结 只有当您在 Mapper 接口中定义的方法如 insert 或 update 方法上同时使用了AutoFill注解时AutoFillAspect 的逻辑才会在该方法执行时被触发。二、 架构设计与难点解决这部分涉及企业级开发的规范和常见“坑”的解决方案。1. 雪花算法精度丢失问题现象: 后端ID为Long类型19位前端JS的Number类型最大安全整数是253−12^{53}-1253−1约16位。传递到前端时后几位会被四舍五入导致ID不一致。解决方案:后端将Long转为String传输。实现方式:局部处理: 在实体类ID字段上加注解JsonSerialize(using ToStringSerializer.class)。全局处理: 配置Jackson的消息转换器 (MappingJackson2HttpMessageConverter)将所有Long类型序列化为String。2. 企业级文件上传设计技术栈: 阿里云 OSS (Object Storage Service)。设计模式:XXXProperties: 使用ConfigurationProperties读取application.yml中的配置endpoint, key, secret, bucket实现配置与代码分离。XXXConfiguration: 使用Configuration和Bean利用Properties创建OSS客户端对象交给Spring容器管理。接口设计: 定义标准的FileStorageService接口包含upload方法。多实现类: 如果未来切换到腾讯云COS或MinIO只需新增实现类并修改配置无需修改业务代码符合开闭原则。三、 中间件集成 (Redis)StringRedisTemplate vs RedisTemplate特性RedisTemplateStringRedisTemplate序列化方式默认使用JdkSerializationRedisSerializer默认使用StringRedisSerializer存储格式二进制流乱码状不可读纯字符串清晰可读占用空间较大包含类信息较小适用场景存储复杂的Java对象且不关心Redis中数据的可读性存储简单的KV结构或者需要与其他语言交互或者需要人工排查Redis数据推荐一般不推荐直接用默认的。通常会自定义配置JSON序列化器。推荐使用。手动将对象转为JSON字符串存入取出来再转回对象。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

怎样创建网站的基本流程15年做哪个网站能致富

目录 1.二叉树的层序遍历 a.核心思想 b.思路 c.步骤 2.C语言函数指针和指针函数的区别 a.函数指针 b.指针函数 c.核心区别 1.二叉树的层序遍历 102. 二叉树的层序遍历 - 力扣(LeetCode)https://leetcode.cn/problems/binary-tree-level-order-t…

张小明 2025/12/29 18:42:55 网站建设

做网站去哪里找广告主关键词在线挖掘网站

索尼相机逆向工程工具:5个实用功能完全指南 【免费下载链接】Sony-PMCA-RE Reverse Engineering Sony Digital Cameras 项目地址: https://gitcode.com/gh_mirrors/so/Sony-PMCA-RE 索尼相机逆向工程工具(Sony-PMCA-RE)是一款专为索尼…

张小明 2025/12/29 18:40:54 网站建设

新闻门户网站建设方案厦门网站建设商家

Langchain-Chatchat 能否部署在 Kubernetes 集群中? 在企业智能化转型的浪潮中,如何安全、高效地构建基于私有知识库的智能问答系统,成为越来越多组织关注的核心议题。尤其是在金融、医疗、法律等对数据敏感性要求极高的行业,将大…

张小明 2025/12/29 18:38:48 网站建设

电力公司在哪个网站做推广最好工商查询系统

第一章:MCP续证Agent开发考核标准概述在MCP(Microsoft Certified Professional)续证过程中,Agent开发能力的考核成为评估开发者技术实践水平的重要组成部分。该考核聚焦于自动化代理程序的设计、实现与集成能力,要求开…

张小明 2025/12/29 18:36:43 网站建设

分类信息网站程序用图片做简单网站

高可用性集群与安装服务器搭建指南 1. 高可用性集群故障排查 在搭建高可用性集群时,可能会遇到集群服务无法正常运行的情况。以下是一些排查和解决问题的方法: - 检查日志文件 :集群会在 /var/log/cluster 目录下写入许多日志,其中可能包含服务无法正常工作的重要线…

张小明 2025/12/29 18:32:40 网站建设

青岛做网站排名网站如何做ins链接分享

推荐系统如何“实时进化”?揭秘在线学习的底层逻辑与工程实践你有没有想过,为什么抖音能“猜中”你下一个想看的视频?为什么淘宝总在你刚想起某件商品时就把它推到首页?这背后的关键,并不只是一个强大的离线模型&#…

张小明 2025/12/29 18:28:34 网站建设