尚硅谷尚庭公寓学习笔记
@Builder 注解
- 加在实体类上
// 使用@Builder(链式调用)
ApartmentVO vo = ApartmentVO.builder().id(1001L).name("阳光公寓").build(); // 最终通过build()方法生成对象
saveOrUpdate
当调用 saveOrUpdate(T entity)
时:
- 如果主键不存在,则插入数据
- 如果主键已存在,更新数据
使用 Minio 上传图片
-
引入依赖
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId> </dependency>
-
配置
Minio
相关参数minio:endpoint: http://<hostname>:<port>access-key: <access-key>secret-key: <secret-key>bucket-name: <bucket-name>
-
创建
MinioProperties
:@ConfigurationProperties(prefix = "minio") @Data public class MinioProperties {private String endpoint;private String accessKey;private String secretKey;private String bucketName; }
-
创建
MinioConfiguration
:@Configuration @EnableConfigurationProperties(MinioProperties.class) public class MinioConfiguration {@Autowiredprivate MinioProperties properties;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).build();} }
-
Controller
层逻辑:@Tag(name = "文件管理") @RequestMapping("/admin/file") @RestController public class FileUploadController {@Autowiredprivate FileService service;@Operation(summary = "上传文件")@PostMapping("upload")public Result<String> upload(@RequestParam MultipartFile file) {String url = service.upload(file);return Result.ok(url);} }
-
Service
层逻辑:@Autowired private MinioProperties properties;@Autowired private MinioClient client;@Override public String upload(MultipartFile file) {try {boolean bucketExists = client.bucketExists(BucketExistsArgs.builder().bucket(properties.getBucketName()).build());if (!bucketExists) {client.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build());client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(properties.getBucketName()).config(createBucketPolicyConfig(properties.getBucketName())).build());}String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();client.putObject(PutObjectArgs.builder().bucket(properties.getBucketName()).object(filename).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build());return String.join("/", properties.getEndpoint(), properties.getBucketName(), filename);} catch (Exception e) {e.printStackTrace();}return null; }private String createBucketPolicyConfig(String bucketName) {return """{"Statement" : [ {"Action" : "s3:GetObject","Effect" : "Allow","Principal" : "*","Resource" : "arn:aws:s3:::%s/*"} ],"Version" : "2012-10-17"}""".formatted(bucketName); }
createBucketPolicyConfig
的作用是生成用于描述指定bucket
访问权限的JSON
字符串。最终生成的字符串格式如下,其表示,允许(Allow
)所有人(*
)获取(s3:GetObject
)指定桶(<bucket-name>
)的内容{"Statement" : [ {"Action" : "s3:GetObject","Effect" : "Allow","Principal" : "*","Resource" : "arn:aws:s3:::<bucket-name>/*"} ],"Version" : "2012-10-17" }
-
集合判空
-
collection != null
:判断集合对象是否为null
, 集合为空也返回true
-
!CollectionUtils.isEmpty(collection)
:同时判断是否为null
以及是否为空
UpdateWrapper
LambdaUpdateWrapper<LeaseAgreement>queryWrapper=new LambdaUpdateWrapper<>();queryWrapper.eq(BaseEntity::getId,id)
.set(LeaseAgreement::getStatus,status); this.update(queryWrapper);
等价于:
UPDATE apartment_info SET is_release = ?
IPage
的作用
创建:
IPage<ApartmentItemVo> resultPage = new Page<>(apartmentPage.getCurrent(), // 当前页码(如第1页、第2页)apartmentPage.getSize(), // 每页显示的记录数(如每页10条)apartmentPage.getTotal() // 总记录数(符合查询条件的所有记录总数)
);//也可以复用原来的
IPage<HistoryItemVo> resultPage = new Page<>(current, size);
resultPage.setRecords(historyItemVos);
设置每一页的记录:
resultPage.setRecords(voList);
lambada表达式写法
List<SystemUserItemVo> itemVos = userIPage.getRecords().stream() .map(user -> { SystemUserItemVo vo = new SystemUserItemVo(); BeanUtils.copyProperties(user, vo); // 拷贝属性(字段名一致时生效) return vo; }) .collect(Collectors.toList());// 提取支付类型ID(使用Stream API简化代码)
List<Long> paymentTypeIds = roomPaymentTypes.stream() .map(RoomPaymentType::getPaymentTypeId) .collect(Collectors.toList());
ModelMapper
-
BeanUtils
需要两个对象的属性名需要完全相同才能映射 ;ModelMapper
支持相似名称映射,username
可以映射到userName
-
ModelMapper
的效率更好
使用:
// 将 UserEntity 转换为 UserVO
modelMapper.map(user,vo);
验证码生成
EasyCaptcha
工具
<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId>
</dependency>
逻辑删除
如果在实体类中设置了逻辑删除 @TableLogic
, service.list()
会过滤掉逻辑删除的记录
下面的方法错误,因为该方法不能用于拷贝两个集合的属性, 只能用于拷贝两个对象实例
//拷贝属性
List<FeeValue> feeValues
List<FeeValueVo> feeValueVoList=new ArrayList<>();
BeanUtils.copyProperties(feeValues,feeValueVoList);
@Async 注解
@Async
异步执行注解,作用是:将被标记的方法提交到线程池异步执行,调用方(主线程)不会等待该方法执行完成,而是直接继续执行后续逻辑
注意异步方法必须定义在被 Spring
管理的 Bean
中(如 @Service
类)