spring mybatis upgrade to mybatisplus 实战小记

我司压箱底儿的灵工服务商系统,系统框架是spring,持久层是mybatis。最近,将Mybatisplus集成到系统中,以提高开发效率。

升级版本:

  • mybatis版本3.2.2,升级到3.5.16
  • Mybatisplus版本:3.5.3
  • mybatis-spring版本1.2.0,升级到3.0.0
  • pagehelper版本:5.3.1

【注】mybatis官方提供了Mybatis-Plus SpringMVC Demo:https://gitee.com/baomidou/mybatisplus-spring-mvc.git


本文整理升级过程中踩过的坑。

java.lang.IllegalArgumentException: invalid comparison: com.levy.enums.BillFormTypeEnum and java.lang.String

grep 'invalid comparison' /www/epaysch/tomcat-web-8180/logs/catalina.2024-10-17.out -c

sqlmapper文件 TInvoiceConfigChangeFlowMapper.xml 中有如下insert定义:

<insert id="saveFlow" parameterType="com.levy.entity.InvoiceConfigChangeFlow">
    <selectKey resultType="java.lang.Long" order="BEFORE" keyProperty="id">
        SELECT SEQ_INVOICE_CONFIG_CHANGE_FLOW.Nextval FROM dual
    </selectKey>
    insert into T_INVOICE_CONFIG_CHANGE_FLOW
    <trim prefix="(" suffix=")" suffixOverrides=",">
        ID,
        <if test="changeFormType != null and changeFormType!=''">
            CHANGE_FORM_TYPE,
        </if>
        ...
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
        #{id,jdbcType=DECIMAL},
        <if test="changeFormType != null and changeFormType != ''">
            #{changeFormType,jdbcType=VARCHAR},
        </if>
        ...
    </trim>
</insert>

其中,entity属性InvoiceConfigChangeFlow#changeFormType 是枚举类型。

@Data
public class InvoiceConfigChangeFlow implements Serializable {
    /**
     * 主键id
     */
    private Long id;

    /**
     * 发票形式类型,
     * BillFormTypeEnum:PAPER(纸票) ELECTRONIC(电票)
     */
    private BillFormTypeEnum changeFormType;
    。。。
}

注意sql语句中的 changeFormType != ''。 它将enum与String做比较。这在 mybatis-3.2.2 版本没有问题。而在升级后的版本 mybatis-3.5.16 却不兼容了。就是说,这个版本发现 将enum数据与字符串去比较,就抛出类型不匹配的异常:java.lang.IllegalArgumentException: invalid comparison: com.levy.enums.BillFormTypeEnum and java.lang.String

详细异常信息:

### Error updating database.  Cause: java.lang.IllegalArgumentException: invalid comparison: com.levy.enums.BillFormTypeEnum and java.lang.String
### The error may exist in URL [jar:file:/www/epaysch/tomcat-web-8180/webapps/BossMgr/WEB-INF/lib/tax-pay-ext-common-service-1.0-SNAPSHOT.jar!/mapper/InvoiceConfigChangeFlowMapper.xml]
### The error may involve com.levy.dao.InvoiceConfigChangeFlowDAO.saveFlow

解决办法自然是,去掉这段sql里的 changeFormType != ''。

那么,细究一下,为什么高版本的mybatis却不向下兼容这个“特性”了呢? 我认为,mybatis团队也是推崇开发者编写规范的代码。因此,我也不打算花时间研究让高版本的mybatis-3.5.16 来支持这一点。

Bean named 'xxx' is expected to be of type 'xxx' but was actually of type 'jdk.proxy2.$ProxyN'

继承了Mybatisplus.ServiceImpl的Manager类或Service类,当在这些子class中定义方法时,会抛异常:org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'xxx' is expected to be of type 'xxx' but was actually of type 'jdk.proxy2.$Proxy24'

例如: Bean named 'userManager' is expected to be of type 'com.baomidou.springmvc.service.system.UserManager' but was actually of type 'com.sun.proxy.$Proxy27'

解决办法:xml配置文件中设置proxy-target-class=true

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

Only one AsyncAnnotationBeanPostProcessor may exist within the context.

Configuration problem: Only one AsyncAnnotationBeanPostProcessor may exist within the context.

去配置文件中找 , 某个配置文件被引用了两次以上.移除后保留一个即可.如下即可产生上述问题

<import resource="classpath:testContext-currentproduct.xml" />
<import resource="classpath:testContext-currentproduct.xml" />
<import resource="classpath:testContext-elitecurrentproduct.xml" />

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.levy.dao.TBankBillFileDAO.listNotFinalStateByTimeRange

