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

网站没被百度收录淘宝优惠券网站怎么做

网站没被百度收录,淘宝优惠券网站怎么做,十堰网站seo方法,郑州工作很多小伙伴可能都用过 MyBatis-Plus#xff0c;这里边我们构造 where 条件的时候#xff0c;可以直接通过方法引用的方式去指定属性名#xff1a; LambdaQueryWrapperBook qw new LambdaQueryWrapper(); qw.eq(Book::getId, 2); ListBook list bo…很多小伙伴可能都用过 MyBatis-Plus这里边我们构造 where 条件的时候可以直接通过方法引用的方式去指定属性名 LambdaQueryWrapperBook qw new LambdaQueryWrapper(); qw.eq(Book::getId, 2); ListBook list bookMapper.selectList(qw); System.out.println(list list); Book::getId 这就是方法引用之前也专门写过文章介绍相关内容这里就不再多说。这里我们就单纯来说说为什么 MP 通过 Book::getId 就可以识别出来这里的属性名。 1. 源码分析 这个问题其实好解决我们顺着 qw.eq 这个方法往下看就可以了这个方法在执行的过程中几经辗转会来到 getColumnCache 方法中这个方法就是解析出来属性值的地方。 protected ColumnCache getColumnCache(SFunctionT, ? column) {LambdaMeta meta LambdaUtils.extract(column);String fieldName PropertyNamer.methodToProperty(meta.getImplMethodName());Class? instantiatedClass meta.getInstantiatedClass();tryInitCache(instantiatedClass);return getColumnCache(fieldName, instantiatedClass); } 首先这里先将我们传入的 Lambda 表达式通过 LambdaUtils.extract 方法解析出来一个 LambdaMeta 对象。 public static T LambdaMeta extract(SFunctionT, ? func) {// 1. IDEA 调试模式下 lambda 表达式是一个代理if (func instanceof Proxy) {return new IdeaProxyLambdaMeta((Proxy) func);}// 2. 反射读取try {Method method func.getClass().getDeclaredMethod(writeReplace);method.setAccessible(true);return new ReflectLambdaMeta((SerializedLambda) method.invoke(func), func.getClass().getClassLoader());} catch (Throwable e) {// 3. 反射失败使用序列化的方式读取return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract(func));} } 这块的重点其实就在反射读取这块这是从我们传入的 Lambda 中找到了一个名为 writeReplace 的方法并且通过反射执行了这个方法然后将执行结果封装为一个 ReflectLambdaMeta 对象返回。 接下来回到 getColumnCache 方法中继续通过 String fieldName PropertyNamer.methodToProperty(meta.getImplMethodName()); 获取到属性名称。 这里有一个 meta.getImplMethodName() 方法这个方法的拿到的其实就是我们 Lambda 表达式中的方法名也就是 getId然后再通过 PropertyNamer.methodToProperty 对这个方法名进行处理最终拿到属性名 public static String methodToProperty(String name) {if (name.startsWith(is)) {name name.substring(2);} else if (name.startsWith(get) || name.startsWith(set)) {name name.substring(3);} else {throw new ReflectionException(Error parsing property name name . Didnt start with is, get or set.);}if (name.length() 1 || name.length() 1 !Character.isUpperCase(name.charAt(1))) {name name.substring(0, 1).toLowerCase(Locale.ENGLISH) name.substring(1);}return name; } 大家看到这个解析的过程其实就是把方法名的前缀 get/set/is 这些去掉然后剩余的字符串首字母小写之后返回。 这就是我们传入 Book::getId最终能够拿到 id 这个名称的原因。 现在的问题变成了 writeReplace 方法究竟是个什么方法 2. writeReplace 这个方法其实是系统底层自动生成的。我们可以将 Lambda 表达式在运行时生成的字节码保存下来然后进行反编译这样就能够看到 writeReplace 方法了。 如果需要将 Lambda 运行时生成的字节码保存需要在启动参数中添加如下内容 -Djdk.internal.lambda.dumpProxyClasses/Users/sang/workspace/code/mp_demo/lambda/ 等于号后面的部分是指定生成的字节码的保存位置大家可以根据自己的实际情况去配置。 以本文一开头的 Lambda 表达式为例最终生成的字节码反编译之后内容如下 final class MpDemo02ApplicationTests$$Lambda$1164 implements SFunction {private MpDemo02ApplicationTests$$Lambda$1164() {}public Object apply(Object var1) {return ((Book)var1).getId();}private final Object writeReplace() {return new SerializedLambda(MpDemo02ApplicationTests.class, com/baomidou/mybatisplus/core/toolkit/support/SFunction, apply, (Ljava/lang/Object;)Ljava/lang/Object;, 5, org/javaboy/mp_demo02/model/Book, getId, ()Ljava/lang/Integer;, (Lorg/javaboy/mp_demo02/model/Book;)Ljava/lang/Object;, new Object[0]);} } 大家可以看到apply 方法实际上是重写的接口的方法在这个方法中将传入的对象强转为 Book 类型然后调用其 getId 方法。 然后大家看到反编译之后多了一个 writeReplace 方法这个方法的返回值是一个 SerializedLambda这个 SerializedLambda 对象其实就是对 Lambda 表达式的描述。基本上每个参数都能做到见名知意我这里说一下第七个参数值是 getId这个参数的变量名是 implMethodName这就是我们 Lambda 表达式中给出来的变量名。这也是第一小节中meta.getImplMethodName() 所获取到的值。 这下就清楚了为什么写了 Book::getId 就能拿到属性名了。 3. 扩展知识 有的小伙伴注意到在 qw.eq(Book::getId, 2); 方法中第一个参数是一个 SFunction 的实例那就说我直接给一个 SFunction 的实例不用 Lambda。大家注意这种写法不对 原因在于经过前面的源码分析之后我们发现MP 中根据 Book::getId 去获取属性名称一个关键点是利用 Lambda 在执行的时候生成的字节码去获取如果你都没有用 Lambda那也就不会生成所谓的 Lambda 字节码也就不存在 writeReplace 方法按照前文所分析的源码就无法获取到属性名称。 还有小伙伴说既然是 Lambda那么我不用方法引用行不行我像下面这样写行不行 LambdaQueryWrapperBook qw new LambdaQueryWrapper(); qw.eq(b - b.getId(), 2); ListBook list bookMapper.selectList(qw); System.out.println(list list); 这也是一个 Lambda但是如果你这样写了运行之后就会报错。为什么呢我们来看下这个 Lambda 生成的字节码反编译之后是什么样的 final class MpDemo02ApplicationTests$$Lambda$1164 implements SFunction {private MpDemo02ApplicationTests$$Lambda$1164() {}public Object apply(Object var1) {return MpDemo02ApplicationTests.lambda$test18$3fed5817$1((Book)var1);}private final Object writeReplace() {return new SerializedLambda(MpDemo02ApplicationTests.class, com/baomidou/mybatisplus/core/toolkit/support/SFunction, apply, (Ljava/lang/Object;)Ljava/lang/Object;, 6, org/javaboy/mp_demo02/MpDemo02ApplicationTests, lambda$test18$3fed5817$1, (Lorg/javaboy/mp_demo02/model/Book;)Ljava/lang/Object;, (Lorg/javaboy/mp_demo02/model/Book;)Ljava/lang/Object;, new Object[0]);} } 首先大家注意到 apply 方法生成的就不一样apply 里边调用了 MpDemo02ApplicationTests.lambda$test18$3fed5817$1 方法传入了 Book 对象作为参数。这个方法内容相当于就是 return book.getId();。然后在 writeReplace 方法中返回 SerializedLambda 对象的时候implMethodName 的值就是 lambda$test18$3fed5817$1 了。回到本文一开始的源码分析中你会发现这样的方法名就无法提取出来我们想要的属性名。所以这种写法也不对。 从这里大家也可以看到类似于 b - b.getId() 这样的 Lambda和方法引用 Book::getId 在底层是不同的。 再给小伙伴们举个例子比如下面一段代码 public class Demo01 {public static void main(String[] args) {ConsumerString out1 System.out::println;out1.accept(javaboy);ConsumerString out2 s - System.out.println(s);out2.accept(江南一点雨);} } 这里有两个输出第一个是一个方法引用第二个则是一个常规的 Lambda 表达式。这两个执行起来效果是一致的但是底层原理不同。 先来看第一个底层生成的 Lambda 字节码 final class Demo01$$Lambda$14 implements Consumer {private final PrintStream arg$1;private Demo01$$Lambda$14(PrintStream var1) {this.arg$1 var1;}public void accept(Object var1) {this.arg$1.println((String)var1);} } 可以看到这里把 System.out 的值 PrintStream 作为构造函数的参数传进来赋值给 arg$1 变量当调用 accept 方法的时候再调用 arg$1.println 方法将字符串输出。 对于第二个底层生成的 Lambda 字节码如下 final class Demo01$$Lambda$16 implements Consumer {private Demo01$$Lambda$16() {}public void accept(Object var1) {Demo01.lambda$main$0((String)var1);} } 可以看到这里有一个新的 lambda$main$0 方法这个方法的底层逻辑其实就是我们自定义 Lambda 的时候写的 System.out.println(s)。 3. 小结 好啦一篇小文和小伙伴们探讨下 MP 中 qw.eq(Book::getId, 2); 方法的底层逻辑。 前端的世界总是在不断变化作为开发者我们需要保持好奇心和学习热情不断探索新的技术只有这样我们才能在这个快速发展的时代中立于不败之地。Web Components 就是这样一个值得我们深入探索的领域让我们拭目以待它将给前端世界带来怎样的变革。 介绍一款程序员都应该知道的软件JNPF快速开发平台很多人都尝试用过它它是功能的集大成者任何信息化系统都可以基于它开发出来。 这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架。前后端封装了上千个常用类方便扩展集成了代码生成器支持前后端业务代码生成实现快速开发提升工作效率框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用后端框架支持 Vue2、Vue3。如果你有闲暇时间可以做个知识拓展。 看完本文如果觉得有用记得点个赞支持收藏起来说不定哪天就用上啦
http://www.w-s-a.com/news/313628/

