不知道大家有没有用过 Lombok?里面的 @Builder 注解使用的创建者模式又叫建造者模式。简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程。...创建一个名为 ThisClassBuilder 的内部静态类,并具有和实体类形同的属性(称为构建器)。 在构建器中:对于目标类中的所有的属性和未初始化的final字段,都会在构建器中创建对应属性。...在构建器中:创建一个无参的default构造函数。 在构建器中:对于实体类中的每个参数,都会对应创建类似于setter的方法,只不过方法名与该参数名相同。...在实体类中:会创建一个builder()方法,它的目的是用来创建构建器。...在使用 @Singular 注释注释一个集合字段(使用 @Builder 注释类),lombok 会将该构建器节点视为一个集合,并生成两个 adder 方法而不是 setter 方法。
它返回与目标返回相同的类型 有意义的toString()实现 在包含target的类中:一个builder()方法,该方法创建builder的新实例 如果该元素已存在,则每个列出的生成元素都将被静默跳过...这包括构建器本身:如果该类已经存在,则lombok会简单地开始在此现有类中注入字段和方法,除非要注入的字段/方法当然已经存在。...toBuilder();它创建一个新的构建器,该构建器以该实例的所有值开始。...您可以将@Builder.ObtainVia注释放在参数(对于构造函数或方法的情况)或字段(对于@Builder类型的情况)上,以指示从该实例获取该字段/参数的值的替代方法。...同时在子类和全参数的构造器使用 @Builder 注解,最终的 build() 函数只返回了空参的构造器创建的一个子类对象,因此属性“采用 builder 方式设置的 字段最终都丢失了。
> 3.基于Lombok Builder的POJO 首先,让我们看看 Lombok如何帮助我们从实现 Builder模式所需的样板代码中解脱出来。...,我们需要给每个字段实现一个getter。...我们可以通过在Builder注解中配置toBuilder参数来启用: // class annotations as before // 添加在类上的注解同上 @Builder(toBuilder =...当然,这也是有代价的。我们必须通过 实例化这个类来创建一个Builder实例。...因此使用无参构造函数与使用Builder具有相同的默认值。 8.总结 至此,我们已经展示了为Lombok Builder提供默认值的几种方法。 Builder.Default注解的副作用也很明显。
Lombok是一个Java库,它通过注解的方式,在编译时期自动生成模板方法、构造函数、getter/setter等,从而减少冗余的代码,让开发者能够专注于业务逻辑的实现。...它为类生成所有字段的getter/setter方法,以及equals()、hashCode()和toString()方法。...,它生成了一个内部的Builder类,以及一个builder()静态方法。...复杂的链式调用通过@Builder注解,我们可以创建复杂的链式调用,使得对象的创建更加灵活。...(List.of("reading", "hiking")) .build();泛型方法的简化Lombok还可以简化泛型方法的编写。
最新解决方案: 对于一些实在复杂的查询,比如find_in_set,也可以直接使用原生SQL语句进行查询,例如: Db::table('think_user') ->where('find_in_set...select(); 如果用数组条件查询形式的话,那么像下面这么写查询条件即可: $where[]=['exp','FIND_IN_SET(2,sids)']; 当然也有朋友说建议用like,like是广泛的模糊匹配...,字符串中没有分隔符,Find_IN_SET 是精确匹配,字段值以英文","分隔,Find_IN_SET查询的结果要小于like查询的结果。
; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.xml.bind.annotation.XmlAccessType...package com.gwf.gwf.weather.basic.vo * @describe 天气实体类与xml映射 * @date 2018/2/20 */ @Data @Builder(toBuilder...= true) @NoArgsConstructor @AllArgsConstructor // 以上为lombok注解,方便生成getter/setter方法 @XmlRootElement(name...(XmlAccessType.FIELD) // 控制默认情况下字段还是Javabean属性序列化。...xmlStrToObject(Class clazz,String xmlStr) throws Exception{ Object xmlObject = null; // 创建
创建目录 os.Mkdir创建单个目录函数原形func Mkdir(name string, perm FileMode) error输入一个目录的名称和目录的权限,我们可以用默认的os.ModePerm...('\\') { //前边的判断是否是系统的分隔符 path = "\\" } else { path = "/" } fmt.Println(path) dir, _ := os.Getwd...= nil { fmt.Println(err) } fmt.Println("创建目录" + dir + path + "md成功") } os.MkdirAll()函数原形是func MkdirAll...(path string, perm FileMode) error输入的是多级目录结构和权限返回的是error的信息 复制代码代码如下: import ( "fmt" "os" ) func...= nil { fmt.Println(err) } fmt.Println("创建文件夹" + dir + "/a/b/c成功") }
更有甚者,由于字段太多,想要使用builder来创建。手动创建builder和字段和原来的类夹杂在一起,看起来真的难受。lombok的@Builder即可解决这个问题。...Getter声明创建getter方法; Setter声明创建setter方法; @Setter(AccessLevel.PROTECTED)可以添加参数,指定权限为私有; Attention!...@NonNull将标注这个字段不应为null,初始化的时候会检查是否为空,否则抛出NullPointException。在上面的无参构造函数中被忽略了。...其他默认,Java的class初始化默认为null.false,0. lombok提供了另一种初始化做法,静态初始化。即私有构造器,使用静态方法创建对象。这种做法看起来简单,但通常用的不多。...但是,手动复制字段,手动创建方法很让人不喜。@Builder解决了刚需。
创建目录 os.Mkdir创建单个目录函数原形func Mkdir(name string, perm FileMode) error输入一个目录的名称和目录的权限,我们可以用默认的os.ModePerm...然后返回的是一个error的信息,我们看下,也一块复习前边的一点知识 import ( "fmt" "os" ) func main() { var path string if os.IsPathSeparator...('\\') { //前边的判断是否是系统的分隔符 path = "\\" } else { path = "/" } fmt.Println(path) dir, _ := os.Getwd...= nil { fmt.Println(err) } fmt.Println("创建目录" + dir + path + "md成功") } os.MkdirAll()函数原形是func MkdirAll...= nil { fmt.Println(err) } fmt.Println("创建文件夹" + dir + "/a/b/c成功") }
buildMethodName:构建器类中创建构造器实例的方法名称 builderClassName:构造器类名 toBuilder:生成toBuilder方法 例子 public Example.ExampleBuilder...,方法体不能带有参数,默认为close @Data 作用 生成所有字段的getter、toString()、hashCode()、equals()、所有非final字段的setter、构造器,相当于设置了...hashCode(),默认:false doNotUseGetters:是否不调用字段的getter,默认如果有getter会调用。...的返回值为this fluent:为true时,默认设置chain为true,setter的方法名修改为字段名 @Delegate 作用 代理模式,把字段的方法代理给类,默认代理所有方法 参数 types...extends String> var1); } } @ExtensionMethod 作用 拓展方法,向现有类型“添加”方法,而无需创建新的派生类型。有点像kotlin的扩展函数。
// 标识在执行字段计算前,是否调用父类的equals和hashCode方法 boolean callSuper() default false; boolean doNotUseGetters...{ // 打印输出时是否包含字段的名称 boolean includeFieldNames() default true; // 列出打印输出时,需要排除的字段列表...String[] exclude() default {}; // 显式的列出需要打印输出的字段列表 String[] of() default {}; // 打印输出的结果中是否包含父类的...@Target(FIELD) @Retention(SOURCE) public @interface Default {} // 创建新的builder实例的方法名称...,将会自动生成一个 withFieldName(newValue) 的方法,该方法会基于 newValue 调用相应构造函数,创建一个当前类对应的实例。
{ // 打印输出时是否包含字段的名称 boolean includeFieldNames() default true; // 列出打印输出时,需要排除的字段列表 String[]...exclude() default {}; // 显式的列出需要打印输出的字段列表 String[] of() default {}; // 打印输出的结果中是否包含父类的toString...@Target(FIELD) @Retention(SOURCE) public @interface Default {} // 创建新的builder实例的方法名称 String builderMethodName...() default "builder"; // 创建Builder注解类对应实例的方法名称 String buildMethodName() default "build"; // builder...,将会自动生成一个 withFieldName(newValue) 的方法,该方法会基于 newValue 调用相应构造函数,创建一个当前类对应的实例。
io.swagger.annotations.ApiModelProperty; import java.util.Date; import javax.persistence.Column; import lombok.Data...") private Date createDate; } 字段上有@ApiModelProperty注解用于swagger文档注释说明。...如果是Date属性的字段,有@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")用于日期格式化。...--忽略getter/setter方法--> 实体类注释,..."false"/> <property name="builder.<em>toBuilder</em>
他可以看到一个数据库里的表名、字段名、字段类型、和字段大小的信息。 建立两个这样的视图,一个读取客户的数据库,一个读取新的数据库。这样我们就有了两个数据库的表和字段的信息的列表了。...col INNER JOIN .sysobjects obj ON col.id = obj.id ORDER BY obj.name 2、执行查询语句 我们可以使用 not in 的方式来检查表名是否一致...当然是在表名一致的前提下才能进行字段的对比。 3、下面就是对照字段类型,然后字段的大小。 需要的SQL语句我还没有写出来。估计不是太难吧。...这种方法已经在我的一个项目里试验了一下,基本是正确的。 4、不过还是发现了几个问题。 1、缺少表的话可以使用企业管理器来自动生成键表语句,但是添加字段就有一点麻烦了。...不过对于视图和存储过程 只能得知名称和字段、参数是否一致,如果参数没有变化,只是修改了一下内容的话就检查不出来了。 3、如果是修改表名或者是修改字段名、删除字段名就没有检查了。
Lombok in IntelliJ IDEA Lombok in Eclipse 三、Lombok详解 注解说明 val:用在局部变量前面,相当于将变量声明为final @NonNull:给方法参数增加这个注解会自动在方法内对该参数进行是否为空的校验...// 标识在执行字段计算前,是否调用父类的equals和hashCode方法 boolean callSuper() default false; boolean doNotUseGetters...{ // 打印输出时是否包含字段的名称 boolean includeFieldNames() default true; // 列出打印输出时,需要排除的字段列表...,将会自动生成一个 withFieldName(newValue) 的方法,该方法会基于 newValue 调用相应构造函数,创建一个当前类对应的实例。...IDE工具问题解决: 现在有一个A类,其中有一些字段,没有创建它们的setter和getter方法,使用了lombok的@Data注解,另外有一个B类,它调用了A类实例的相应字段的setter和getter
3.2+ 开发工具 IntelliJ IDEA smartGit 创建一个SpringBoot Initialize项目 选择jdk8 选择lombok和spring web 项目建好之后...return desc; } public void setDesc(String desc) { this.desc = desc; } } 因为要校验传入参数是否为枚举类里的类型...,然后通过@Constraint指定具体的校验类,通过反射机制获取对应的方法,比如isValueValid这个方法 package com.example.common.util.validator;...> vclass = o.getClass(); try { // 反射机制获取具体的校验方法 Method method...; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.SuperBuilder
有的方法看看就好,知道可以这么用,但是否应用到实际开发中,那就仁者见仁,智者见智了。 一万个读者就会有一万个哈姆雷特,希望这篇文章能够给您带来一些思考。 耐心看完,你一定会有所收获。...@Singular注解可以用在集合类型的字段上,它会生成两个方法,一个是添加单个元素的方法,一个是添加整个集合的方法。...这两个方法可以和 @Builder 生成的其他方法一起链式调用,给你的类的所有字段赋值。...,你可以灵活地添加集合类型的字段,而不需要自己创建和初始化集合对象。...@With 允许你创建一个新的对象,该对象是当前对象的副本,但某些字段的值已被更改。
过多的数据复制有可能会造成内存占用的问题,但就跟所有性能问题一样,这种情况并不常见。 若共享的数据需要更新,将其复制多份的做法就会遇到巨大困难。此时我必须找到所有副本,更新所有对象。...漏掉一个副本没更新,就会导致数据不一致。这时,考虑将多份数据副本变成单一的引用,这样对顾客数据的修改就会立即反映在该顾客的所有订单中。...我在*Customer****中定义工厂方法: package com.javaedge.refactor.ttt; import lombok.AllArgsConstructor; import...我比较喜欢通过另一个对象(例如Order中的一个字段)来访问它。但本例并没有这样一个明显的字段用于访问Customer对象。...简化例子,我把这个注册表保存在Customer类的static字段中,让Customer类作为访问点: 然后我得决定: 在接到请求时,创建新的Customer对象 还是预先将它们创建好 这里我选择后者。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。...ThreadLocal常用方法: public void set(T value) 设置当前线程的线程局部变量的值 public T get() 返回当前线程所对应的线程局部变量的值 三、解决方法... 在LoginCheckFilter的doFilter方法中获取当前登录用户id,并调用ThreadLocal的set方法来设置当前线程的线程局部变量的值(用户id),然后在MyMetaObjectHandler...的updateFill方法中调用ThreadLocal的get方法来获得当前线程所对应的线程局部变量的值(用户id)。...,并没有检查删除的分类是否关联了菜品或者套餐,我们需要进行功能完善。
新添分类 分类信息分页查询 删除分类 修改分类 公共字段自动填充 我们的功能开发一般分为三个阶段 需求分析 前面我们已经完成了后台系统的员工系统的开发,在新增或修改员工时需要填写创建时间创建人修改时间修改人等繁杂信息...而且这些属性基本在后续的菜品,套餐中都有所体现,我们把这些字段称为公共字段,所以我们希望采用一种统一的方法来设置: MyBatisPlus为我们提供了公共字段自动填充的功能 我们先来简单介绍一下流程:...当使用ThreadLocal维护变量时,每个使用该变量的线程具有独立的变量副本。 每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。...,而是存储在Dish和Setmeal数据表中: 所以我们需要创建这两者的基本信息,并在Category的业务层中修改默认代码,创建一个符合我们要求的方法 代码实现 首先我们将创建Dish和Setmeal...工具类的使用 在公共字段自动填充的部分,我们为了使用ThreadLocal从而创建了相对的工具类 我们的工具类就是为了便捷操作而使用的,我们为了使用相关的参数但同时多次不用创建实体而直接使用工具类 例如我们的
领取专属 10元无门槛券
手把手带您无忧上云