微信小程序开发教程:mysql数据库的组合查询实战案例

实战案例:

mysql数据库的info01表中,有如下字段:kmz、chengci、yxid、yxname、zyid、zyname、jhs、xz、xf。
我现在写了如下微信小程序的wxml代码:

<button bindtap="filterData" style="width: 100%; margin-top: 28rpx; background-color: lightslategrey; color: white; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);">立即筛选</button>
<view wx:for="{
   
   {pathinfo}}" class="view1" wx:if="{
   
   {!loading}}">
  <view class="view-box1">
    <view class="view-box2">
    <view class="title0">
    <view class="title11">
    <view class="cc1"><view class="cc2">{
   
   {item.chengci}}</view></view>
    <view>{
   
   {item.yxname}}</view>
    </view>
    </view>
    </view>
    <view>
    <view class="view-box3">
      <view>
      <h1>科目:</h1><h1>{
   
   {item.kmz}}</h1>
      </view>
      <view class="view-boxright">
      <h1>专业名:</h1><h1>{
   
   {item.zyname}}</h1>
      </view>
    </view>
    <view class="view-box3">
      <view><h1>计划数:</h1><h1>{
   
   {item.jhs}}</h1></view>
      <view class="view-boxright"><h1>学费:</h1><h1>{
   
   {item.xf}}</h1></view>
      <view class="view-boxright"><h1>学制:</h1><h1>{
   
   {item.xz}}</h1></view>
    </view>
    </view>
  </view>
</view>

当用户点击bindtap="filterData"事件后,会调用微信小程序TS文件中的下列代码:

filterData: function() {
this.setData({
loading: true,
offset: 0, // 重置已加载的数据量
pathinfo: [], // 清空现有数据
hasMore: true, // 重置是否还有更多数据标志
});
this.loadData();
},
     loadData: function () {
        if (!this.data.hasMore) return; // 如果没有更多数据,则不执行加载操作
        wx.showLoading({
          title: '加载中...',
        });
        const year = this.data.years[this.data.yearIndex];
        const batch = this.data.batches[this.data.batchIndex];
        const limit = this.data.limit;
        const offset = this.data.offset;

        console.log("选择器",year, batch);
        this.setData({
          loading: true
        });
      
        wx.request({
          url: config.apiUrl + '/api/getinfojh',
          method: 'POST',
          data: {
            year: year,
            batch: batch,
            limit: limit, // 新增,传递每次加载的数据量
            offset: offset, // 新增,传递当前已加载的数据量
          },
          header: {
            'content-type': 'application/json' // 确保发送的是JSON格式
          },
          success: (res) => {
            if (res.statusCode === 200) {
              const newData = res.data;
              const allData = this.data.pathinfo.concat(newData);
              this.setData({
                //pathinfo: res.data,
                pathinfo: allData,
                offset: offset + newData.length, // 更新已加载的数据量
                hasMore: newData.length === limit, // 如果返回的数据少于请求的数据量,则表示没有更多数据
                loading: false
              });
              wx.pageScrollTo({
                scrollTop: 99999, // 给一个足够大的值,确保可以滚动到底部
                duration: 0 // 滚动动画持续时间,单位ms
              });
            } else {
              // 处理错误情况,例如无数据或查询错误
              this.setData({
                pathinfo: [],
                loading: false
              });
              wx.showToast({
                title: '未找到数据',
                icon: 'none'
              });
            }
            wx.hideLoading();
          },
          fail: (err) => {
            console.error(err);
            this.setData({
              loading: false
            });
            wx.hideLoading();
            wx.showToast({
              title: '数据加载失败',
              icon: 'none'
            });
          }
        });
      },

然后通过下面/api/getinfojh路由接口获取数据:

const express = require('express');
const router = express.Router();
const sql = require('../sql');

