当前位置: 首页 > news >正文

【java爬虫】使用element-plus进行个股详细数据分页展示

前言

前面的文章我们讲述了获取详细个股数据的方法,并且使用echarts对个股的价格走势图进行了展示,本文将编写一个页面,对个股详细数据进行展示。别问涉及到了element-plus中分页的写法,对于这部分知识将会做重点讲解。

首先看一下效果

之前我一直认为前端分页很难写,不过今天写完这个页面之后我发现,有了element-plus这样的框架,前端真的变得非常简单。

获取所有有数据的股票代码

我们的页面主要分为两个部分,第一部分是获取所有有数据的股票代码,一旦选择了某一个股票代码,就会进行相对应数据的展示

本节我们先来说一下获取所有可展示的数据

和本页面相关的数据表一共有两张,一张是沪深300成分股表,表中记录了股票代码和股票名称

 

另一张表是个股详细数据表,就是我们在之前的文章介绍过的表

【java爬虫】基于springboot+jdbcTemplate+sqlite+OkHttp获取个股的详细数据-CSDN博客

这样表对应的详细信息如下图所示

我们要分页展示的也是这张表中的数据,之所以需要两张表联动,是因为这张表中没有股票名称,为了能够同时将股票代码和股票名称查出来,我们需要首先查询个股数据表,然后再从沪深300成分股表中查询出股票代码对应的股票名称

    public List<StockOptionVO> getAllCode() {List<StockEntity> stockEntities = sqLiteStockDao.queryAllCode();List<CSI300Entity> csi300Entities = sqlIteCSI300Dao.queryAllItems();List<StockOptionVO> stockOptionVOList = new ArrayList<>();for (int i=0; i<stockEntities.size(); i++) {StockOptionVO stockOptionVO = new StockOptionVO();stockOptionVO.setCode(stockEntities.get(i).getCode());for (int j=0; j<csi300Entities.size(); j++) {if (csi300Entities.get(j).getCode().equals(stockEntities.get(i).getCode())) {stockOptionVO.setName(csi300Entities.get(j).getName());break;}}stockOptionVOList.add(stockOptionVO);}return stockOptionVOList;}

 其中两个SQL语句都很简单,就是SELECT查询数据

    @Overridepublic List<StockEntity> queryAllCode() {String sql = "SELECT DISTINCT code FROM " + TABLE_NAME;log.info("执行sql:" + sql);List<StockEntity> stockEntities = jdbcTemplate.query(sql, new Object[]{}, new BeanPropertyRowMapper<>(StockEntity.class));return stockEntities;}
    @Overridepublic List<CSI300Entity> queryAllItems() {String sql = "SELECT * FROM " + tableName;List<CSI300Entity> csi300Entities = jdbcTemplate.query(sql, new Object[]{}, new BeanPropertyRowMapper<CSI300Entity>(CSI300Entity.class));return csi300Entities;}

控制层代码如下

    // 获取所有有详细数据的股票代码@RequestMapping("/queryCodeOptions")@ResponseBodypublic String queryCodeOptions() {List<StockOptionVO> stockOptionVOList = stockService.getAllCode();return JSON.toJSONString(stockOptionVOList);}

该接口调用的结果如下所示

[{"code":"000001","name":"平安银行"},{"code":"000063","name":"中兴通讯"},{"code":"000002","name":"万科A"},{"code":"688981","name":"中芯国际"},{"code":"000568","name":"泸州老窖"}]

然后我们回到前端,我们使用了<el-select>组件进行多个选项的选择,其中<el-option>是对应的选项,我们使用v-for将后端请求到的数据渲染成选项

     <el-card><el-form label-width="auto"><el-form-item label="选择要查询的股票"><el-select v-model="code" placeholder="请选择股票"><el-option@click="handleSelect(item)"v-for="item in options":label="item.code + ' ' + item.name":value="item.code":key="item.code"></el-option></el-select></el-form-item></el-form></el-card>

注意看,<el-option>中有一个@click选项,就是我们点击的时候会触发的相应操作,实际上这个函数的逻辑就是点击后就进行相对应股票数据的查询。

获取个股详细数据并分页展示

分页有非常多好处,在SQL端主要就是使用LIMIT和OFFSET这两个关键字来实现的

