Arrays工具类
使用Arrays.sort( )对自定义类进行排序的时候,这个类需要实现(implements) Comparable<类名>,然后重写compareTo( )这个方法。
Lambda表达式
Lambda表达式,必须要有一个接口类,并且这个接口类中只有有一个抽象方法,注意:不能是抽象类,只能是接口。
(重写方法的参数列表)->{重写方法的代码
};
Lambda简化
(o1,o2)->{重写方法的代码
};
(o1,o2)-> 重写方法的代码;
Mybatis常用标签
<update id="update" parameterType="Category">
parameterType:通过mapper传递过来的参数类型。
<select id="list" resultType="Category">
resultType:MyBatis会根据SQL语句的结果集中的列名与resultType类型的属性进行自动映射,将每一行数据转换为一个resultType实例。
<insert id="insertBatch" useGeneratedKeys="true" keyProperty="id">insert into dish_flavor(dish_id, name, value) values<foreach collection="flavors" item="df" separator=",">(#{df.dishId},#{df.name},#{df.value})</foreach
</insert>
useGenerateKeys:这是一个属性设置,表示开启JDBC的getGeneratedKeys功能来获取数据库自动生成的主键值。许多数据库系统(如MySQL、SQL Server等)支持在插入数据时自动为某些列生成唯一标识符(通常是主键)。通过设置useGeneratedKeys="true",MyBatis可以将这些自动生成的主键值映射到实体对象中。
keyProperty:指定主键为谁。
@Transactionalpublic void saveWithFlavor(DishDTO dishDTO) {Dish dish = new Dish();BeanUtils.copyProperties(dishDTO,dish);//向菜品表添加数据dishMapper.insert(dish);//获取dishIdlong dishId=dish.getId();//向口味表插入n条数据List<DishFlavor> flavors=dishDTO.getFlavors();if(flavors!=null&& flavors.size()>0){flavors.forEach(dishFlavor -> {dishFlavor.setDishId(dishId);});//非空数据dishFlavorMapper.insertBatch(flavors);//保持一致,都为flavors}}
collection:通常是传递过来一个集合,collection的值和传递过来的值保持一致。
item:依次遍历collection这个集合,每一次遍历出来的对象叫做item。
separator:一次遍历完了之后和下一次遍历的结果之间的分隔符
Mybatis配置文件
mybatis:#mapper配置文件mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.sky.entity #设置别名configuration:#开启驼峰命名map-underscore-to-camel-case: true
PageHelper
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {//设置当前的页码是多少,以及当前页面有多少个数据PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());//查询结果封装在Page中Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);//获取查询到的所有的数据数量long total=page.getTotal();//拿到分页查询的数据List<Employee> records=page.getResult();//返回PageResultreturn new PageResult(total,records);
}
AOP切面操作
切面操作通常用来简化代码。
依赖:
<dependencies><!--spring核心依赖,会将spring-aop传递进来--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><!--切入点表达式依赖,目的是找到切入点方法,也就是找到要增强的方法--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency>
</dependencies>
- 在Spring配置类上打开注解,开启注解开发AOP功能—>
@EnableAspectJAutoProxy。 - 定义通知类,制作通知方法。通知类必须配置为Spring管理的bean
- 定义切入点表达式、配置切面(绑定切入点与通知关系)
//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {//设置切入点,@Pointcut注解要求配置在方法上方@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void pt(){}//设置在切入点pt()的前面运行当前操作(前置通知)@Before("pt()")public void method(){System.out.println(System.currentTimeMillis());}
}
Annotation自定义注解
public enum OperationType {//更新操作UPDATE,//插入操作INSERT
}@Target(ElementType.METHOD) //注解只能加在方法上
@Retention(RetentionPolicy.RUNTIME) //注解在运行期间起作用
public @interface AutoFill {//数据库操作类型:update insertOperationType value();
}
@Aspect
@Component
@Slf4j
public class AutoFillAspect {//切入点//锁定com.sky.mapper包下的所有类的所有方法,并且标注了AutoFill这个注解的方法就会被拦截进行填充处理@Pointcut("execution(* com.sky.mapper.*.*(..))&&@annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut(){}//通知@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint){MethodSignature signature= (MethodSignature) joinPoint.getSignature();//获取调用函数签名AutoFill autoFill=signature.getMethod().getAnnotation(AutoFill.class);//获取到注解对象OperationType operationType = autoFill.value();//获取注解上的value-->如何操作数据库。Insert or Update//获取当前被拦截的方法的参数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) {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{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();}}}
}
SpringMvc
依赖:
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.10.RELEASE</version></dependency>
配置:
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {@Autowiredprivate JwtTokenAdminInterceptor jwtTokenAdminInterceptor;@Autowiredprivate JwtTokenUserInterceptor jwtTokenUserInterceptor;/*** 注册自定义拦截器** @param registry*/protected void addInterceptors(InterceptorRegistry registry) {log.info("开始注册自定义拦截器...");registry.addInterceptor(jwtTokenAdminInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/employee/login");registry.addInterceptor(jwtTokenUserInterceptor).addPathPatterns("/user/**").addPathPatterns("/user/user/login").addPathPatterns("/user/shop/status");}/*** 通过knife4j生成接口文档* @return*/@Beanpublic Docket docket1() {ApiInfo apiInfo = new ApiInfoBuilder().title("苍穹外卖项目接口文档").version("2.0").description("苍穹外卖项目接口文档").build();Docket docket = new Docket(DocumentationType.SWAGGER_2).groupName("管理端").apiInfo(apiInfo).select().apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin")).paths(PathSelectors.any()).build();return docket;}@Beanpublic Docket docket2() {ApiInfo apiInfo = new ApiInfoBuilder().title("苍穹外卖项目接口文档").version("2.0").description("苍穹外卖项目接口文档").build();Docket docket = new Docket(DocumentationType.SWAGGER_2).groupName("用户端").apiInfo(apiInfo).select().apis(RequestHandlerSelectors.basePackage("com.sky.controller.user")).paths(PathSelectors.any()).build();return docket;}/*** 设置静态资源映射* @param registry*/protected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}/*** 扩展Spring Mvc的消息转换器,对数据进行转换处理* @param converters*///@Overrideprotected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {//创建一个消息转换器对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();//设置对象转换器,java对象转换为JSON数据converter.setObjectMapper(new JacksonObjectMapper());//将自己的消息转换器加入到容器中converters.add(0,converter);}
}
@RequestParam:用于接收url地址传参或表单传参,非json格式
@RequestBody:用于接收json数据
@PathVariable:用于接收路径参数,使用{参数名称}描述路径参数
@PostMapping("/status/{status}")@ApiOperation("启用禁用分类")public Result<String> startOrStop(@PathVariable("status") Integer status, Long id){categoryService.startOrStop(status,id);return Result.success();}

异常处理器
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {/*** 捕获业务异常* @param ex* @return*/@ExceptionHandlerpublic Result exceptionHandler(BaseException ex){log.error("异常信息:{}", ex.getMessage());return Result.error(ex.getMessage());}@ExceptionHandlerpublic Result exceptionHandler(SQLIntegrityConstraintViolationException ex){//先获取错误信息String message=ex.getMessage();if(message.contains("Duplicate entry")){String[] split=message.split(" ");String username=split[2];String msg=username+ MessageConstant.ALREADY_EXISTS;return Result.error(msg);}else{return Result.error(MessageConstant.UNKNOWN_ERROR);}}
}
SpringBoot整合Mybatis
设置数据源参数
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTCusername: rootpassword: roottype: com.alibaba.druid.pool.DruidDataSource
LocalDate转LocalDateTime
处理精度不同,LocalDate转换为LocalDateTime
LocalDate localDate=LocalDate.now();System.out.println("现在的时间为:");System.out.println(localDate);System.out.println("转换后为:");LocalDateTime localDateTime=LocalDateTime.of(localDate, LocalTime.now());LocalDateTime localDateTime1=LocalDateTime.of(localDate, LocalTime.MIN);LocalDateTime localDateTime2=LocalDateTime.of(localDate, LocalTime.MAX);System.out.println(localDateTime);
Spring Task
@Component
@Slf4j
public class OrderTask {@Autowiredprivate OrderMapper orderMapper;@Test@Scheduled(cron = "0 * * * * ? ")public void processTimeoutOrder(){//每分钟触发一次log.info("定时处理超时订单:{}", LocalDateTime.now());//查询待付款状态的,并且已经超过15分钟了,就要取消掉LocalDateTime time= LocalDateTime.now().plusMinutes(-15);List<Orders> ordersList = orderMapper.findByStatusAndOrderTime(Orders.PENDING_PAYMENT, time);if(ordersList!=null&&ordersList.size()>0){for(Orders orders:ordersList){orders.setStatus(Orders.CANCELLED);orders.setCancelReason("订单超时,自动取消");orders.setCancelTime(LocalDateTime.now());orderMapper.update(orders);}}}
}