配置正确的mapperLocations。如<property name="mapperLocations" value="classpath*:mapper/*.xml"/>

MybatisSqlSessionFactoryBean#mapperLocations:

/**
   * Set locations of MyBatis mapper files that are going to be merged into the {@code SqlSessionFactory} configuration
   * at runtime.
   * <p>
   * This is an alternative to specifying "&lt;sqlmapper&gt;" entries in an MyBatis config file. This property being
   * based on Spring's resource abstraction also allows for specifying resource patterns here: e.g.
   * "classpath*:sqlmap/*-mapper.xml".
   *
   * @param mapperLocations location of MyBatis mapper files
   */
  public void setMapperLocations(Resource... mapperLocations) {
      this.mapperLocations = mapperLocations;
  }

java.lang.NoClassDefFoundError: net/sf/jsqlparser/statement/select/SelectBody

java.lang.InstantiationError: net.sf.jsqlparser.statement.select.SelectItem

com.github.pagehelper:pagehelper:jar:5.3.1

com.github.jsqlparser:jsqlparser:jar:4.2

SelectItem类在jsqlparser-4.2.jar里。完整类名:net.sf.jsqlparser.statement.select.SelectItem

java.lang.IllegalStateException: Failed to load ApplicationContext

 at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
 at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
 at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
 at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
 at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
 at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
 at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
 at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
 at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
 at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
 at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
 at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mybatisPlusInterceptor' defined in com.yft.mybatisplus.MybatisPlusConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor]: Factory method 'mybatisPlusInterceptor' threw exception; nested exception is java.lang.InstantiationError: net.sf.jsqlparser.statement.select.SelectItem
 at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776)
 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
 at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
 at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
 at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
 at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
 at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
 at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
 ... 26 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor]: Factory method 'mybatisPlusInterceptor' threw exception; nested exception is java.lang.InstantiationError: net.sf.jsqlparser.statement.select.SelectItem
 at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
 at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
 ... 43 more
Caused by: java.lang.InstantiationError: net.sf.jsqlparser.statement.select.SelectItem
 at com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor.<clinit>(PaginationInnerInterceptor.java:69)
 at com.yft.mybatisplus.MybatisPlusConfig.mybatisPlusInterceptor(MybatisPlusConfig.java:27)
 at com.yft.mybatisplus.MybatisPlusConfig$$EnhancerBySpringCGLIB$$7cd6f94a.CGLIB$mybatisPlusInterceptor$0(<generated>)
 at com.yft.mybatisplus.MybatisPlusConfig$$EnhancerBySpringCGLIB$$7cd6f94a$$FastClassBySpringCGLIB$$1ebe875d.invoke(<generated>)
 at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
 at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
 at com.yft.mybatisplus.MybatisPlusConfig$$EnhancerBySpringCGLIB$$7cd6f94a.mybatisPlusInterceptor(<generated>)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
 ... 44 more

完搭如下:

[INFO] +- com.baomidou:mybatis-plus:jar:3.5.3.1:compile
[INFO] |  \- com.baomidou:mybatis-plus-extension:jar:3.5.3.1:compile
[INFO] |     \- com.baomidou:mybatis-plus-core:jar:3.5.3.1:compile
[INFO] |        +- com.baomidou:mybatis-plus-annotation:jar:3.5.3.1:compile
[INFO] |        \- org.mybatis:mybatis:jar:3.5.16:compile
[INFO] +- org.mybatis:mybatis-spring:jar:3.0.0:compile
[INFO] +- com.github.pagehelper:pagehelper:jar:5.3.1:compile
[INFO] |  \- com.github.jsqlparser:jsqlparser:jar:4.2:compile

嗯,从上面dependency tree(依赖树)可以看到,pagehelper:jar:5.3.1 依赖了jsqlparser:jar:4.2。 见 pagehelper-5.3.1.pom

<dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>4.2</version>
        </dependency>

经测:mybatis-plus-3.5.3.1 或者 mybatis-plus-3.5.3 均可。看来同一版本的小迭代在这一点是相同的。

而 mybatis-plus-3.5.7 则显式引入了 com.github.jsqlparser:jar:4.9。见 mybatis-plus-3.5.7.pom

<dependency>
      <groupId>com.github.jsqlparser</groupId>
      <artifactId>jsqlparser</artifactId>
      <version>4.9</version>
      <scope>compile</scope>
    </dependency>

如果项目要使用 mybatis-plus-3.5.7,即使排除了jsqlparser,运行程序依然报上面错误:java.lang.InstantiationError: net.sf.jsqlparser.statement.select.SelectItem。待进一步研究。

