苍穹外卖------收获和改进(day03-04)

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>

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值