浪花 - 主页开发

一、简易版主页

1. 主页展示用户列表

<template>
  <!--推荐用户列表-->
  <van-card
      v-for="user in userList"
      :desc="user.profile"
      :title="`${user.username}(${user.planetCode})`"
      :thumb="user.avatarUrl"
  >
    <template #tags>
      <van-tag plain type="danger" v-for="tag in user.tags" style="margin-right: 5px; margin-top: 3px">
        {{ tag }}
      </van-tag>
    </template>
    <template #footer>
      <van-button size="small">联系我</van-button>
    </template>
  </van-card>
  <van-empty v-if="!userList || userList.length < 1" description="结果为空" />

</template>

<script setup lang="ts">
import { useRoute } from'vue-router'
import {onMounted, ref} from "vue";
import myAxios from "/src/plugins/myAxios.js";
import qs from 'qs';
import type {UserType} from "@/models/user";


const route = useRoute();
const { tags } = route.query;
const userList = ref([]);

onMounted( async () => {
  const userListData: UserType[] = await myAxios.get('/user/recommend', {
    params: {
      tagNameList: tags,
    },
    paramsSerializer: params => {
      return qs.stringify(params, {indices: false})
    }
  })
      .then(function (response) {
        // handle success
        console.log("/user/recommend succeed", response);
        return response.data;
      })
      .catch(function (error) {
        console.log("/user/recommend error", error);
      })
  if(userListData) {
    userListData.forEach(user => {
      if(user.tags) {
        user.tags = JSON.parse(user.tags);
      }
    });
    userList.value = userListData;
  }
})


</script>

<style scoped>

</style>

2. 抽取卡片组件

  • 搜索结果页和主页的组件重复,提取出 Card 卡片组件,方便后续统一修改样式等操作
  • 注意抽取出来的组件用到了哪些变量:将变量转化为属性,再通过父组件传递属性
  • 使用 withDefaults 添加默认值:增强健壮性(userList 为空时也能正常运行)
<template>
  <!--推荐用户列表-->
  <user-card-list :user-list="userList"/>
  <van-empty v-if="!userList || userList.length < 1" description="结果为空" />
</template>
<template>
  <!--推荐用户列表-->
  <van-card
      v-for="user in userList"
      :desc="user.profile"
      :title="`${user.username}(${user.planetCode})`"
      :thumb="user.avatarUrl"
  >
    <template #tags>
      <van-tag plain type="danger" v-for="tag in user.tags" style="margin-right: 5px; margin-top: 3px">
        {{ tag }}
      </van-tag>
    </template>
    <template #footer>
      <van-button size="small">联系我</van-button>
    </template>
  </van-card>
</template>

<script setup lang="ts">
import type {UserType} from "@/models/user";

interface UserCardListProps {
  userList: UserType[];
}

const props = withDefaults(defineProps<UserCardListProps>(), {
  userList: [],
})

</script>

<style scoped>

</style>

3. 后端返回所有用户

    /**
     * 用户推荐
     * @param request
     * @return 用户列表
     */
    @GetMapping("/recommend")
    public BaseResponse<List<User>> recommendUsers(HttpServletRequest request) {
        log.info("推荐用户列表");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        List<User> userList = userService.list(queryWrapper);// 查询所有用户

        // 返回脱敏后的用户数据
        List<User> list = userList.stream().map(user -> userService.getSafetyUser(user)).collect(Collectors.toList());
        return ResultUtils.success(list);
    }

4. 查看页面效果

二、批量导入数据的几种方式

1. 用可视化界面

  • 适合一次性导入、数据量可控

2. 执行 SQL 语句

  • 适用于数据量较小的