来了!同时支持mybatis-plus原生分页 和 github.pageHelper分页

方式一:xml配置

<property name="plugins">
    <array>
        <bean class="com.github.pagehelper.PageInterceptor">
            <property name="properties">
                <value>
                    helperDialect=oracle
                </value>
            </property>
        </bean>
        <bean class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
            <property name="interceptors">
                <list>
                    <bean class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor">
                        <property name="maxLimit" value="2"></property>
                    </bean>
                </list>
            </property>
        </bean>
    </array>
</property>

方式二:xml配置结合@Bean

<property name="plugins" ref="mybatisPlusInterceptors">
@Bean
public List<Interceptor> mybatisPlusInterceptors() {

    MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
    mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor() {{
        setMaxLimit(2L);
    }});

    PageInterceptor pageInterceptor = new PageInterceptor();
    Properties properties = new Properties();
    properties.setProperty("helperDialect", "oracle");
    pageInterceptor.setProperties(properties);

    return Arrays.asList(mybatisPlusInterceptor, pageInterceptor);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/899434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Springboot基于微信小程序的同城优惠软件的开发-计算机毕设 附源码24287

Springboot基于微信小程序的同城优惠软件的开发 摘要 随着互联网技术的发展&#xff0c;网络购物越来越受到大家的欢迎。电子商务这一概念大家都不在陌生。通过互联网进行的商品贸易范围越来越广泛&#xff0c;从经典的电子商品、到化妆品、书籍等&#xff0c;发展到小吃商品&a…

PCL学习——点云基础

点云基础 一、什么是三维点云二、获取三维点云的几种方式三、主要挑战四、什么是PCL 一、什么是三维点云 三维点云&#xff08;3D Point Cloud&#xff09;是一种用于表示三维空间中对象或场景的数据结构。在最基础的形式中&#xff0c;它是一个包含多个三维坐标点&#xff08…

SpringBoot民宿预定信息管理系统-计算机毕业设计源码89828

目 录 摘要 1 绪论 1.1 选题背景与意义 1.2研究背景 1.3论文结构与章节安排 2 民宿预定信息管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分…

Pytest日志收集器配置

前言 在pytest框架中&#xff0c;日志记录&#xff08;logging&#xff09;是一个强大的功能&#xff0c;它允许我们在测试期间记录信息、警告、错误等&#xff0c;从而帮助调试和监控测试进度。 pytest与Python标准库中的logging模块完美集成&#xff0c;因此你可以很容易地在…

Spring源码解析(35)之Spring全体系源码流程图

一、前言 画了一个spring全体系的流程图&#xff0c;spring容器创建过程&#xff0c;spring生命周期过程&#xff0c;AOP过程&#xff0c;Spring事务执行过程。 二、Spring体系源码图

【1024程序员节】之C++系列完结篇:Web编程

文章目录 一、Web编程1. 使用C标准库和第三方库2. 使用CWeb框架3. 使用C与JavaScript的集成4. 数据库交互5. 部署和运维 二、CppCMS框架构建Web应用1. 安装 CppCMS&#xff1a;2. 创建项目目录和文件3. 编写源代码4. 编译和运行5. 访问 Web 应用 三、HTTP介绍1. 请求头部字段&a…

Vue项目的创建

安装Vue工具 Vue CLI Vue CLI Vue.js 开发的标准工具&#xff0c;Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统 npm install -g vue/cli安装之后&#xff0c;你就可以在命令行中访问 vue 命令。你可以通过简单运行 vue&#xff0c;看看是否展示出了一份所有可用命令的…

qt QApplication详解

一、概述 QApplication是Qt应用程序的基础类&#xff0c;负责设置和管理应用的环境。它的主要功能包括&#xff1a;初始化应用程序、管理事件循环、处理命令行参数、提供全局设置&#xff08;如样式和调色板&#xff09;以及创建和管理主窗口。通常在main函数中创建QApplicati…

Netty简单应用

1.服务端构建 接收客户端请求&#xff0c;打印请求消息&#xff1b;消息采用内置String作为编码与解码器&#xff1b;开启信息输入监听线程&#xff0c;发送消息至客户端&#xff1b; 1.1 服务端消息处理类 import io.netty.channel.Channel; import io.netty.channel.Chann…

React实现购物车功能

今日学习React的useReducer&#xff0c;实现了一个购物车功能 文章目录 目录 效果展示 逻辑代码 CSS代码 效果展示 逻辑代码 import {useReducer} from "react"; import ./index.css; import { message} from antd;export function ShoppingCount(){// 初始化购…

