文章目录
- 公众字段填充
- 1. 自定义注解标识需要用的方法
- 定义注解
- 定义枚举
- 2. 自定义类拦截用了上面注释的方法
- 3. 在方法上使用注解
- 获取yml自定义数据
- 生成 UUID.randomUUID().toString()
- 文件上传到本地
- 七牛云 oss https://developer.qiniu.com/kodo/1239/java#server-upload
- 本地文件上传
- post参数file文件上传
- 普通文件上传
- @Transactional 事务原子性
公众字段填充
1. 自定义注解标识需要用的方法
定义注解
package com.sky.annotation;import com.sky.enumeration.OperationType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义注解,用于标识某个方法需要进行功能字段自动填充处理*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {//数据库操作类型:UPDATE INSERTOperationType value();
}
定义枚举
package com.sky.enumeration;/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT}
2. 自定义类拦截用了上面注释的方法
package com.sky.aspect;import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.time.LocalDateTime;/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*/@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut(){}/*** 前置通知,在通知中进行公共字段的赋值*/@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint){log.info("开始进行公共字段自动填充...");//获取到当前被拦截的方法上的数据库操作类型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];//准备赋值的数据LocalDateTime now = LocalDateTime.now();Long currentId = BaseContext.getCurrentId();//根据当前不同的操作类型,为对应的属性通过反射来赋值if(operationType == OperationType.INSERT){//为4个公共字段赋值try {Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_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){//为2个公共字段赋值try {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();}}}}
3. 在方法上使用注解
package com.sky.mapper;@Mapper
public interface EmployeeMapper {/*** 插入员工数据** @param employee*/@Insert("insert into employee (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user,status) " +"values " +"(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})")@AutoFill(value = OperationType.INSERT)void insert(Employee employee);/*** 根据主键动态修改属性** @param employee*/@AutoFill(value = OperationType.UPDATE)void update(Employee employee);}
获取yml自定义数据
yx:path: D:\cangQiong\
------------------@Value("${yx.path}")private String basePath;
生成 UUID.randomUUID().toString()
文件上传到本地
//MultipartFile是文件上传的类型//file是前端参数的名字@PostMapping("/upload")@ApiOperation("文件上传")public Result<String> upload(MultipartFile file) {log.info("文件上传,参数file={}", file);//原始文件名String originalFilename = file.getOriginalFilename();//从最后一个点的位置开始截取String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//使用UUID重新生成文件名,防止文件名称重复造成文件覆盖String fileName = UUID.randomUUID().toString() + suffix;//创建一个目录对象File dir = new File(basePath);//判断当前目录是否存在if (!dir.exists()) {//目录不存在,需要创建dir.mkdirs();}try {//将临时文件转存到指定位置file.transferTo(new File(basePath + fileName));} catch (IOException e) {e.printStackTrace();}return Result.success(fileName);}
七牛云 oss https://developer.qiniu.com/kodo/1239/java#server-upload
<!--七牛云oss--><dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.15.0</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.2</version><scope>compile</scope></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version><scope>compile</scope></dependency><dependency><groupId>com.qiniu</groupId><artifactId>happy-dns-java</artifactId><version>0.1.6</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
本地文件上传
//构造一个带指定 Region 对象的配置类Configuration cfg = new Configuration(Region.huanan());// 指定分片上传版本cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传String accessKey = "1111111111111111";String secretKey = "22222222222222222";String bucket = "33333333333333";
//如果是Windows情况下,格式是 D:\\qiniu\\test.pngString localFilePath = "C:\\Users\\yxmia\\Pictures\\1.png";
//默认不指定key的情况下,以文件内容的hash值作为文件名String key = null;Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(localFilePath, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);} catch (QiniuException ex) {ex.printStackTrace();if (ex.response != null) {System.err.println(ex.response);try {String body = ex.response.toString();System.err.println(body);} catch (Exception ignored) {}}}
post参数file文件上传
//MultipartFile是文件上传的类型//file是前端参数的名字@PostMapping("/upload")@ApiOperation("文件上传")public Result<String> upload(MultipartFile file) {log.info("文件上传,参数file={}", file);//构造一个带指定 Region 对象的配置类Configuration cfg = new Configuration(Region.huanan());// 指定分片上传版本cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);//...生成上传凭证,然后准备上传String accessKey = "3-1111111111111";String secretKey = "2222222222222222222";String bucket = "3333333333333";//默认不指定key的情况下,以文件内容的hash值作为文件名String key = "123.jpg";try {ByteArrayInputStream byteInputStream = new ByteArrayInputStream(file.getBytes());Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(byteInputStream, key, upToken, null, null);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);} catch (QiniuException ex) {ex.printStackTrace();if (ex.response != null) {System.err.println(ex.response);try {String body = ex.response.toString();System.err.println(body);} catch (Exception ignored) {}}}} catch (IOException ex) {//ignore}
普通文件上传
//原始文件名String originalFilename = file.getOriginalFilename();//从最后一个点的位置开始截取String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//使用UUID重新生成文件名,防止文件名称重复造成文件覆盖String fileName = UUID.randomUUID().toString() + suffix;//创建一个目录对象File dir = new File(basePath);//判断当前目录是否存在if (!dir.exists()) {//目录不存在,需要创建dir.mkdirs();}String endFilePath=basePath + fileName;//https://img-blog.csdnimg.cn/direct/9096f6ea1ffc4255b09d0e2471210db9.pnglog.info("最终文件路径={}",endFilePath);try {//将临时文件转存到指定位置file.transferTo(new File(endFilePath));} catch (IOException e) {e.printStackTrace();}endFilePath="https://profile-avatar.csdnimg.cn/198398dc218d4058afe2a25a16d6b2ae_qq_44627608.jpg";return Result.success(endFilePath);
@Transactional 事务原子性
- 使用前需要application主类加上@EnableTransactionManagement //开启注解方式的事务管理
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。