收获tips
记录工作中学到的知识
- 1、Lombok 的 @Builder 注解
- 2、Lombok 的 @Accessors 注解
- 2.1 fluent 属性
- 2.2 chain 属性
- 2.3 prefix 属性
- 3、CharSequence
- 4、springboot 参数校验
- 5、Mybatis 方法单个参数
- 6、
1、Lombok 的 @Builder 注解
@Builder 注释为类生成相对略微复杂的构建器API。@Builder 可以让你以下面显示的那样调用你的代码,来初始化实例对象:
Student.builder()
.sno( "001" )
.sname( "admin" )
.sage( 18 )
.sphone( "110" )
.build();
我们在对实体对象进行操作时,往往会存在对某些实体对象的某个字段进行二次赋值。@Builder 注解里有个 toBuilder() 方法,使用 toBuilder() 可以实现以一个实例为基础继续创建一个对象,也就是重用原来对象的值。但是,这会创建一个新的对象,而不是原来的对象,原来的对象属性是不可变的,除非你自己想要给这个实体类再添加上 @Data 或者 @Setter 方法。
转载自:详解Lombok中的@Builder用法
2、Lombok 的 @Accessors 注解
(1)该注解主要作用是:当属性字段在生成 getter 和 setter 方法时,做一些相关的设置。
(2)当它可作用于类上时,修饰类中所有字段,当作用于具体字段时,只对该字段有效。
该字段共有三个属性,分别是 fluent,chain,prefix。
2.1 fluent 属性
不写默认为false,当该值为 true 时,对应字段的 getter 方法前面就没有 get,setter 方法就不会有 set。
2.2 chain 属性
不写默认为false,当该值为 true 时,对应字段的 setter 方法调用后,会返回当前对象。
2.3 prefix 属性
该属性是一个字符串数组,当该数组有值时,表示忽略字段中对应的前缀,生成对应的 getter 和 setter 方法。
比如现在有 xxName 字段和 yyAge 字段,xx 和 yy 分别是 name 字段和 age 字段的前缀。
那么,我们在生成的 getter 和 setter 方法如下,它也是带有 xx 和 yy 前缀的。
如果,我们把它的前缀加到 @Accessors 的属性值中,则可以像没有前缀那样,去调用字段的 getter和 setter 方法。
转载自:@Accessors 注解详解
3、CharSequence
CharSequence 在 java.lang 包下,是一个描述字符串结构的接口,表示 char 值的一个可读序列。此接口对许多不同种类的 char 序列提供统一的自读访问。此接口不修改 equals 和 hashCode 方法的常规协定,因此,通常未定义比较实现 CharSequence 的两个对象的结果。他有几个实现类:CharBuffer、String、StringBuffer、StringBuilder。
CharSequence 与 String 都能用于定义字符串,但 CharSequence 的值是可读可写序列,而 String 的值是只读序列。
对于抽象类或者接口来说不可以直接使用new的方式创建对象,但是可以直接给它赋值进行实例的创建:
CharSequence cs="hello";
参考自:CharSequence详情介绍
4、springboot 参数校验
实际业务开发中,为了避免入参错误对业务系统有影响,一般会都会在Controller层进行参数校验,常见的方式主要包含了两种:
get、delete等请求,参数形式为RequestParam/PathVariable
post、put等请求,参数形式为RequestBoty
RequestParam/PathVariable形式的参数校验
Get、Delete请求一般会使用RequestParam/PathVariable形式参数参数,这种形式的参数校验一般需要以下两个步骤,如果校验失败,会抛出ConstraintViolationException异常。
必须在Controller类上标注@Validated注解;
在接口参数前声明约束注解(如@NotBlank等)
@Validated
@RestController
@RequestMapping("/validate")
public class ValidationController {
private Logger log = LoggerFactory.getLogger(ValidationController.class);
/**
* get、delete请求使用requestParam/PathVariable形式传递参数的,
* 参数校验需要在Controller添加上@Validated注解,并在参数列表中添加对应的校验注解即可
*
* @param id ID
* @return true/false 成功或失败
*/
@GetMapping("/get")
public ResultObject<Boolean> validateGetRequest(@NotBlank(message = "id不能为空") String id,
@NotBlank(message = "appkey不能为空") String appkey) {
// 具体业务逻辑调用
log.info("id [{}] appKey [{}]", id, appkey);
return ResultObject.success();
}
}
转载自:springboot 参数校验
5、Mybatis 方法单个参数
正常情况下,mybatis 在进行参数判断的时候,直接用就可以了,使用 entity 实体或者 Map 的时候,下面的代码是正确的:
是单个参数和多参数的判断有个不同点,当我们的入参为 entity 实体,或者 map 的时候,使用 if 参数判断没任何问题。但是当我们的入参为 java.lang.Integer 或者 java.lang.String 的时候,这时候就需要注意一些事情了。
我们需要使用 if 参数判断 引入参数,会抛异常 nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘deptId’ in ‘class java.lang.String’
<select id="queryList" resultType="com.soft.back.model.OutdevFactory"
parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
from op_outdev_factory
<where>
<if test="factoryName != null">
and name like concat('%',#{factoryName},'%')
</if>
</where>
</select>
原因就是对于这类单个入参然后用 if 判断的,mybatis 有自己的内置对象,Mybatis 默认采用 OGNL 解析参数,所以会自动采用对象树的形式取 string.xxx 值,如果没在方法中定义,则会抛异常报错。
解决方案:
方案一:把 #{xxx} 修改为 #{_parameter}
<select id="queryList" resultType="com.soft.back.model.OutdevFactory"
parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
from op_outdev_factory
<where>
<if test="_parameter != null">
and name like concat('%',#{_parameter},'%')
</if>
</where>
</select>
方案二:在方法中提前定义
/**
* 查询厂家列表
* @param factoryName
* @return
*/
List<OutdevFactory> getFactoryList(@Param("factoryName") String factoryName);
<select id="queryList" resultType="com.soft.back.model.OutdevFactory"
parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
from op_outdev_factory
<where>
<if test="factoryName!= null">
and name like concat('%',#{factoryName},'%')
</if>
</where>
</select>
转载自:【Mybatis异常】nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter