当前位置:   article > 正文

springboot + vue 实现oracle数据库中的分页功能_vue+springboot+oracle

vue+springboot+oracle

        个人想要记录一些比较常用的网页端功能。所以写这一篇博客记录一下。

        话不多说,开始吧。

        首先是,数据库的设计,没什么设计,就是一张表而已,用做分页功能的记录就足够了。不过要说的是oracle数据库与mysql数据的分页功能不同,oracle数据里面是不支持limit语法的,所以一开始就让我有点懵,不过涉猎一番之后,还是有办法写出于mysql数据库类似的sql语句。

        创建一个oracle数据表:player

  1. CREATE TABLE "C##GAME"."player"
  2. ( "p_id" NUMBER(*,0) NOT NULL ENABLE,
  3. "p_name" VARCHAR2(38) NOT NULL ENABLE,
  4. "p_type" VARCHAR2(38) NOT NULL ENABLE,
  5. "p_hp" NUMBER(38,0) NOT NULL ENABLE,
  6. "p_mp" NUMBER(38,0),
  7. "p_defense" NUMBER(38,0),
  8. "p_attack" NUMBER(38,0),
  9. "p_critical_hit" NUMBER(38,0),
  10. "p_miss" FLOAT(126),
  11. "p_user_id" NUMBER(38,0),
  12. "p_create_time" DATE,
  13. PRIMARY KEY ("p_id")
  14. USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  15. STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  16. PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  17. BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  18. TABLESPACE "GAME" ENABLE,
  19. CONSTRAINT "p_user_id" FOREIGN KEY ("p_user_id")
  20. REFERENCES "C##GAME"."user" ("user_id") ON DELETE SET NULL ENABLE
  21. ) SEGMENT CREATION IMMEDIATE
  22. PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  23. NOCOMPRESS LOGGING
  24. STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  25. PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  26. BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  27. TABLESPACE "GAME" ;
  28. CREATE OR REPLACE EDITIONABLE TRIGGER "C##GAME"."Z_Z" BEFORE INSERT ON "C##GAME"."player" REFERENCING OLD AS "OLD" NEW AS "NEW" FOR EACH ROW
  29. begin
  30. select "z_z".nextval into :new."p_id" from dual;
  31. end;
  32. ALTER TRIGGER "C##GAME"."Z_Z" ENABLE

        这个表中是后面是写了一个触发器,用于id的自增,oracle数据库的自增不像mysql那样可以直接选择自增选项。得要自己写一个触发器实现主键自增。

        创建完了之后就是这个样子的:

        这些数据自己填一下就好了。

        数据库表创建好了,那就是开始后端的Springboot项目的创建了,创建项目的话,这里的就不一一详细的写了,我把pom文件贴出来,如果不知道项目的依赖的话,直接复制上去就好了。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.7.8</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.lhh</groupId>
  12. <artifactId>record</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>record</name>
  15. <description>record</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-devtools</artifactId>
  27. <scope>runtime</scope>
  28. <optional>true</optional>
  29. </dependency>
  30. <dependency>
  31. <groupId>com.oracle.database.jdbc</groupId>
  32. <artifactId>ojdbc8</artifactId>
  33. <scope>runtime</scope>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.projectlombok</groupId>
  37. <artifactId>lombok</artifactId>
  38. <optional>true</optional>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-test</artifactId>
  43. <scope>test</scope>
  44. </dependency>
  45. <!-- mybatis plus-->
  46. <dependency>
  47. <groupId>com.baomidou</groupId>
  48. <artifactId>mybatis-plus-boot-starter</artifactId>
  49. <version>3.1.2</version>
  50. </dependency>
  51. </dependencies>
  52. <build>
  53. <plugins>
  54. <plugin>
  55. <groupId>org.springframework.boot</groupId>
  56. <artifactId>spring-boot-maven-plugin</artifactId>
  57. <configuration>
  58. <excludes>
  59. <exclude>
  60. <groupId>org.projectlombok</groupId>
  61. <artifactId>lombok</artifactId>
  62. </exclude>
  63. </excludes>
  64. </configuration>
  65. </plugin>
  66. </plugins>
  67. </build>
  68. </project>

        先连接一下数据库:这是在application.yml文件里面配置的

  

        我创建了两个配置文件一个是application.yml,用于连接数据库;另外一个是application.properties文件,用于配置端口,mybatis-plus扫描mapper文件的路径等等,其实可以配置在一个文件里面,但是我习惯了,所以暂时就先这样吧。下面是application.properties文件的配置:

        之后在创建一些实体类包,Service包,mapper包,controller包等,最终的整个项目的目录就是这个样子的。

        

        目录创建完了,开始写代码,先在mapper中创建一个playerMapper接口文件,代码如下

  1. package com.lhh.record.mapper;
  2. import com.lhh.record.entity.player;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import org.apache.ibatis.annotations.Param;
  5. import org.springframework.stereotype.Repository;
  6. import org.springframework.web.bind.annotation.RequestBody;
  7. import java.util.List;
  8. @Mapper
  9. @Repository
  10. public interface playerMapper {
  11. List<player> playersList();
  12. List<player> pagePlayer(@Param(value = "page") int page, @Param(value = "pageSize") int pageSize);
  13. int count();
  14. }

        playerList用于查询所有的数据,暂时不用管用不上。

        第二个接口pagePlayer就是用于实现分页的方法,需要前端传两个参数过来,一个是当前页面page,一个是页面大小pageSize;

        第三个接口count()则是查询数据的总条数,用于在前端计算可以产生多少页。

        mapper接口写完,就在resources资源目录下mapper包中创建一个playerMapper.xml文件。用于写需要的sql语句,对应上上面写的mapper接口方法,id中填写的就是src目录下mapper包中的接口名称,例如下面的代码

  1. <!DOCTYPE mapper
  2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.lhh.record.mapper.playerMapper">
  5. <resultMap id="PlayerMap" type="com.lhh.record.entity.player">
  6. <id column="p_id" property="pId"/>
  7. <result column="p_name" property="pName"/>
  8. <result column="p_type" property="pType"/>
  9. <result column="p_hp" property="pHp"/>
  10. <result column="p_mp" property="pMp"/>
  11. <result column="p_defense" property="pDefense"/>
  12. <result column="p_attack" property="pAttack"/>
  13. <result column="p_critical_hit" property="pCriticalHit"/>
  14. <result column="p_miss" property="pMiss"/>
  15. <result column="p_user_id" property="pUserId"/>
  16. <result column="p_create_time" property="pCreateTime"/>
  17. </resultMap>
  18. <select id="playersList" resultType="com.lhh.record.entity.player">
  19. select * from "player"
  20. </select>
  21. <!--oracle分页写法 <-->
  22. <!-- SELECT * FROM "player" ORDER BY "p_id" ASC 这一条是查询所有数据根据p_id排序-->
  23. <!-- ROWNUM rn FROM ( SELECT * FROM "player" ORDER BY "p_id" ASC ) t WHERE ROWNUM &lt; = #{pageSize} 限制输出的pageSize条数-->
  24. <!-- rn>#{page} 从page那条记录开始输出-->
  25. <select id="pagePlayer" resultType="com.lhh.record.entity.player">
  26. SELECT
  27. *
  28. FROM
  29. ( SELECT t.*, ROWNUM rn FROM ( SELECT * FROM "player" ORDER BY "p_id" ASC ) t WHERE ROWNUM &lt;= #{pageSize} )
  30. WHERE
  31. rn &gt; #{page}
  32. </select>
  33. <select id="count" resultType="java.lang.Integer">
  34. select count(*) as count from "player"
  35. </select>
  36. </mapper>

        最主要的方法就是pagePlayer下面的sql语句,因为oracle是没有limit语句的,得用rownum函数,rownum函数是返回编号的函数,第一条就返回1,所以返回前十条就rownum<=10,这里就是暂时解析一下这条语句,如果想要了解rownum函数,还是请自行百度吧。回到语句里,从里面到外面说 select * from “play” order by "p_id" asc 就是根据查询所有的数据并根据“p_id”进行升序排序,asc就是升序,desc就是降序。第一步是进行排序,第二根据查询出来已经排好序的数据看做是一个新的表t,在查询t表中的所有数据,t表就是原来的play表,就是已经升序好了。而中间那层语句:

SELECT t.*, ROWNUM rn FROM ( SELECT * FROM "player" ORDER BY "p_id" ASC ) t WHERE ROWNUM &lt;= #{pageSize}

        就是查询t表的所有数据以及rownum函数(返回的是一个编号)在后面加个rn,表示用rn的名称代替rownum函数,where后面,rownum<=#{pageSize}就是表示rownum函数返回的编号要小于前端的提交的页面大小,不过这里的pageSzie不是真正的页面大小,需要java代码中进行计算,后面会说到,还有就是这里的"<"的符号表示小于号,如果不懂,可以去百度一下mybatis的大于号小于号的写法,这里不在多说了。

        继续说where后面小于等于pageSzie,也就是说从第一条到pageSize参数的那条,例如pageSize=10,就是说从第一条到第十条;而此时的rn返回的数据是第一条数据后面对应rn就是1,而第十条对应的rn就是10了,如图所示:

        最后再说最后一层吧,就是查询已经限制十条数据了的t表的所有数据并再进一步的进行做输出限制,而后面的where条件语句rn>#{page}就是从page+1条开始输出,例如,page=1,就是从第二条开始到pageSize(假设pageSize=10)的条数,就是从2条开始到第10条了,这样子就可以进行限制从第几条到第几条的输出了。这样可以根据前端传进来的参数进行分页输出条数了。

        对了,光顾着解释sql语句了,其实第一步的话应该从创建表的实体类开始的,根据上面的目录,在entity下创建一个player的实体类,类名头字母应该是要大写的,这里忘了改了,还是得规范一下代码,不然的话读起来会非常难受的。player类里面的代码为:

  1. package com.lhh.record.entity;
  2. import com.baomidou.mybatisplus.annotation.TableField;
  3. import com.baomidou.mybatisplus.annotation.TableId;
  4. import com.baomidou.mybatisplus.annotation.TableName;
  5. import lombok.AllArgsConstructor;
  6. import lombok.Data;
  7. import lombok.NoArgsConstructor;
  8. import java.sql.Date;
  9. @Data
  10. @AllArgsConstructor
  11. @NoArgsConstructor
  12. @TableName(value = "\"player\"")
  13. public class player {
  14. @TableId(value = "\"p_id\"")
  15. private long pId;
  16. @TableField(value = "\"p_name\"")
  17. private String pName;
  18. @TableField(value = "\"p_type\"")
  19. private String pType;
  20. @TableField(value = "\"p_hp\"")
  21. private long pHp;
  22. @TableField(value = "\"p_mp\"")
  23. private long pMp;
  24. @TableField(value = "\"p_defense\"")
  25. private long pDefense;
  26. @TableField(value = "\"p_attack\"")
  27. private long pAttack;
  28. @TableField(value = "\"p_critical_hit\"")
  29. private long pCriticalHit;
  30. @TableField(value = "\"p_miss\"")
  31. private float pMiss;
  32. @TableField(value = "\"p_user_id\"")
  33. private long pUserId;
  34. @TableField(value = "\"p_create_time\"")
  35. private Date pCreateTime;
  36. }

        这里我用了lombok,不然的话就要自己写getter、setter方法,不了解lombok的话,就去了解一下吧,还是挺好用的。

        我们继续一层一层往下,接下来就是Service层了,不多说先贴代码:

  1. package com.lhh.record.service;
  2. import com.lhh.record.entity.player;
  3. import java.util.List;
  4. public interface PlayerService {
  5. /***
  6. * 分页查询
  7. * @param page 从第几条开始显示
  8. * @param pageSize 页面大小,显示几条数据
  9. * @return pageSize条数的数据
  10. */
  11. List<player> pagePlayer(int page, int pageSize);
  12. /***
  13. * 查询总条数
  14. * @return int总条数
  15. */
  16. int count();
  17. List<player> playerList();
  18. }

        先写一个playerService接口,然后需要playerServiceImpl类来实现这些方法,代码为:

  1. package com.lhh.record.service;
  2. import com.lhh.record.entity.player;
  3. import com.lhh.record.mapper.playerMapper;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Service;
  6. import java.sql.Date;
  7. import java.util.List;
  8. @Service
  9. public class PlayerServiceImpl implements PlayerService{
  10. @Autowired
  11. playerMapper playerMapper;
  12. @Override
  13. public List<player> pagePlayer(int page, int pageSize) {
  14. int pageCount = (page-1)*pageSize;
  15. pageSize = page * pageSize;
  16. return playerMapper.pagePlayer(pageCount,pageSize);
  17. }
  18. @Override
  19. public int count() {
  20. return playerMapper.count();
  21. }
  22. @Override
  23. public List<player> playerList() {
  24. return playerMapper.playersList();
  25. }
  26. }

        这里主要看pagePlayer这个方法,接收从前端传来的page(当前页面),pageSize(页面大小),这里处理了一下pageCount传到最后的sql语句里面的#{page}参数,就是说这里的pageCount 就是等于sql语句了page了,而这个我们第一页的话肯定是从第一条开始,但是数据库下表是从0开始的是,所以说前端传来的page需要减去1,再乘以当前页面大小pageSize,就是从第几条开始了,例如前端传来(page,pageSize)为 (1,10),那么传到sql语句里面的数值就是page = (1-1)* 10 = 0,说明是从第一条开始(这里面page为0就是下标为0 的第一条),然后是pageSize = 1*10 = 10,就是从0~10条的数据了,如果是(2,10),那么就是page = (2-1)* 10 就是=10,从第十条开始到pageSize = 2 * 10 = 20 到第二十条了。所以这方法里面进行这个操作的。

        而count方法则是查询总条数,用于分页可以分多少页;而第三个方法暂时用不上,所以不用看了。

        写完了Service就开始最后一个controller层的编写了,前端传过来的参数就是从这里接收,然后一步一步往下传的,所以如果接收不到参数,那么就不可能进行后面的操作了。而需要先创建一个playerController类,代码为:

  1. package com.lhh.record.controller;
  2. import com.lhh.record.entity.player;
  3. import com.lhh.record.service.PlayerServiceImpl;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.*;
  6. import javax.servlet.http.HttpServletRequest;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. @RestController
  11. @CrossOrigin
  12. public class PlayerController {
  13. @Autowired
  14. PlayerServiceImpl playerService;
  15. @PostMapping (value = "/findPagePlayer")
  16. public Map<String, player> findPagePlayer(int page, int pageSize){
  17. Map playerMap = new HashMap();
  18. List<player> players = playerService.pagePlayer(page,pageSize);
  19. playerMap.put("player",players);
  20. int count = playerService.count();
  21. playerMap.put("playerCount",count);
  22. return playerMap;
  23. }
  24. @GetMapping(value = "/playerList")
  25. public Map<String,player> playerList(){
  26. Map playerList = new HashMap();
  27. List<player> players = playerService.playerList();
  28. playerList.put("playerList",players);
  29. return playerList;
  30. }
  31. }

        第二个接口不用看,主要是第一个,我返回了一个map,前端只要找到了player,就可以取到数据了,而我把count(也就是总条数)也添加进了这个map里面,只要找到键值对的键playerCount就可以获取到总条数了。

        大概整个后端都还是比较详细的说明了,但是前端的话就不会那么详细了,本人是做后端,对于前端的一些东西可能就是只有了解一些,应该是不会特别详细的说明前端了,前端是用vue做的,至于创建vue项目,网上也有挺多资料的,大家也可以参考,我这里可能只会贴上前端分页功能的页面代码了,因为就是一个分页功能,所以是比较简陋,如果说是遇到报错的,可能大家需要自己去查找原因了。当然也可以留言,但是我不一定有时间及时回复的,所以还是靠自己解决bug吧。

        好了,话不多说!开始贴代码,就是一个分页的页面:

  1. <template>
  2. <div style="align-content: center">
  3. <el-button type="primary" @click="getPlayer">主要按钮</el-button>
  4. <el-table :data="tableData" style="width: 750px" height="750">
  5. <el-table-column prop="pname" label="昵称" width="120">
  6. </el-table-column>
  7. <el-table-column prop="ptype" label="类型" width="120">
  8. </el-table-column>
  9. <el-table-column prop="php" label="生命" width="120">
  10. </el-table-column>
  11. <el-table-column prop="pmp" label="蓝量" width="120">
  12. </el-table-column>
  13. <el-table-column prop="pattack" label="攻击" width="120">
  14. </el-table-column>
  15. <el-table-column prop="pdefense" label="防御" width="120">
  16. </el-table-column>
  17. </el-table>
  18. <div class="block">
  19. <span class="demonstration">显示总数</span>
  20. <!-- @size-change 每页条数
  21. @current-change 当前页
  22. -->
  23. <el-pagination
  24. @size-change="handleSizeChange"
  25. @current-change="handleCurrentChange"
  26. :page-sizes="[2,5,10]"
  27. :current-page="this.pages.pageCount"
  28. :page-size="this.pages.pageSize"
  29. layout="total, prev, pager, next, sizes,jumper"
  30. :total=total>
  31. </el-pagination>
  32. </div>
  33. </div>
  34. </template>
  35. <script>
  36. import axios from "axios";
  37. export default {
  38. data() {
  39. return {
  40. tableData: [{
  41. }],
  42. tableList:[],
  43. total: 0,
  44. pages:{
  45. pageCount:1,//当前页面
  46. pageSize:5 //页面条数
  47. }
  48. }
  49. },
  50. created(){
  51. this.getPlayer()    //打开页面执行点击事件
  52. },
  53. methods: {
  54. getPlayer() {
  55. const that = this;
  56. const page = this.pages.pageCount
  57. const pageSize = this.pages.pageSize
  58. console.log(pageSize)
  59. let formData = new FormData()
  60. formData.append('page',page)
  61. formData.append('pageSize',pageSize)
  62. this.$axios.post("http://localhost:8888/findPagePlayer",formData).then(res => {
  63. this.tableData = res.data.player
  64. this.total = res.data.playerCount
  65. })
  66. },
  67. handleSizeChange(val) {
  68. this.pages.pageSize = val
  69. this.getPlayer()
  70. //this.pageList()
  71. console.log(`每页 ${val} 条`);
  72. },
  73. handleCurrentChange(val) {
  74. this.pages.pageCount = val
  75. this.getPlayer()
  76. //this.pageList()
  77. console.log(`当前页: ${val}`);
  78. },
  79. }
  80. }
  81. </script>

        主要是getPlayer方法传参数调接口,主要是传参数(pageCount,pageSize),调用http://localhost:8888/findPagePlayer接口,调用之后将查询出来的数据,赋值到tableData上,而total主要用于存储接收的总条数,前面也说过了,返回的使用个map,可以通过键player找到列表数据,可以通过键playerCount找到总条数并赋值。

        下面的两个方法是使用分页功能组件自带的,分别表示在当前页面和页面条数改变是会触发,将改变的数值再一次传到方法getPlayer里面,进行再一次的请求,然后返回对应的数据,在页面进行显示,最终的效果图是这样的

        我这里面访问的页面url是这样:http://localhost:8080/#/player;大家得根据自己实际情况访问前端的url,我这里前端写的不太详细,如果是新手的话,还得需要自己去创建项目,怎么访问都要自己去弄明白来的,这里就只贴出一个最后的效果图以及一些简单的说明

        第二页:

        每页十条:

        好了,这篇文章也是写了挺久的了,虽然对于我来时可能不需要那么详细的说明了,一开始我就是想记录一下那一条sql语句的,没想到写着写着就把所有的东西都写上去了,也行吧,方便一些刚入门,或者是对oracle数据库不太熟悉的有一些参考吧 。

        

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/88006?site
推荐阅读
相关标签
  

闽ICP备14008679号