接口层面接收三个参数,分别是股票代码,每一页的数据量和当前页数

    // 分页查询某一只股票的详细数据@RequestMapping("/queryDataByPage/{code}/{pagesize}/{page}")@ResponseBodypublic String queryDataByPage(@PathVariable("code") String code,@PathVariable("pagesize") Integer pagesize,@PathVariable("page") Integer page) {List<StockEntity> stockEntities = stockService.queryDataByPage(code, pagesize, page);return JSON.toJSONString(stockEntities);}

在Service层将页数转换为SQL语句中的LIMIT和OFFSET,其中LIMIT是固定的,就是你的每一页的数据量,OFFSET的计算公式为(page - 1) * pagesize

    // 分页查询某一只股票的详细数据public List<StockEntity> queryDataByPage(String code, Integer pagesize, Integer page) {Integer limit = pagesize;Integer offset = (page - 1) * pagesize;List<StockEntity> stockEntities = sqLiteStockDao.queryDataByPage(code, limit, offset);return stockEntities;}

最后就是DAO层的代码

     @Overridepublic List<StockEntity> queryDataByPage(String code, Integer limit, Integer offset) {String sql = "SELECT * FROM " + TABLE_NAME +" WHERE code=? ORDER BY record_date DESC LIMIT ? OFFSET ?";log.info("执行sql:" + sql);List<StockEntity> stockEntities = jdbcTemplate.query(sql, new Object[]{code, limit, offset},new BeanPropertyRowMapper<>(StockEntity.class));return stockEntities;}

这样一来我们就编写好了分页查询的后端接口。

我们还需要一个获取数据总量的接口,从控制层到服务层再到Dao层的代码如下

    // 查询数据的总条数@RequestMapping("/queryNumByCode/{code}")@ResponseBodypublic Integer queryNumByCode(@PathVariable("code") String code) {int num = stockService.queryNumByCode(code);return num;}
    // 查询数据的总条数public int queryNumByCode(String code) {return sqLiteStockDao.queryNumByCode(code);}
    @Overridepublic int queryNumByCode(String code) {String sql = "SELECT COUNT(id) FROM " + TABLE_NAME + " WHERE code=?";log.info("执行sql:" + sql);int num = jdbcTemplate.queryForObject(sql, new Object[]{code},Integer.class);return num;}

下面来看一下前端的分页组件,element-plus提供了<el-pagintion>进行分页,我们拿一个官网的例子来讲解这个组件的用法

从上到下依次为:

  • current-page:表示当前页数,这是一个动态的值
  • page-size:表示每一页的数据量,这也是一个动态的值
  • small:是否采用小型分页样式
  • disabled:是否禁用分页
  • background:是否为分页按钮添加背景颜色(添加了背景颜色会更好看)
  • layout:组件的排版方式
  • total:总的数据量(这是需要提前获取的)
  • size-change:当每一页的数据量变化时触发的事件
  • current-change:当前页面变化时触发的事件

关于这个样式,我给大家举一个例子,比如我是这样写的

可以看到从左到右分别是sizes,prev,pager,next和total,那么对应的呈现的效果如下

这样子说不知道大家是否能更好地理解这个属性的用法。

那么有了基本的样式后,我们还需要编写当前页和每一页数据量这两个变量改变时的响应事件,其实逻辑都很简单,就是改变一下变量的值,然后再请求新的数据

    handleSizeChange(number) {this.current_size = number;var url ="http://localhost:9001/stock/queryDataByPage/" +this.current_code +"/" +this.current_size +"/" +this.current_page;this.loading = true;axios.get(url).then((response) => {this.table_data = response.data;console.log(response);this.loading = false;}).catch((error) => {console.log(error);this.loading = false;});},handleCurrentChange(number) {this.current_page = number;var url ="http://localhost:9001/stock/queryDataByPage/" +this.current_code +"/" +this.current_size +"/" +this.current_page;this.loading = true;axios.get(url).then((response) => {this.table_data = response.data;console.log(response);this.loading = false;}).catch((error) => {console.log(error);this.loading = false;});},

下面展示一下前端页面的完整代码

