PageHelper的一个大坑 | 网页不断刷新请求

在使用PageHelper进行MyBatis分页查询时,若查询结果为空集,可能导致前端页面不断刷新,引起服务器安全风险。问题源于PageHelper在空集合情况下的处理。解决方案是对查询结果进行判断,避免调用PageInfo时产生循环请求。通过全局异常处理或在Service层直接处理空集合,可以临时缓解此问题。

PageHelper的一个大坑 | 网页不断刷新请求

最近再写一个后台管理项目的时候,对于某个字段的模糊查询加上借助pagehelper插件的分页功能时,产生了网页持续刷新的情况,此时客户端向服务端不断地发送大量请求,对于服务器安全有较大的威胁。

一、问题起源

在使用MyBatis进行数据库操作时,为了图方便使用了Example类,其中有一段涉及到分页的查询代码如下:

@Override
public PageInfo<Course> getCourseListByPage(SearchVo searchVo) {
    CourseExample example = new CourseExample();
    CourseExample.Criteria criteria = example.createCriteria();
    if (null != searchVo.getKeyword() && "" != searchVo.getKeyword())
        criteria.andCourseNameLike("%" + searchVo.getKeyword() + "%");
    PageHelper.startPage(searchVo.getPageNum(), searchVo.getPageSize());
    List<Course> courses = courseMapper.selectByExample(example);
    PageInfo<Course> info = new PageInfo<>(courses);
    return info;
}

SearchVo中只有三个属性,当前页pageNum、每页大小pageSize以及模糊查询时使用的关键字keyword,模糊查询的关键字通过搜索框输入并提交。

在这里插入图片描述
如上图,当输入的模糊查询字段不存在匹配的对象时,查询出的集合理所当然是一个空集合,这个时候如果用pagehelper分页,前端页面便会不断地刷新,不断地请求服务端,而服务端也不停地进行数据库访问操作。

二、查找问题所在

1.URL书写错误导致循环请求

一开始对于该问题我以为是前端页面与Controller层的请求循环转发的原因,于是不断的查找每一个URL,经过多次比对后,算是确定URL并没有出现问题。

2.Example类使用不当

由于Example类平时开发时使用较少,所以存在不确定因子,于是怀疑可能是Example类的问题。于是修改了Service层代码,采用自己手写Mapper来进行模糊查询。
Mapper:

