伙伴匹配系统06
目标
- 开发主页(默认推荐和自己兴趣相当的用户)
- 导入模拟数据100万条
1.开发主页
思路:最简单方式List列表
1.1先将SearchPage.vue中的复制代码拿来用一下
<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: 8px;margin-top: 8px">
{{ tag }}
</van-tag>
</template>
<template #footer>
<van-button size="mini">联系我</van-button>
</template>
</van-card>
<van-empty v-if="!userList||userList.length<1" image="search" description="数据为空" />
</template>
<script setup >
import {onMounted, ref} from "vue";
import {useRoute} from "vue-router";
import myAxios from "../plugins/myAxios";
import {Toast} from "vant";
import qs from 'qs';
const route =useRoute();
const { tags }=route.query;
const userList = ref([])
onMounted(async () =>{
const userListData= await myAxios.get('/user/recommend', {
params: {
},
})
.then(function (response) {
console.log('/user/recommend===>succeed',response);
Toast.success('请求成功')
return response?.data;
})
.catch(function (error) {
console.error('/user/recommend===>error',error);
Toast.fail('请求失败')
});
if (userListData){
userListData.forEach(user=>{
if (user.tags){
user.tags = JSON.parse(user.tags);
}
})
userList.value = userListData;
}
})
</script>
<style scoped>
</style>
1.2开发后台接口
@GetMapping("/recommend")
public BaseResponse<List<User>> recommendUsers(HttpServletRequest request) {
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);
}
1.3刷新前端主页,拿到数据
1.4我们发现我们可以将卡片列表单独抽出封装成一个组件UserCardList.vue
<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: 8px;margin-top: 8px">
{{ tag }}
</van-tag>
</template>
<template #footer>
<van-button size="mini">联系我</van-button>
</template>
</van-card>
</template>
<script setup lang="ts">
import {UserType} from "../models/user";
interface UserCardListProps {
userList: UserType[];
}
const props = withDefaults(defineProps<UserCardListProps>(), {
userList: [],
})
</script>
<style scoped>
</style>
优化搜索结果页面和主页,将原来的冗余代码换成UserCardList组件标签
这样最简单的主页就开发完成了
2.数据导入模拟一百万个用户
导入数据
1.用可视化界面即可:适合一次性导入,数据量可控
2.写程序:for循环,建议分批次,不要一把梭哈(可以用接口来控制)要保持可控,幂等性
3.执行SQL语句,适用于小数据量
编写一次性任务最简单是main方法,但这种方法不是万能的
@SpringBootApplication
@MapperScan("com.hyx.getfriend.mapper")
@EnableScheduling//开启一次性任务的注解
public class GetFriendApplication {
public static void main(String[] args) {
SpringApplication.run(GetFriendApplication.class, args);
}
}
编写一个一次性任务
快捷,快捷生成set并设置默认值
StopWatch详解
https://blog.csdn.net/Frlyh/article/details/122312161
上面应该是插入一百条时间为1秒
这次插入1000条为3秒
for循环一次性插入的问题
1.建立和释放数据库连接时
2.for循环是绝对线性的
思考,可不可以每个连接插入几条数据,而不是一次连接插入一条数据就被释放了?
优化代码
导入一百万数据162秒
刚才我们的都是顺序执行的,这次我们换多线程试试会不会更快
并发
用并发来试试,开个多线程
清空了一下数据表,重新开启并发,发现导入100万条数据从162秒减少到了58秒
https://blog.csdn.net/listeningsea/article/details/123175964
可见,这边用线程并发执行导入数据会大大节约我们的时间
3.分页
修改一下后端接口
给前台加上分页所需的参数,并修改返回值
这样我们就成功获取到了分页之后的数据
思考?主页未登录的情况下,推荐的用户应该就是一些固定的,或者预先把数据查出来,放到一个更快读取的地方,不用再查数据库,这样主页响应的速度会不会大大加快呢?(缓存)
新问题:什么时候将缓存写入进去呢?
预加载缓存,定时更新缓存。(定时任务)
多个机器都要执行任务吗?(分布式锁,控制同一时间只有一台机器去执行定时任务,其他机器不用重复执行了)