去哪儿旅行携手 HarmonyOS SDK | 告别繁琐,常用信息秒级填充

背景 去哪儿旅行作为行业内领先的一站式在线旅游平台&#xff0c;多年来在日益加剧的市场竞争中积极寻求创新&#xff0c;凭借其优质的服务深受消费者青睐。2024年&#xff0c;去哪儿旅行适配HarmonyOS NEXT版本&#xff0c; 升级用户服务体验。 当前&#xff0c;去哪儿旅行应…

HTML+JavaScript 贪吃蛇游戏实现与详解

在网页开发的领域中&#xff0c;利用 HTML 和 JavaScript 能够创造出各种引人入胜的互动游戏。其中&#xff0c;贪吃蛇作为一款经典之作&#xff0c;以其简单易玩的特性和紧张刺激的挑战&#xff0c;一直深受玩家的喜爱。本文将详细阐述如何运用 HTML 和 JavaScript 来打造一个…

OPPO携手比亚迪共同探索手机与汽车互融新时代

10月23日&#xff0c;OPPO与比亚迪宣布签订战略合作协议&#xff0c;双方将共同推进手机与汽车的互融合作&#xff0c;这一合作也标志着两大行业巨头在技术创新和产业融合上迈出了重要一步&#xff0c;为手机与汽车的深度融合探索新的可能。 OPPO创始人兼首席执行官陈明永、OP…

鸿蒙网络编程系列3-TCP客户端通讯示例

1. TCP简介 TCP协议是传输层最重要的协议&#xff0c;提供了可靠、有序的数据传输&#xff0c;是多个广泛使用的表示层协议的运行基础&#xff0c;相对于UDP来说&#xff0c;TCP需要经过三次握手后才能建立连接&#xff0c;建立连接后才能进行数据传输&#xff0c;所以效率差了…

【PDF文件】默认被某种软件打开,如何进行修改?

当有时下载某种软件后&#xff0c;电脑中的PDF文件就默认由该种软件打开&#xff0c;每次需要右键选择打开方式才能选择需要的其他软件打开。如下图所示。 修改方法&#xff1a; &#xff08;1&#xff09;点击电脑的“设置”&#xff0c;选择应用 &#xff08;2&#xff09;…

Java一站式校园社区外卖系统小程序源码

一站式校园社区外卖系统&#xff0c;让校园生活更便捷&#xff01; &#x1f3eb; 开篇&#xff1a;校园生活的“新宠儿” 嘿&#xff0c;小伙伴们&#xff01;今天要和大家分享一个超级实用的校园生活神器——“一站式校园社区外卖系统”&#xff01;在这个快节奏的时代&…

一个开源可私有化部署的没有任何广告的网易云

优点 ✅ 使用 Vue.js 全家桶开发&#x1f534; 网易云账号登录&#xff08;扫码/手机/邮箱登录&#xff09;&#x1f4fa; 支持 MV 播放&#x1f4c3; 支持歌词显示&#x1f4fb; 支持私人 FM / 每日推荐歌曲&#x1f6ab;&#x1f91d; 无任何社交功能&#x1f30e;️ 海外用…

歌手如何建立抖音百科?塑造个人形象!

在抖音这个充满无限可能的舞台上&#xff0c;明星们以独特的魅力吸引着亿万粉丝的目光。而抖音百科&#xff0c;作为明星们展示自我、塑造形象的又一重要窗口&#xff0c;正逐渐成为连接明星与粉丝的桥梁。 创建明星人物抖音百科&#xff0c;不仅是对明星过往成就的总结与回顾&…

WRB Hidden Gap,WRB隐藏缺口,MetaTrader 免费公式!(指标教程)

WRB Hidden Gap MetaTrader 指标用于检测和标记宽范围的柱体&#xff08;非常长的柱体&#xff09;或宽范围的烛身&#xff08;具有非常长实体的阴阳烛&#xff09;。此指标可以识别WRB中的隐藏跳空&#xff0c;并区分显示已填补和未填补的隐藏跳空&#xff0c;方便用户一眼识别…

uniapp移动端优惠券! 附源码!!!!

本文为常见的移动端uniapp优惠券&#xff0c;共有6种优惠券样式&#xff08;参考了常见的优惠券&#xff09;&#xff0c;文本内容仅为示例&#xff0c;您可在此基础上调整为你想要的文本 预览效果 通过模拟数据&#xff0c;实现点击使用优惠券让其变为灰色的效果&#xff08;模…