3. 编写程序控制导入

  • for 循环,建议分批,要保证可控、幂等性,注意线上数据库和测试数据库有区别
  • 一次性任务:在程序入口使用 @EnableScheduling 开启 SpringBoot 框架对定时任务的支持
  • 执行任务
    • 不能使用 main 方法来执行:SpringBoot 还没有加载这个 Bean,会报空指针异常
    • 使用定时任务框架:在定时任务上使用 @Scheduled 注解设置定时
    • initialDelay:第一次延时执行
    • fixedRate:下一次执行任务的延时时间(设置为 Long.MAX_VALUE 可视为只执行一次)
package com.example.usercenter.once;

import com.example.usercenter.mapper.UserMapper;
import com.example.usercenter.model.domain.User;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;

/**
 * 导入用户任务
 * @author Ghost
 * @version 1.0
 */
@Component
public class InsertUsers {

    @Resource
    private UserMapper userMapper;

    /**
     * 批量插入用户
     */
//    @Scheduled(initialDelay = 5000, fixedRate = Long.MAX_VALUE)
    public void doInsertUsers() {
        StopWatch stopWatch = new StopWatch();
        System.out.println("goodgoodgood");
        stopWatch.start();
        final int INSERT_NUM = 1000;
        for (int i = 0; i < INSERT_NUM; i++) {
            User user = new User();
            user.setUsername("假用户");
            user.setUserAccount("fakeghost");
            user.setAvatarUrl("https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/logo.png");
            user.setGender(0);
            user.setUserPassword("12345678");
            user.setPhone("123");
            user.setEmail("123@qq.com");
            user.setTags("[]");
            user.setUserStatus(0);
            user.setUserRole(0);
            user.setPlanetCode("11111111");
            userMapper.insert(user);
        }
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }
}
  • for 循环的缺点
    • 建立和释放数据库连接==>>批量插入解决
    • for 循环是绝对线性的==>>并发执行
  • 批量插入用户:使用 Mybatis-plus 提供的批量插入 saveBatch 方法,现将要插入的用户存储到一个集合里,再将集合批量插入到数据库
package com.example.usercenter.once;

import com.example.usercenter.model.domain.User;
import com.example.usercenter.service.UserService;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 导入用户任务
 * @author Ghost
 * @version 1.0
 */
@Component
public class InsertUsers {

    @Resource
    private UserService userService;

    /**
     * 批量插入用户
     */
    public void doInsertUsers() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final int INSERT_NUM = 1000;
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < INSERT_NUM; i++) {
            User user = new User();
            user.setUsername("假用户");
            user.setUserAccount("fakeghost");
            user.setAvatarUrl("https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/logo.png");
            user.setGender(0);
            user.setUserPassword("12345678");
            user.setPhone("123");
            user.setEmail("123@qq.com");
            user.setTags("[]");
            user.setUserStatus(0);
            user.setUserRole(0);
            user.setPlanetCode("11111111");
            userList.add(user);
        }
        // 20 秒 10 万条
        userService.saveBatch(userList, 10000);
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }
}
  • 并发执行:将数据分成多组,开启多线程并发执行 
    • 注意:插入数据的顺序对应用没有影响才使用并发;不要用不支持并发的集合
    /**
     * 并发批量插入用户
     */
    @Test
    public void doConcurrencyInsertUsersTest() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 分十组
        int batchSize = 5000;
        int j = 0;
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            List<User> userList = new ArrayList<>();
            while (true) {
                j++;
                User user = new User();
                user.setUsername("假用户");
                user.setUserAccount("fakeghost");
                user.setAvatarUrl("https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/logo.png");
                user.setGender(0);
                user.setUserPassword("12345678");
                user.setPhone("123");
                user.setEmail("123@qq.com");
                user.setTags("[]");
                user.setUserStatus(0);
                user.setUserRole(0);
                user.setPlanetCode("11111111");
                userList.add(user);
                if (j % batchSize == 0) {
                    break;
                }
            }
            // 异步执行
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                System.out.println("threadName: " + Thread.currentThread().getName());
                userService.saveBatch(userList, batchSize);
            }, executorService);
            futureList.add(future);
        }
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
        // 20 秒 10 万条
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }

三、分页查询