router.post('/getinfojh', function(req, res, next) {
    //const { year, batch } = req.body;
    const { year, batch, limit, offset } = req.body;
    console.log(year, batch);
    let tableName = '';
    // 确保参数匹配的逻辑是正确的
    if (year === '2022' && batch === '第一批次') {
        tableName = 'info01';
        console.log(tableName);
    } else if (year === '2022' && batch === '第二批次') {
        tableName = 'info02';
        console.log(tableName);
    } else if (year === '2023' && batch === '第一批次') {
        tableName = 'info03';
        console.log(tableName);
    } else if (year === '2023' && batch === '第二批次') {
        tableName = 'info05';
        console.log(tableName);
    } else {
        // 如果没有匹配的表,返回错误
        return res.status(400).json({ message: 'Invalid year or batch' });
    }
    // 查询数据库前打印SQL语句
    console.log(`SELECT * FROM ${tableName}`);
    // 修改SQL查询语句,增加LIMIT和OFFSET子句
    const query = `SELECT * FROM ${tableName} LIMIT ${limit} OFFSET ${offset}`;
    //const query = `SELECT *, COUNT(*) as count FROM ${tableName} GROUP BY yxname LIMIT ${limit} OFFSET ${offset}`;
    //SELECT yxname FROM info01 GROUP BY yxname HAVING COUNT(*) > 1;
    //const query = `SELECT DISTINCT yxname,chengci FROM ${tableName} LIMIT ${limit} OFFSET ${offset}`;
    //SELECT DISTINCT yxname FROM info;这个查询会检索info表中的yxname列,并且只返回不重复的值。如果yxname列中有重复的值,它们只会在结果集中出现一次。
    console.log(query);
    // 查询数据库
    sql.query(query, (err, result) => {
        if (err) {
            console.error("查询出现错误:", tableName);
            console.error(err);
            res.status(500).json({ message: 'Internal Server Error' });
        } else {
            // 确保返回的结果是预期的
            if (result.length > 0) {
                res.json(result);
                //res.status(200).json(result);
                console.log("返回了结果");
            } else {
                // 如果查询结果为空,返回404状态码
                console.log("查询结果为空");
                res.status(404).json({ message: 'No data found' });
            }
        }
    });
});
module.exports = router;

最后将获得到的数据显示到下面的代码中:

<view wx:for="{
   
   {pathinfo}}" class="view1" wx:if="{
   
   {!loading}}">
  <view class="view-box1">
    <view class="view-box2">
    <view class="title0">
    <view class="title11">
    <view class="cc1"><view class="cc2">{
   
   {item.chengci}}</view></view>
    <view>{
   
   {item.yxname}}</view>
    </view>
    </view>
    </view>
    <view>
    <!-- <view wx:for="{
   
   {pathinfos}}"> -->
    <view class="view-box3">
      <view>
      <h1>科目:</h1><h1>{
   
   {item.kmz}}</h1>
      </view>
      <view class="view-boxright">
      <h1>专业名:</h1><h1>{
   
   {item.zyname}}</h1>
      </view>
    </view>
    <view class="view-box3">
      <view><h1>计划数:</h1><h1>{
   
   {item.jhs}}</h1></view>
      <view class="view-boxright"><h1>学费:</h1><h1>{
   
   {item.xf}}</h1></view>
      <view class="view-boxright"><h1>学制:</h1><h1>{
   
   {item.xz}}</h1></view>
    </view>
    </view>
  </view>
</view>

现在我想要将info01表中yxname字段值相同的数据,遍历后显示到下面的代码中:

<view class="view-box3">
      <view>
      <h1>科目:</h1><h1>{
   
   {item.kmz}}</h1>
      </view>
      <view class="view-boxright">
      <h1>专业名:</h1><h1>{
   
   {item.zyname}}</h1>
      </view>
    </view>

于是我写了/api/getinfojh2路由接口,代码如下:

const express = require('express');
const router = express.Router();
const sql = require('../sql');

