1.AOP实现-公共字段填充
1.1大体思路
(1)自定义注解,用于标识需要进行公共字段自动填充的方法
(2)自定义切面类,同意拦截加入自定义的方法,通过反射为字段赋值
(3)在需要拦截的Mapper的方法上加入自定义注解
1.2反射详细实现
/**
* 前置通知,在通知中进行公共字段的赋值(update_user,update_time)
*/
@Before("autoFillPointCut()")//前置通知注解,指定要处理的对象
public void autoFill(JoinPoint joinPoint){
log.info("开始进行公共字段的赋值...");
//获取当前被拦截的方法上的数据库操作类型(UPDATE or INSERT)
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
OperationType operationType = autoFill.value();//得到数据库操作类型
//获取当前被拦截的方法参数-实体对象
Object[] args = joinPoint.getArgs();
if(args == null || args.length == 0) return;
Object entity = args[0];//这里需要再mapper中约定拦截到需要使用的对象是第一个参数
//准备赋值的数据
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();
//通过反射为对象属性赋值
if(operationType == OperationType.INSERT){
try {
//获取需要更改的公共字段的set方法
Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME,LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER,Long.class);
Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME,LocalDateTime.class);
Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER,Long.class);
//通过反射为对象属性赋值
setCreateTime.invoke(entity,now);
setCreateUser.invoke(entity,currentId);
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
} catch (Exception e) {
e.printStackTrace();
}
}else if(operationType == operationType.UPDATE){
try {
//获取需要更改的公共字段的set方法
Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME,LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
//通过反射为对象属性赋值
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
} catch (Exception e) {
e.printStackTrace();
}
}
2.阿里云OSS
2.1环境配置
(1)Maven项目引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
<!-- java9及以上版本还需引入以下依赖 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
(2) 引入AliOssUtil工具类
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
/**
* 文件上传
*
* @param bytes
* @param objectName
* @return
*/
public String upload(byte[] bytes, String objectName) {
// 创建OSSClient实例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);
log.info("文件上传到:{}", stringBuilder.toString());
return stringBuilder.toString();
}
}
(3)配置云端密匙信息
alioss:
endpoint: ${sky.alioss.endpoint}
access-key-id: ${sky.alioss.access-key-id}
access-key-secret: ${sky.alioss.access-key-secret}
bucket-name: ${sky.alioss.bucket-name}
2.2使用方法
(1)创建AliOssProperties类,提供方便的方式来管理和访问阿里云OSS的相关配置信息
@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
/**
* @ConfigurationProperties(prefix = "sky.alioss"):
* 这个注解是Spring Boot提供的,用于将配置文件中的属性绑定到JavaBean上。
* prefix = "sky.alioss"指定了配置文件中与这个类属性对应的配置项的前缀。
* 这意味着,Spring Boot会在application.properties或application.yml等配置文件中
* 查找以sky.alioss为前缀的属性,并将它们自动绑定到AliOssProperties类的相应字段上。
*/
public class AliOssProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
(2) 创建OssConfiguration配置类,用于创建AliOssUtil对象,使用AliOssProperties中定义的配置信息与阿里云OSS进行交互
@Configuration
@Slf4j
/**
* @Configuration:
* 这个注解表明OssConfiguration类是一个配置类,Spring容器会特别处理这个类中的@Bean注解。
* 配置类允许你通过@Bean注解定义bean,这些bean会被Spring容器管理,
* 并且可以在应用程序的其他部分中通过自动装配(如@Autowired)来访问。
*/
public class OssConfiguration {
@Bean
@ConditionalOnMissingBean
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
log.info("开始创建阿里云文件上传工具类:{}",aliOssProperties);
//把AliOssProperties封装的信息赋值给AliOssUtil对象
return new AliOssUtil(aliOssProperties.getEndpoint(),
aliOssProperties.getAccessKeyId(),
aliOssProperties.getAccessKeySecret(),
aliOssProperties.getBucketName());
}
}
(3)在接口中使用OSS工具类
@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {
/**
* 文件上传
*/
@Autowired
private AliOssUtil aliOssUtil;
@PostMapping("/load")
@ApiOperation("文件上传")
public Result<String> upload(MultipartFile file){
log.info("文件上传:{}",file);
try {
//原始文件名
String originalFilename = file.getOriginalFilename();
//截取原始文件的类型,即获得文件的拓展名
String extention = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectname = UUID.randomUUID().toString() + extention;
//把文件的二进制形式和存储到云端的名字传给工具类,返回在云端的访问路径
String filePath = aliOssUtil.upload(file.getBytes(), objectname);
//把文件路径返回
return Result.success(filePath);
} catch (IOException e) {
log.error("文件上传失败:{}",e);
}
return Result.error("文件上传失败");
}
}
3.Mybatis-定义SQL语句
3.1配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.DishMapper">
<!-- namespace的值为映射接口的路径 -->
</mapper>
3.2动态SQL遍历集合
<insert id="insertBatch">
insert into sky_take_out.dish_flavor (dish_id, name, value) values
<foreach collection="flavors" item="df" separator=",">
<!-- collection-要遍历的集合 item-集合中元素的命名 separator-分隔符 -->
(#{df.dishId},#{df.name},#{df.value})
</foreach>
</insert>