1. 开启分页

  • 接收前端传来的分页数量和每页展示数目
    /**
     * 用户推荐
     * @param request
     * @return 用户列表
     */
    @GetMapping("/recommend")
    public BaseResponse<Page<User>> recommendUsers(long pageSize, long pageNum, HttpServletRequest request) {
        log.info("推荐用户列表");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Page<User> userList = userService.page(new Page<>((pageNum - 1) * pageSize, pageSize), queryWrapper);// 查询所有用户
        return ResultUtils.success(userList);
    }

2. 开启 Mybatis-plus 分页配置

/**
 * MyBatisPlus 配置
 * @author 乐小鑫
 * @version 1.0
 */
@Configuration
@MapperScan("com.example.usercenter.mapper")
public class MybatisPlusConfig {
    /**
     * 新的分页插件,一缓和二缓遵循 mybatis 的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

四、查看页面效果

  • 开启分页后后端响应封装到了 Page 中,前端接收时需要取出 response 中的 records

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

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

相关文章

利用预训练模型SKEP进行情感分析

项目地址&#xff1a;文本情感分析 - 飞桨AI Studio星河社区 (baidu.com) baidu/Senta: Baidus open-source Sentiment Analysis System. (github.com) 本项目将详细全面介绍情感分析任务的两种子任务&#xff0c;句子级情感分析和目标级情感分析。 同时演示如何使用情感分析…

【RabbitMQ】快速入门及基本使用

一、引言 1、、消息队列 Ⅰ、什么是消息队列&#xff1f; 消息队列是一种进程间通信或同一进程的不同线程间的通信方式&#xff0c;软件的贮列用来处理一系列的输入&#xff0c;通常是来自用户。消息队列提供了异步的通信协议&#xff0c;每一个贮列中的纪录包含详细说明的数据…

一文看完String的前世今生,内容有点多,请耐心看完!

写在开头 String字符串作为一种引用类型&#xff0c;在Java中的地位举足轻重&#xff0c;也是代码中出现频率最高的一种数据结构&#xff0c;因此&#xff0c;我们需要像分析Object一样&#xff0c;将String作为一个topic&#xff0c;单独拿出来总结&#xff0c;这里面涉及到字…

虹科分享 | Redis与MySQL协同升级企业缓存

文章速览&#xff1a; MySQL为什么需要Redis EnterpriseRedis Enterprise带来哪些优势Redis Enterprise与MySQL协同 传统的MySQL数据库在处理大规模应用时已经到了瓶颈&#xff0c;Redis Enterprise怎样助力突破这一瓶颈&#xff1f;Redis Enterprise与MYSQL共同用作企业级缓存…

第二次作业+第三次作业

第二次作业第三次作业 第二次作业 题目&#xff1a; 网站需求&#xff1a; ​ 1.基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于[ww…

[全连接神经网络]Transformer代餐,用MLP构建图像处理网络

一、MLP-Mixer 使用纯MLP处理图像信息&#xff0c;其原理类似vit&#xff0c;将图片进行分块(patch)后展平(fallten)&#xff0c;然后输入到MLP中。理论上MLP等价于1x1卷积&#xff0c;但实际上1x1卷积仅能结合通道信息而不能结合空间信息。根据结合的信息不同分为channel-mixi…

hash应用

目录 一、位图 1.1、引出位图 1.2、位图的概念 1.3、位图的应用 1.4、位图模拟实现 二、布隆过滤器 2.1、什么是布隆过滤器 2.2、布隆过滤器应用的场景 2.3、布隆过滤器的原理 2.4、布隆过滤器的查找 2.5、布隆过滤器的插入 2.6、布隆过滤器的删除 2.7、布隆过滤器…

深入解析JavaScript中箭头函数的用法

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 箭头函数(Arrow function)是JavaScript ES6中引入的一大特性。箭头函…

数字图像处理期末速成笔记

目录 一、基础知识二、相邻像素间基本关系三、图像增强方法1、直方图求解2、直方图均衡化3、直方图规定化4、图像平滑5、邻域平均法&#xff08;线性&#xff09;6、 中值滤波法&#xff08;分线性&#xff09;7、中值滤波与领域平均的异同8、4-邻域平滑法9、超限像素平滑法10、…

【Linux】yum

个人主页 &#xff1a; zxctsclrjjjcph 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 yum 1. 什么是yum&#xff1f;2. Linux系统(Centos)的生态3. yum的相关操作4. yum的本地配置5. 如何安装软件 1. 什么是yum&#xff1f; yum是一个软件下载安装的一个客户端&a…

逻辑运算

目录 AND OR NOT Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 逻辑运算可以保证连接多个条件&#xff0c;连接主要使用 AND、OR 、NOT完成 AND 1.查询职位不是办事员&#xff0c;但是工资低于 300 的员工信息 这个范例可以理…

学习响应式编程中遇到的奇奇怪怪的问题

spring项目无法启动 Description: Web application could not be started as there was no org.springframework.boot.web.reactive.server.ReactiveWebServerFactory bean defined in the context. Action: Check your application’s dependencies for a supported react…

Visual Studio 设置编辑框(即代码编辑器)的背景颜色

在Visual Studio 中设置编辑框&#xff08;即代码编辑器&#xff09;的背景颜色&#xff0c;可以按照以下步骤进行&#xff1a; 打开Visual Studio。在菜单栏上找到并点击“工具”(Tools)选项。在下拉菜单中选择“选项”(Options)。在“选项”对话框中&#xff0c;导航至“环境…

基于Spring+mybatis+vue的在线课后测试系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

Oracle架构_数据库底层原理、机制 (授人以渔)

目录 系统全局区SGA 高速缓存缓冲区(数据库缓冲区) 日志缓冲区 共享池 其他结构 用户连接进程 用户进程User Process Server Process服务进程 程序全局区PGA Oracle的connect连接和session会话与User Process紧密相关 后台进程 数据库写入进程(DBWn) 检查点(CKPT)…

plt.table绘制表格

目录 一&#xff1a;介绍 二&#xff1a;绘制一个表格 一&#xff1a;介绍 plt.table()函数是Matplotlib库中的一个函数&#xff0c;用于在图表中插入一个表格。它提供了创建和定制表格的功能。下面是plt.table()函数的一些常用参数&#xff1a; cellText: 一个二维列表或数…

mp4文件可以转成mp3音频吗

现在是个非常流行刷短视频一个年代&#xff0c;刷短视似乎成了人们休闲娱乐的一种方式&#xff0c;在日常刷短视频过程中&#xff0c;肯定会有很多同学被短视频 bgm 神曲洗脑&#xff0c;比如很多被网红翻唱带火的歌曲&#xff0c;例如其中"不负人间”&#xff0c;就是其中…

elementUI+el-upload 上传、下载、删除文件以及文件展示列表自定义为表格展示

Upload 上传组件的使用 官方文档链接使用el-upload组件上传文件 具体参数说明&#xff0c;如何实现上传、下载、删除等功能获取文件列表进行file-list格式匹配代码 文件展示列表自定义为表格展示 使用的具体参数说明文件大小展示问题&#xff08;KB/MB&#xff09;文件下载代码…

Windows下载并配置Kettle

注意&#xff1a;需要windows配置Java 下载 Kettle 进入官网&#xff1a;https://www.hitachivantara.com/en-us/products/pentaho-plus-platform/data-integration-analytics/pentaho-community-edition.html 下载带有Pentaho Data Integration (Base Install)的文件&#…

智能工厂能耗监测系统

智能工厂能耗监测系统是一种用于监测和管理智能工厂内能耗的系统。它通过实时收集和分析能耗数据&#xff0c;帮助工厂管理者实现能源节约、提高能源使用效率和降低运营成本。本文将详细介绍智能工厂能耗监测系统的原理、组成、优势和应用。 一、系统原理 智能工厂能耗监测系…