router.post('/getinfojh2', function(req, res, next) {
    const { year, batch, yxname } = req.body;
    let tableName = '';
    // 根据年份和批次确定表名
    if (year === '2022' && batch === '第一批次') {
        tableName = 'info01';
    } else if (year === '2022' && batch === '第二批次') {
        tableName = 'info02';
    } else if (year === '2023' && batch === '第一批次') {
        tableName = 'info03';
    } else if (year === '2023' && batch === '第二批次') {
        tableName = 'info05';
    } else {
        return res.status(400).json({ message: 'Invalid year or batch' });
    }
    // 查询数据库,获取特定yxname对应的所有记录
    const query = `SELECT * FROM ${tableName} WHERE yxname = ?`;
    sql.query(query, [yxname], (err, result) => {
        if (err) {
            console.error("查询出现错误:", err);
            res.status(500).json({ message: 'Internal Server Error' });
        } else {
            if (result.length > 0) {
                res.json(result);
            } else {
                res.status(404).json({ message: 'No data found for the specified yxname' });
            }
        }
    });
});
module.exports = router;

现在我想要将getinfojh2路由接口,用wx.request语句放置在getinfojh路由接口后进行调用,让每一个<view wx:for="{ {pathinfo}}" class="view1" wx:if="{ {!loading}}">块都能显示指定yxname字段值的所有内容,并将相同yxname字段值的内容,遍历显示在下面的代码中:

<view class="view-box3">
      <view>
      <h1>科目:</h1><h1>{
   
   {item.kmz}}</h1>
      </view>
      <view class="view-boxright">
      <h1>专业名:</h1><h1>{
   
   {item.zyname}}</h1>
      </view>
    </view>

解决方案如下:

将getinfojh2路由接口的调用,放置在getinfojh路由接口的成功回调函数中。以下是修改后的代码示例:

    if (res.statusCode === 200) {
        const newData = res.data;
        const allData = this.data.pathinfo.concat(newData);
        
        // 添加调用getinfojh2路由接口的代码
        for (let i = 0; i < allData.length; i++) {
            const yxname = allData[i].yxname;
            
            wx.request({
                url: config.apiUrl + '/api/getinfojh2',
                method: 'POST',
                data: {
                    year: year,
                    batch: batch,
                    yxname: yxname
                },
                header: {
                    'content-type': 'application/json'
                },
                success: (res) => {
                    if (res.statusCode === 200) {
                        // 将获取到的数据更新到指定的allData项中
                        allData[i].yxInfo = res.data;
                        this.setData({
                            pathinfo: allData
                        });
                    } else {
                        console.log("未找到数据");
                    }
                },
                fail: (err) => {
                    console.error(err);
                    console.log("数据加载失败");
                }
            });
        }
        
        this.setData({
            pathinfo: allData,
            offset: offset + newData.length,
            hasMore: newData.length === limit,
            loading: false
        });
        // 其他代码...
    } else {
        // 处理错误情况...
    }
    wx.hideLoading();
},

然后,在WXML代码中通过wx:for和使用item.yxInfo获取到每个yxname字段值对应的数据,并将其遍历显示在相应的<view class="view-box3">块中:

<view wx:for="{
   
   {pathinfo}}" class="view1" wx:if="{
   
   {!loading}}">
    <view class="view-box1">
        <view class="view-box2">
            <view class="title0">
                <view class="title11">
                    <view class="cc1"><view class="cc2">{
   
   {item.chengci}}</view></view>
                    <view>{
   
   {item.yxname}}</view>
                </view>
            </view>
        </view>
        <view>
            <!-- 遍历显示指定yxname字段值的内容 -->
            <view class="view-box3" wx:for="{
   
   {item.yxInfo}}">
                <view>
                    <h1>科目:</h1><h1>{
   
   {item.kmz}}</h1>
                </view>
                <view class="view-boxright">
                    <h1>专业名:</h1><h1>{
   
   {item.zyname}}</h1>
                </view>
            </view>
            <view class="view-box3">
                <view><h1>计划数:</h1><h1>{
   
   {item.jhs}}</h1></view>
                <view class="view-boxright"><h1>学费:</h1><h1>{
   
   {item.xf}}</h1></view>
                <view class="view-boxright"><h1>学制:</h1><h1>{
   
   {item.xz}}</h1></view>
            </view>
        </view>
    </view>
</view>

这样,每个<view wx:for="{ {pathinfo}}" class="view1" wx:if="{ {!loading}}">块都会根据指定的yxname字段值显示对应的内容。

猜你喜欢

转载自blog.csdn.net/qq_25501981/article/details/134810962
今日推荐