<template><el-container><el-main><el-card><el-form label-width="auto"><el-form-item label="选择要查询的股票"><el-select v-model="code" placeholder="请选择股票"><el-option@click="handleSelect(item)"v-for="item in options":label="item.code + ' ' + item.name":value="item.code":key="item.code"></el-option></el-select></el-form-item></el-form></el-card><el-card><template #header><div class="card-header"><span>{{ table_title }}</span></div></template><el-tablev-loading="loading":data="table_data":show-header="true":max-height="500"stripe><el-table-column prop="record_date" label="时间"></el-table-column><el-table-column prop="open_price" label="开盘价"></el-table-column><el-table-column prop="close_price" label="收盘价"></el-table-column><el-table-column prop="change_ament" label="涨跌额"></el-table-column><el-table-columnprop="change_range"label="涨跌幅":formatter="formatter1"></el-table-column><el-table-column prop="max_price" label="最高价格"></el-table-column><el-table-column prop="min_price" label="最低价格"></el-table-column><el-table-column prop="volume" label="成交量(手)"></el-table-column><el-table-columnprop="turnover"label="成交额(万)"></el-table-column><el-table-columnprop="turnover_rate"label="换手率":formatter="formatter2"></el-table-column></el-table><el-divider /><el-pagination:current-page="current_page":page-size="current_size":page-sizes="[10, 20, 30]":small="false":background="true"layout="sizes, prev, pager, next, total":total="total_num"@size-change="handleSizeChange"@current-change="handleCurrentChange"/></el-card></el-main></el-container>
</template><script>
import axios from "axios";
import { getCurrentInstance } from "vue";
export default {data() {return {update_status: "未开始",loading: false,// 当前选中的股票code: "",// 所有的选项options: [],table_title: "个股数据",// 个股详细信息table_data: [],// 分页相关选项// 当前查询的股票代码current_code: "",// 当前页current_page: 1,// 每一页的数量current_size: 10,// 数据总数total_num: 0,echarts: getCurrentInstance().appContext.config.globalProperties.$echarts,};},mounted() {this.init();},methods: {init() {var url = "http://localhost:9001/stock/queryCodeOptions";axios.get(url).then((response) => {this.options = response.data;console.log(response);}).catch((error) => {console.log(error);});},handleSelect(item) {this.current_code = item.code;this.current_page = 1;// 获取表格详细数据var url1 ="http://localhost:9001/stock/queryDataByPage/" +this.current_code +"/" +this.current_size +"/" +this.current_page;this.loading = true;this.table_title = item.code + " " + item.name;axios.get(url1).then((response) => {this.table_data = response.data;console.log(response);this.loading = false;}).catch((error) => {console.log(error);this.loading = false;});// 获取当前股票数据总数var url2 = "http://localhost:9001/stock/queryNumByCode/" + item.code;axios.get(url2).then((response) => {this.total_num = response.data;console.log(response);}).catch((error) => {console.log(error);});},formatter1(row) {return row.change_range + "%";},formatter2(row) {return row.turnover_rate + "%";},handleSizeChange(number) {this.current_size = number;var url ="http://localhost:9001/stock/queryDataByPage/" +this.current_code +"/" +this.current_size +"/" +this.current_page;this.loading = true;axios.get(url).then((response) => {this.table_data = response.data;console.log(response);this.loading = false;}).catch((error) => {console.log(error);this.loading = false;});},handleCurrentChange(number) {this.current_page = number;var url ="http://localhost:9001/stock/queryDataByPage/" +this.current_code +"/" +this.current_size +"/" +this.current_page;this.loading = true;axios.get(url).then((response) => {this.table_data = response.data;console.log(response);this.loading = false;}).catch((error) => {console.log(error);this.loading = false;});},},
};
</script><style scoped>
.card-header {display: flex;justify-content: space-between;align-items: center;
}
</style>

还有一点需要额外说一下,大家可以看一下我们表格中的数据

这两列是由百分号,但是数据库中存的数据是没有百分号的,我们选择在前端进行处理,在表格相应的列中添加一个formatter属性,属性的值是一个函数,函数返回值就是最后渲染到页面上的字符串。

这两个函数的具体实现如下

 

结语

本文介绍了后端分页接口以及基于element-plus的分页实现方法,希望对你有所帮助。

相关文章:

【java爬虫】使用element-plus进行个股详细数据分页展示

前言 前面的文章我们讲述了获取详细个股数据的方法&#xff0c;并且使用echarts对个股的价格走势图进行了展示&#xff0c;本文将编写一个页面&#xff0c;对个股详细数据进行展示。别问涉及到了element-plus中分页的写法&#xff0c;对于这部分知识将会做重点讲解。 首先看一…...

Python使用余弦相似度比较两个图片

为了使用余弦相似度来找到与样例图片相似的图片&#xff0c;我们需要先进行一些预处理&#xff0c;然后计算每两张图片之间的余弦相似度。以下是一个简单的实现&#xff1a; 读取样例图片和目标文件夹中的所有图片。对每张图片进行预处理&#xff0c;例如灰度化、降噪等。计算…...

树莓派4B-Python使用PyCharm的SSH协议在电脑上远程编辑程序

目录 前言一、pycharm的选择二、添加SSH的解释器使用总结 前言 树莓派的性能始终有限&#xff0c;不好安装与使用高级一点的程序编辑器&#xff0c;如果只用thonny的话&#xff0c;本人用得不习惯&#xff0c;还不如PyCharm&#xff0c;所以想着能不能用电脑中的pycharm来编写…...

Servlet的自动加载、ServletConfig对象、ServletContext对象

一、 Servlet的自动加载 默认情况下&#xff0c;第一次访问servlet的时候&#xff0c;创建servlet对象。如果servlet构造函数里面的代码或者init方法里面的代码比较多&#xff0c;就会导致用户第一次访问servlet的时候比较慢。这个时候&#xff0c;我们可以改变servlet对象的创…...

Vue - Class和Style绑定详解

1. 模板部分 <template><div><!-- Class 绑定示例 --><div :class"{ active: isActive, text-danger: hasError }">Hello, Vue!</div><!-- Class 绑定数组示例 --><div :class"[activeClass, errorClass]">Cla…...

适用于 Windows 的 7 个顶级视频转换器 – 流畅的视频转换体验!

对于任何想要增强视频转换体验的人来说&#xff0c;视频转换器都是必不可少的工具。无论您是需要转换视频文件格式以实现兼容性&#xff0c;还是只是想优化视频以获得更好的质量&#xff0c;可靠的视频转换器都可以使该过程无缝且高效。在这篇博文中&#xff0c;我们将探讨适用…...

Vue3全局属性app.config.globalProperties

文章目录 一、概念二、实践2.1、定义2.2、使用 三、最后 一、概念 一个用于注册能够被应用内所有组件实例访问到的全局属性的对象。点击【前往】访问官网 二、实践 2.1、定义 在main.ts文件中设置app.config.globalPropertie import {createApp} from vue import ElementPl…...

单片机开发--keil5

一.keil5 Keil uVision5是一个集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于对嵌入式系统中的微控制器进行编程。它是一个软件套件&#xff0c;包括源代码编辑器、项目经理、调试器以及微控制器开发、调试和编程所需的其他工具。Keil uVision5 IDE主要用于对基于A…...

<JavaEE> TCP 的通信机制(三) -- 滑动窗口

目录 TCP的通信机制的核心特性 四、滑动窗口 1&#xff09;什么是滑动窗口&#xff1f; 2&#xff09;滑动窗口的作用是什么&#xff1f; 3&#xff09;批量传输出现丢包如何处理&#xff1f; 1> 接收端ACK丢包 2> 发送端数据包丢包 4&#xff09;适用性 TCP的通…...

听GPT 讲Rust源代码--library/portable-simd

File: rust/library/portable-simd/crates/core_simd/examples/spectral_norm.rs spectral_norm.rs是一个示例程序&#xff0c;它展示了如何使用Portable SIMD库中的SIMD&#xff08;Single Instruction Multiple Data&#xff09;功能来实现频谱规范化算法。该示例程序是Rust源…...

CMake入门教程【基础篇】CMake+Minggw构建项目

文章目录 Minggw是什么Minggw下载CMake下载安装第1步&#xff1a;下载CMake第2步&#xff1a;安装CMake 如何构建和编译项目&#xff1a;使用CMake和MinGW总结 Minggw是什么 MinGW&#xff08;Minimalist GNU for Windows&#xff09;是一个免费的软件开发环境&#xff0c;旨在…...

2024年原创深度学习算法项目分享

原创深度学习算法项目分享&#xff0c;包括以下领域&#xff1a; 图像视频、文本分析、知识图谱、推荐系统、问答系统、强化学习、机器学习、多模态、系统界面、爬虫、增量学习等领域… 有需要的话&#xff0c;评论区私聊...

Linux自定义shell编写

Linux自定义shell编写 一.最终版本展示1.动图展示2.代码展示 二.具体步骤1.打印提示符2.解析命令行3.分析是否是内建命令1.shell对于内建名令的处理2.cd命令3.cd函数的实现4.echo命令的实现5.export命令的实现6.内建命令函数的实现 4.创建子进程通过程序替换执行命令5.循环往复…...

堆的应用:堆排序和TOP-K问题

上次才讲完堆的相关问题&#xff1a;二叉树顺序结构与堆的概念及性质&#xff08;c语言实现堆 那今天就接着来进行堆的主要两方面的应用&#xff1a;堆排序和TOP-K问题 文章目录 1.堆排序1.1概念、思路及代码1.2改良代码&#xff08;最初建立大堆用AdjustDow&#xff09; 2. TO…...

element表格排序功能

官方展示 个人项目 可以分别对每一项数据进行筛选 注&#xff1a;筛选的数据不能是字符串类型必须是数字类型&#xff0c;否则筛选会乱排序 html <el-table :data"tableData" border height"600" style"width: 100%"><el-table-co…...

HNU-Java程序设计基础训练-2023

1.DNA序列&#xff08;Java&#xff09; 【问题描述】 一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例&#xff08;定义为GC-Ratio&#xff09;是序列中G和C两个字母的总的出现次数除以总的字母数目&#xff08;也就是序列长度&#xff09;。在基因工程中&#xf…...

数据库和数据库编程

数据库、数据表、表数据操作以及数据库编程相关的知识点 1. 数据库的概念&#xff1a; 数据库是用于存储和组织数据的系统。数据库管理系统(DBMS)是管理数据库的软件&#xff0c;提供对数据的访问、查询和维护。关系型数据库是一种通过表格结构来组织和管理数据的数据库。 2…...

爬虫基础一(持续更新)

爬虫概念&#xff1a; 通过编写程序&#xff0c;模拟浏览器上网&#xff0c;然后让其去互联网上抓取数据的过程 分类&#xff1a; 1&#xff0c;通用爬虫&#xff1a;抓取一整张页面数据 2&#xff0c;聚焦爬虫&#xff1a;抓取页面中的局部内容 3&#xff0c;增量式爬虫&…...

右键菜单“以notepad++打开”,在windows文件管理器中

notepad 添加到文件管理器的右键菜单中 找到安装包&#xff0c;重新安装一般即可。 这里有最新版&#xff1a;地址 密码:f0f1 方法 在安装的时候勾选 “Context Menu Entry” 即可 Notepad的右击打开文件功能 默认已勾选 其作用是添加右键快捷键。即&#xff0c;对于任何…...

JSON.parseObject强制将自动转化的Intage型设置为Long型

通过Redis或Caffeine存储入json型String&#xff0c;通过JSON.parseObject自动类型转化之后&#xff0c;数值会优先转为Intage&#xff0c;如果存入的字符值大于Intage最大值&#xff0c;会自动转为Long型&#xff1b; 需求是&#xff1a;实要取出时数值类型值为Long&#xff1…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能

vxe-table vue 表格复选框多选数据&#xff0c;实现快捷键 Shift 批量选择功能 查看官网&#xff1a;https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...

Python爬虫(四):PyQuery 框架

PyQuery 框架详解与对比 BeautifulSoup 第一部分&#xff1a;PyQuery 框架介绍 1. PyQuery 是什么&#xff1f; PyQuery 是一个 Python 的 HTML/XML 解析库&#xff0c;它采用了 jQuery 的语法风格&#xff0c;让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...

NineData数据库DevOps功能全面支持百度智能云向量数据库 VectorDB,助力企业 AI 应用高效落地

NineData 的数据库 DevOps 解决方案已完成对百度智能云向量数据库 VectorDB 的全链路适配&#xff0c;成为国内首批提供 VectorDB 原生操作能力的服务商。此次合作聚焦 AI 开发核心场景&#xff0c;通过标准化 SQL 工作台与细粒度权限管控两大能力&#xff0c;助力企业安全高效…...

宠物车载安全座椅市场报告:解读行业趋势与投资前景

一、什么是宠物车载安全座椅&#xff1f; 宠物车载安全座椅是一种专为宠物设计的车内固定装置&#xff0c;旨在保障宠物在乘车过程中的安全性与舒适性。它通常由高强度材料制成&#xff0c;具备良好的缓冲性能&#xff0c;并可通过安全带或ISOFIX接口固定于车内。 近年来&…...