<select id="findAllCourse" parameterType="com.daiki.edu.vo.SearchVo" resultMap="BaseResultMap">
      SELECT *
      FROM course
      <where>
          <if test="null!=keyword and ''!=keyword">
              and course_name LIKE concat('%', #{keyword}, '%')
          </if>
      </where>
  </select>

Service:

@Override
public PageInfo<Course> getCourseListByPage(SearchVo searchVo) {
    PageHelper.startPage(searchVo.getPageNum(), searchVo.getPageSize());
    List<Course> courses = courseMapper.findAllCourse(searchVo);
    PageInfo<Course> info = new PageInfo<>(courses);
    return info;
}

再次进行查询,结果和之前一样,当提交的keyword无法匹配到任何一条记录时,pagehelper执行的SQL语句返回的集合为空时,网页依旧频繁的不断刷新,不断向服务器发起请求。

三、结论

综合上述测试,个人认为该问题是Pagehelper的一个缺陷,在使用pagehelper插件时,如果在PageHelper.startPage()函数后面紧跟的SQL语句查询的结果集为空集时,浏览器会不断的循环发起请求。

四、解决方案

对于该问题,目前我个人在网上搜索和官网查询都没有发现有相似的问题分享以及解决方案。对于这个问题的解决,最希望的是在pagehelper插件的源码中加上对查询结果集为空时的处理方案,这样是最好的。
但对于只是临时需要组织该问题造成的对服务器进行大量请求的行为,那么可以对SQL查询的结果集进行一次判断,让其绕过PageInfo例如通过全局异常处理来反馈错误信息。简单示例代码如下:

 @Override
 public PageInfo<Course> getCourseListByPage(SearchVo searchVo) throws Exception {
     PageHelper.startPage(searchVo.getPageNum(), searchVo.getPageSize());
     List<Course> courses = courseMapper.findAllCourse(searchVo);
     if (courses.size() > 0) {
         PageInfo<Course> info = new PageInfo<>(courses);
         return info;
     } else {
         throw new Exception("查无此结果!");
     }
 }

如果有不对的地方欢迎指正,插件本身如果有原生的解决方案望各位指正!

<think> 我们正在讨论的是地形生成软件 Gaea(通常用于游戏开发和虚拟环境创建),而不是小米的数据库中间件(引用[4])。用户的问题是在Gaea软件中如何制作圆形大坑。 根据引用[1]中的信息,Gaea插件在Godot中用于生成地形,但没有直接说明如何制作圆形大坑。引用[2]提到Gaea提供了一系列基础节点,包括控制地形轮廓、细节纹理、侵蚀、雪水效果等。引用[3]则提到Gaea与其他软件(如Houdini和Unreal)的集成。 虽然引用中没有直接给出制作圆形大坑的步骤,但我们可以根据地形生成的通用方法以及Gaea的特性来推断。 在Gaea中,地形通常是由节点组成的流程图(称为graph)来生成的。制作一个圆形大坑,我们可以考虑使用以下节点: 1. **基础形状节点(如平面或噪声)**:首先创建一个基础地形,比如一个平面。 2. **圆形遮罩(Circle Mask)**:使用一个圆形遮罩节点来定义圆形区域。 3. **侵蚀节点(Erosion)** 或 **凹陷节点(Depression)**:利用遮罩来控制凹陷的区域,从而形成坑。或者我们可以使用一个负值的凸起来模拟凹陷(即反向操作)。 4. **组合节点(Combine)**:将生成的坑与基础地形组合。 另一种方法是使用一个圆形形状节点(Circle Shape)作为基础,然后将其反转(正地形变成负地形)从而形成坑。或者使用高度图操作,将圆形区域的高度值降低。 具体步骤可能如下: 步骤1:创建一个基础平面(Flat)。 步骤2:创建一个圆形(Circle)节点,并将其作为遮罩。调整圆形的位置和大小以达到所需的大坑位置和范围。 步骤3:使用一个侵蚀节点(Erosion)或者直接使用高度混合(Blend)节点,将圆形区域的高度降低。我们可以用一个负值的斜坡(Ramp)节点来创建坑的深度变化。 详细步骤: 1. 在Gaea中新建一个图(Graph)。 2. 添加一个“平面”(Flat)节点作为基础地形。 3. 添加一个“圆形”(Circle)节点,调整其半径(Radius)以确定坑的大小,位置(Position)设置坑的中心位置。这个圆形节点将作为遮罩。 4. 添加一个“高度场运算”(Heightfield Math)节点或“混合”(Blend)节点。将平面节点连接到混合节点的背景(Background)输入,然后设置混合模式为“减去”(Subtract)或直接用数学运算节点进行减法。注意,我们需要将圆形节点连接到混合节点的遮罩(Mask)输入。 5. 在混合节点中,我们可以设置一个深度值(即减去的量),这样就会在圆形区域内降低高度,形成坑。 另一种方法是使用“斜坡”(Ramp)节点来创建一个凹陷的形状,然后将其与基础地形混合。具体如下: 1. 创建一个“斜坡”(Ramp)节点,将其形状设置为圆形凹陷(例如,一个倒圆锥形)。在斜坡节点中,可以选择渐变类型为径向(Radial),然后调整渐变曲线使其中间低四周高。 2. 将基础平面和这个斜坡节点通过混合节点(Blend)结合,使用添加(Add)模式?不对,应该是用减法?实际上,如果我们创建的斜坡节点是中间低,那么直接加到基础平面上会使得平面中间出现凹陷。但通常基础平面是平的,所以我们需要将斜坡节点的值取负,然后加上去?或者用混合节点的减法。 更简单的方法: 使用“凹陷”(Crater)节点?但是Gaea中是否有专门制作坑的节点呢?根据引用[2]中提到的节点多样性,我们可以推测可能有直接生成坑的节点,但如果没有,我们可以用上述方法。 考虑到Gaea的节点式工作流,我们可以这样: 1. 创建一个平面(Flat)。 2. 创建一个圆形(Circle)节点作为遮罩。 3. 创建一个高度场运算(Heightfield Math)节点,操作选择为“减去”(Subtract),输入值设为一定量(比如-100),然后将平面节点连接到高度场运算节点的输入,将圆形节点连接到高度场运算节点的遮罩(Mask)输入。这样,在圆形区域内,高度会减去100,形成一个深度为100的坑。 但是这样的坑是平底的,如果想做成有坡度的坑,我们可以: 4. 在高度场运算之前,用一个渐变(Gradient)节点或者斜坡(Ramp)节点来生成一个圆形的坡度,然后通过乘法节点与圆形遮罩结合,再用减法节点减去这个有坡度的形状。这样就能形成有坡度的坑。 具体步骤: 1. 创建平面(Flat)。 2. 创建圆形(Circle)节点。 3. 创建渐变(Gradient)节点,类型为径向(Radial),调整渐变曲线使得中心为0,边缘为1(这样从中心到边缘高度逐渐增加)。 4. 将圆形节点连接到渐变节点的遮罩(Mask)输入,这样渐变节点就只在圆形区域内有效。 5. 用一个乘法(Multiply)节点,将渐变节点与一个常量(Constant)节点(比如值设为-50)相乘,得到从0到-50变化的高度图(中心最低为-50,边缘为0)。 6. 将平面节点和这个乘法节点的输出通过混合节点(Blend)的相加(Add)模式组合(因为乘法节点输出的是负值,所以相当于平面减去这个形状)。 这样我们就得到了一个圆形的坑,坑底是平的?实际上,由于渐变是连续的,所以坑底是锥形的(从中心到边缘坡度连续变化)。 如果我们想要一个碗状的坑(即曲线坡度),可以调整渐变节点的曲线为曲线形状(例如,指数曲线)。 总结:在Gaea中,制作圆形大坑的基本思路是使用圆形遮罩配合高度调整(通常是降低高度)来实现。具体操作可以使用多个节点组合,包括平面、圆形、渐变、数学运算和混合节点。 由于引用中没有直接给出步骤,以上是基于地形生成的通用原理和Gaea节点式工作流的推理。 如果用户需要更具体的步骤,可能需要参考Gaea的官方文档或教程,因为节点名称和操作可能因版本而异。 下面是一个节点流程图的示例: ``` 基础平面(Flat) --> 混合节点(Blend)[背景] 圆形(Circle) --> 渐变(Gradient:径向)[遮罩] --> 乘法(Multiply:乘以常量-50) --> 混合节点(Blend)[前景] 混合节点输出最终地形(圆形大坑) ``` 注意:混合节点使用相加(Add)模式,因为乘法节点输出的是负值,所以相当于在基础平面上减去一个圆形的渐变形状,从而形成坑。 此外,用户还可以在坑的周围添加侵蚀效果(Erosion)来使坑更加自然。 相关问题: 1. Gaea中如何调整坑的深度和半径? 2. 如何在Gaea中制作不规则的坑? 3. Gaea中的侵蚀节点如何应用于坑的边缘使其更自然? 注意:我们引用的内容中并没有直接关于制作圆形大坑的步骤,因此以上回答是根据地形生成的通用知识和Gaea的工作流推断的。如果有更具体的引用信息,应优先参考。 </think> 在 Gaea 软件中创建圆形大坑的方法主要基于高度图编辑和节点工作流实现。以下是详细步骤和技术要点: ### 核心制作方法 1. **基础地形生成** - 使用`平面生成器`(Flat)或`噪声生成器`(Noise)创建基础地形 - 通过`大小参数`设置地形尺寸(例如1000×1000单位) 2. **创建圆形遮罩** ```python # 伪节点流程示例 CircleMask → AdjustRadius(500) → PositionCenter(X:0,Y:0) ``` - 关键参数: - `半径`(Radius):控制坑洞直径 - `边缘羽化`(Feather):15%-30%实现平滑过渡 - `高度衰减曲线`:指数曲线实现坑底平坦效果 3. **地形凹陷处理** - 使用`高度场运算`节点: ```python HeightfieldMath(Operation: Subtract, Value: -300) ``` - 或通过`侵蚀模拟器`: ```python ErosionNode(ErosionType: Hydraulic, Iterations: 50) ``` 4. **进阶效果优化** - 坑壁纹理:叠加`岩石噪声`(RockNoise)和`滑坡效果`(Landslide) - 坑底细节:添加`碎石分布`(DebrisScatter)和`积水效果`(WaterSimulation) - 边缘融合:使用`地形混合器`(TerrainBlender)平滑过渡 ### 参数建议表 | 参数项 | 推荐值 | 效果说明 | |---------------|-----------|--------------------------| | 坑洞深度 | -200~-500 | 负值越大坑越深 | | 羽化范围 | 15%-30% | 边缘过渡自然度 | | 侵蚀迭代次数 | 30-70 | 坑壁自然侵蚀效果强度 | | 底部粗糙度 | 0.3-0.6 | 坑底不规则程度 | ### 应用技巧 1. **分层制作法**:创建嵌套的同心圆坑形成阶梯状地质结构 2. **动态生成**: ```python # Godot引擎集成示例 generator.set_mask_shape("CIRCLE") generator.set_depression_depth(-400) ``` 3. **物理模拟**:启用`粒子侵蚀系统`模拟雨水冲刷效果[^2],使坑壁形成自然沟壑 > **最佳实践**:对复杂坑洞系统使用`区块加载技术`(ChunkLoader)优化性能,大型场景建议分区块生成后拼接[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值