mybatis一个结果集不能用两次吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis一个结果集不能用两次吗相关的知识,希望对你有一定的参考价值。

参考技术A 是的,mybatis一个结果集不能用两次。
MyBatis对JDBC做了很好的封装,其中一个吸引人的地方就是能够对从数据库内查询出来的表的记录集映射生成一系列JavaBean,供应用程序使用。MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。映射关系是一对一得,因此mybatis一个结果集不能用两次。望采纳。

一个承诺可以解决两次吗?

【中文标题】一个承诺可以解决两次吗?【英文标题】:Can one promise be resolved twice? 【发布时间】:2022-01-21 01:55:07 【问题描述】:

我有这样的功能:

async howLongToMyBirthdayDate(date) 
    return await new Promise((resolve, reject) => 
      let bday;
      if (!(date instanceof Date)) 
        if (Number.isInteger(date) && date > 0) 
          bday = new Date(date);
         else 
          setTimeout(() => reject(new Error('Wrong argument!')), 1000);
          return;
        
       else 
        bday = date;
      

      const today = new Date();
      today.setHours(0, 0, 0, 0);

      bday.setFullYear(today.getFullYear());
      bday.setHours(0, 0, 0, 0);

      if (bday - today === 0) 
        setTimeout(() => resolve(this.congratulateWithBirthday()), 1000);
        
      

      setTimeout(
        () =>
          resolve(this.notifyWaitingTime(Math.ceil((bday - today) / 86400000))),
        1000
      );
    );
  

承诺解决了两次。我看到函数 congratulateWithBirthday 和 notifyWaitingTime 的结果。正常吗?我认为承诺只能被解决或拒绝一次 - 通过第一次调用解决或拒绝回调。也许 setTimeout 会改变它的行为?谁能给我解释一下?

【问题讨论】:

“我看到了...的结果”。怎么看?为什么日期相同时调用 resolve() 两次? "" — 不,但很难说发生了什么,因为您没有提供minimal reproducible example “承诺解决了两次。” 你可能的意思是它实现了两次。 (更多关于术语in my post here。)但是一个承诺既不能被解决也不能被多次履行。如果您看到某件事让您认为它已经发生了两次,那么您看到的是其他事情的结果,而不是承诺的实现。 旁注:这里没有理由将任何日期逻辑与承诺混合在一起。算一算,如果你想延迟一秒报告结果,awaitsetTimeout wrapper。 【参考方案1】:

您的承诺不需要解决两次即可获得您所描述的行为。您正在直接调用这两个函数,所以它们当然会被调用。对resolve 的第二次调用是否执行任何操作无关。

这一行

resolve(this.notifyWaitingTime(Math.ceil((bday - today) / 86400000))),

不是说“解析然后运行这个函数”,而是说“调用这个函数,然后用它的返回值调用resolve”。

编写此代码的更合适的方式可能是这样的:

async howLongToMyBirthdayDate(date) 
    const result = await new Promise((resolve, reject) => 
      let bday;
      if (!(date instanceof Date)) 
        if (Number.isInteger(date) && date > 0) 
          bday = new Date(date);
         else 
          setTimeout(() => reject(new Error('Wrong argument!')), 1000);
          return;
        
       else 
        bday = date;
      

      const today = new Date();
      today.setHours(0, 0, 0, 0);

      bday.setFullYear(today.getFullYear());
      bday.setHours(0, 0, 0, 0);

      // resolve with how long until bday
      if (bday - today === 0) 
        setTimeout(() => resolve(0), 1000);
        
      

      // we just resolve with how long until bday
      setTimeout(
        () =>
          resolve(Math.ceil((bday - today) / 86400000)),
        1000
      );
    );

  if (result === 0)  this.congratulateWithBirthday(); 
  else if (result > 0)  this.notifyWaitingTime(result); 
  

不是 100% 肯定这解决了您的问题,因为我看不到您调用的函数是做什么的,但我从您 (ab) 使用 resolve 的方式的猜测是,您基本上想调用两个函数之一计算后的函数取决于 bday 是否现在。

【讨论】:

【参考方案2】:

简短的回答,是的,鉴于您的代码,它将解析两次。这样做的原因是因为congratulateWithBirthdaynotifyWaitingTime 没有相互制约,所以它们都会在同一次运行中被调用。

如果你想避免这种情况,你应该有类似的东西

if (bday - today === 0) 
  setTimeout(() => resolve(this.congratulateWithBirthday()), 1000);
 else 
  setTimeout(() => resolve(this.notifyWaitingTime(Math.ceil((bday - today) / 86400000))), 1000);

另外,作为旁注,请尝试在使用async/awaitPromise 之间做出决定。没有理由同时使用这两种方法,这会使代码看起来很奇怪。

【讨论】:

除了在同一个承诺上第二次调用resolve() 没有任何作用。一个承诺只会真正实现一次。 是的,但他不是在等待完成的值,而是在调用其他一些函数,在这个例子中,如果 bday - today === 0 都会被调用

以上是关于mybatis一个结果集不能用两次吗的主要内容,如果未能解决你的问题,请参考以下文章

mybatis百科-结果集映射类ResultMap

java使用mybatis 调用存储过程返回一个游标结果集

java使用mybatis 调用存储过程返回一个游标结果集

Mybatis结果集封装map类型

如何将 mybatis 选择查询的巨大结果集导出到 csv?

MyBatis结果集一对多映射