相关文章:

  • 加强统计局网站的建设和管理广州微信网站建设价格
  • 华宁网站建设设计公司 网站
  • 简历网站免费怎么查在哪个网站做的备案
  • 响应式网站 价格网站用哪些系统做的比较好用
  • 高端网站案例360做的网站
  • 瑞安地区建设网站公众号开发者工具是干嘛的
  • 请解释网站开发的主要流程.wordpress主体上传
  • 网站方案组成要素饰品公司网站建设方案
  • 网站改版被降权赣州景文网络科技有限公司
  • 吉林省网站建设推广图片模版
  • 如何做网站热力图佛山 网站关键词优化
  • 个人网站建设论文中期报告申报网站建设理由 模板
  • 岫岩做网站软件开发和app开发的区别
  • 邯郸质量一站式服务平台上线如何做国外销售网站
  • 内蒙古工程建设协会网站sem优化策略
  • Linux网站建设总结建设电子商务平台
  • 公司网站背景图片课程网站如何建设
  • 用js做简单的网站页面互联网技术对人力资源管理的影响有哪些
  • 银川做网站贵德县wap网站建设公司
  • 深圳网站建设zvge山西省煤炭基本建设局网站
  • 佛山网页网站设计线上怎么做推广和宣传
  • 多个域名绑定同一个网站案例
  • 建设网站都需要准备什么代理加盟微信网站建设
  • 网站备案没有了wordpress 添加按钮
  • 湖南建设银行宣传部网站福田蒙派克空调滤芯安装位置图
  • wap网站搜索wordpress工作室模板
  • 青岛金融网站建设如何提交网站地图
  • 制作简单门户网站步骤网站建设论文的摘要
  • 可以直接进入网站的正能量照片学做静态网站
  • 织梦做社交网站合适吗网站的市场如何制作