Java_五个月学习_第三阶段

第三阶段

day51、GIT

1.1操作步骤

  • 下载git软件
  • idea端
    • 配置idea
      • plugins配置下:安装好gir软件
      • git设置:路径配置
      • open->project form version control
  • 注册git账号
    • 创建组织
    • 创建仓库
  • 克隆复制项目
  • filter
    本地

1、git的具体详细

  • 1.1 文件名是颜色识别
    • 红色:不上传的文案
    • 绿色:文件
    • 蓝色:未上传的的文件
  • 1.2 pull备注
    • 1.1.1 第一个1大版本 第二数:功能的添加 第3个数:当前版本修改了多少个漏洞

day52、Maven

1.打包方式

 - 1.1 pom:父项目- 1.2 war:发布的子项目- 1.3 jar:不发布的工具项目

2.依赖关系

 war 包依赖 jar 包,war 包不依赖 war 包在 war 包的 pom.xml 的 dependencies 中<!--依赖 shop-pojo --><dependency><groupId>com.qf.nice</groupId><artifactId>shop-pojo</artifactId>//jar包项目名<version>1.0.0-SNAPSHOT</version></dependency>

3.封装坐标版本号

3.1 在 properties 标签中添加自定义标签:<junit-version>4.11</junit-version><serlvet-version>4.0.1</serlvet-version><mysql-version>5.1.6</mysql-version>3.2 在对应的坐标中引用版本号<version>${junit-version}</version>

4.创建 jar 包

4.1 File -- Project Structure4.2 Artifacts -- "+" -- JAR -- From modules with ....4.3 勾选 Include in project build4.4 回到主页面 Build -- Build Artifacts

5.上传 jar 包本地仓库

mvn install:install-file -Dfile=jar包位置 -DgroupId=组织名 -DartifactId=项目名 -Dversion=版本号 -Dpackaging=jarmvn install:install-file -Dfile=D:\Software\java-jar\DBManger.jar -DgroupId=com.qf.hao.utils -DartifactId=DBManager -Dversion=1.0.0 -Dpackaging=jar

day53、day53 Spring-Ioc

关于Ioc介绍

1.配置文件方式

- 1.1 导入 Spring 容器的坐标- 1.2 创建 spring-context.xml IOC的配置文件- 1.3 加载配置文件创建 Spring 容器ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");- 1.4 从容器中获取指定的对象ClassDao classDao = (ClassDao) ctx.getBean("classDao");

2.注解方式

3、部分代码

//1、关于配置文件<!-- 开启扫描,扫描有注解的包,让注解生效 --><context:component-scan base-package="com.qf.ran.controller"/><context:component-scan base-package="com.qf.ran.service.impl"/><context:component-scan base-package="com.qf.ran.dao.impl"/>//2、关于部分注解
/*** @author Ran* @since JDK 1.8*/
/*依赖*/
//@Component
@Controller
public class StudentController {/*对象注入*/@AutowiredStudentService studentService;public void setStudentService(StudentService studentService) {this.studentService = studentService;}public void method(){System.out.println("Controller:"+studentService.method1());}
}
1.添加 xml 配置文件开启扫描支持注解,base-package 值为注解所在的包<context:component-scan base-package="com.qf.ran.controller"/>2.添加依赖注解@Component      --  把对象创建的控制权交给 Spring 容器(支持所有的类)@Controller     --  支持控制成的注解@Service        --  支持业务逻辑层的注解@Repository     --  支持持久层的注解3.添加注入注解@Autowired      --  默认使用类型查找对象默认选项为 true ,设置为 false 代表注入的对象可以为 null在多线程中是不安全的如果出现菱形依赖问题可以通过 Autowired 修饰有参构造方法来解决依赖问题先创建对象再注入属性对象@Resources      --  默认根据 name 在容器中查找对象,没有 name 则根据类型查找对象不允许对象为 null,线程安全

day54、spring-aop

关于AOP介绍

1、代理

1.业务划分:主业务:转账、充值系统级业务:事务控制、日志控制2.静态代理:优势:把主业务和系统级业务划分开劣势:每个业务对象都需要一个代理类,会造成类的冗余3.动态代理:优势:每一个业务对象都可以使用同一个代理,减少类的冗余劣势:产生对象的冗余,占用内存空间,修改了源代码

2、SpringAOP

4.SpringAOP:面向切面编程  --  基于XML配置4.1 引入jar包//注意这里没有显示版本号,是要导入有版本号才行<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId></dependency>4.2 添加增强类 TransactionAdvice ,增强类中定义增强方法4.3 添加XML配置文件 Spring-AOP.xml前置增强后置增强环绕增强异常处理增强方法返回增强5.SpringAOP:面向切面编程  --  基于注解5.1 引入 jar 包5.2 创建切面类,并使用注解 @Component @Aspect5.3 定义切点的方法,并添加注解@Pointcut("execution(* com.qf.ran.service.impl.*ServiceImpl.pay(..))")5.4 编写增强方法并添加对应的注解5.5 在Spring配置文件中添加支持 AOP 注解的配置<aop:aspectj-autoproxy/>

2、遇到3个bug

1、plign文件找不到解决办法
2、导包包已经下载好但是还是报错:idea的seting中勾选dubug …Maven
3、初始化异常:将juit测试包升级

3、部分代码

//1、配置文件配置<!-- 开启扫描,支持IOC注解 --><context:component-scan base-package="com.qf.ran"/><!--开启AOP注解支持(支持JDK动态代理)--><aop:aspectj-autoproxy/><!--开启AOP注解支持(proxy-target-class 设置为 true 代表使用cglib代理)--><!--<aop:aspectj-autoproxy proxy-target-class="true"/>-->
//2、关于代理类
*/
@Component
/*代表切面类*/
@Aspect
public class TransactionAdvice {//定义切点@Pointcut("execution(* com.qf.ran.service.impl.*ServiceImpl.pay(..))")//那些类需要增强写入public void transactionPC(){}//前置增强@Before("TransactionAdvice.transactionPC()")public void before(){System.out.println("前置增强(注解)");}//后置增强@After("TransactionAdvice.transactionPC()")public void after(){System.out.println("后置增强(注解)");}//后置增强(异常出现后增强)@AfterThrowing("TransactionAdvice.transactionPC()")public void afterThrowing(){System.out.println("异常增强(注解)");}//后置增强(方法返回结果后增强)@AfterReturning("TransactionAdvice.transactionPC()")public void afterReturning(){System.out.println("返回结果后");}//环绕增强@Around("TransactionAdvice.transactionPC()")public Object around(ProceedingJoinPoint point) throws Throwable {System.out.println("环绕前(注解)");Object proceed = point.proceed();System.out.println("环绕后(注解)");return proceed;}}
//3、关于测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:Spring-context.xml"})//加载配置文件
public class UserControllerTest {@Autowiredprivate UserController userController;@Testpublic void testTransferAccounts(){userController.transferAccounts();}
}

Day55、SpringMvc

spring的介绍

1、SpringMvc的配置

1.1 导入 SpringMVC 的jar包<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${springmvc-version}</version></dependency>1.2 添加 Spring 的配置文件1.2.1 开启 Spring 扫描1.2.2 开启 SpringMVC 的注解支持    --  注意约束1.3 配置 web.xml 文件1.3.1 配置编码过滤器,初始化参数指定编码格式为UTF-81.3.2 配置 DispatcherServlet 分发器,初始化参数加载 Spring 配置文件1.3.3 配置 html 请求的默认访问1.4 创建 Controller 层的类,添加注解@Controller @RequestMapping("/请求路径")1.5 添加对应的方法并使用注解@RequestMapping("/请求路径")

2、SpringMVC的请求和响应

2.1 添加 jar (fastjson、jackson)2.2 Spring 配置文件添加消息转换器2.3 前端发送ajax请求2.4 添加 RespBean 类2.5 Controller 层类方法添加注解 @ResponseBody (告诉Spring容器,返回的对象需要经过消息转换器转换成json 格式数据)

3、关于代码

//xml文件
<!--开启 Spring 的扫描--><context:component-scan base-package="com.qf.ran"/><!--开启 SpringMVC 的注解支持--><mvc:annotation-driven/><!--消息转换器配置 FastJson--><!--把响应对象转换成json格式对象--><mvc:annotation-driven><mvc:message-converters register-defaults="false"><bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=utf-8</value><value>application/json;charset=utf-8</value></list></property></bean></mvc:message-converters></mvc:annotation-driven>//2、前端控制器
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--1.配置编码过滤器--><filter><filter-name>encoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!--初始化--><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>encoding</filter-name><url-pattern>/*dispatcherServletorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:spring-mvc.xmldispatcherServlet/default*.htmldefault*.js//3、导jar包org.springframeworkspring-webmvc${springmvc-version}com.alibabafastjson1.2.73
//部分注释
/*** @author Ran* @since JDK 1.8*/
@Controller
/*请求的映射路径*/
@RequestMapping("/User")
public class UserController {@Autowiredprivate UserService userService;/*    @RequestMapping("/login")*//*响应对象为json格式数据*//*@ResponseBodypublic RespBean login(String username,String password){System.out.println("username:"+username);System.out.println("password:"+password);RespBean respBean = userService.login(username, password);return respBean;}*/@RequestMapping("/login")/*响应对象为json格式数据*/@ResponseBodypublic RespBean login(User user){System.out.println("user的username:"+user.getUsername());System.out.println("user的password:"+user.getPassword());RespBean respBean = userService.login(user.getUsername(), user.getPassword());return respBean;}@RequestMapping("/register")public void register(){System.out.println("注册方法");}
}

day56、Swagger、SpringMVC 异常处理、SpringMVC 拦截器

注解解释

DTO等详解

:@RestController注解相当于@ResponseBody + @Controller合在一起的作用@ResponseBody的作用其实是将java对象转为json格式的数据。@RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置*      PO:Persistent Object        持久对象            --  与数据库的字段一致对象*      BO:Business Object          业务对象            --  把业务逻辑需要的属性封装成一个对象*      VO:Value/View Object        值对象/视图对象     --  抽象出的业务对象,主要对应页面显示的对象*      DTO:Data Transfer Object    数据传输对象        --  在进行跨域或者远程传输时使用的对象

Responsebody

1.SpringMVC 注解

SpringMvc生命周期

/*
.1 RequestMapping1.1.1 value     --  请求映射路径1.1.2 method    --  指定提交方式1.1.3 params    --  约束请求提交的参数1.2 指定提交方式的映射注解GetMapping、PostMapping...1.3 RestController = Controller + ResponseBody把控制层交由 Spring 创建对象并把当前对象中所有方法返回值指定转换为 json 格式数据
*///在类中添加注解,所有的方法都以json格式的对象方法@GetMapping("/login")public RespBean login(User user){System.out.println("user的username:"+user.getUsername());System.out.println("user的password:"+user.getPassword());RespBean respBean = userService.login(user.getUsername(), user.getPassword());return respBean;}//提交方式只能是get请求@GetMapping("/login")@ResponseBodypublic RespBean login(User user){System.out.println("user的username:"+user.getUsername());System.out.println("user的password:"+user.getPassword());RespBean respBean = userService.login(user.getUsername(), user.getPassword());return respBean;}*/把控制层交由 Spring 创建对象并把当前对象中所有方法返回值指定转换为 json 格式数据// 提交方式: GET:获取信息        POST:更新操作        PUT:新增操作         DELETE:删除操作//代表提交方式只能是GET或者POST请求@RequestMapping(value = "/login",method= {RequestMethod.GET,RequestMethod.POST})@ResponseBodypublic RespBean login(User user){System.out.println("user的username:"+user.getUsername());System.out.println("user的password:"+user.getPassword());RespBean respBean = userService.login(user.getUsername(), user.getPassword());return respBean;}<!--定义对象json装换器--><mvc:annotation-driven><mvc:message-converters><ref bean="stringHttpMessageConverter"/><ref bean="mappingJackson2HttpMessageConverter"/></mvc:message-converters></mvc:annotation-driven><bean id="stringHttpMessageConverter"class="org.springframework.http.converter.StringHttpMessageConverter"/><!--解决IE浏览器json文件下载和json数据中文乱码的问题--><bean id="mappingJackson2HttpMessageConverter"class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json;charset=UTF-8</value></list></property></bean>

2.Swagger – 接口文档

  • 2.1 添加 jar 包
 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger-version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.7.0</version></dependency>
  • 2.2 添加配置文件类 SwaggerConfiguration
/*** @author Ran* @since JDK 1.8*/
/*代表当前类为配置文件类*/
@Configuration
@EnableSwagger2
/*扫描包 支持Swagger注解*/
@ComponentScan("com.qf.ran")
public class SwaggerConfiguration {/*需要创建的对象*/@Beanpublic Docket createAPI() {return new Docket(DocumentationType.SWAGGER_2).forCodeGeneration(true).select().apis(RequestHandlerSelectors.any())//过滤生成链接.paths(PathSelectors.any()).build().apiInfo(apiInfo());}private ApiInfo apiInfo() {Contact contact = new Contact("Ran", "http://baidu.com", "j_daran@qq.com");ApiInfo apiInfo = new ApiInfoBuilder().license("Apache License Version 2.0").title("Swagger 集成测试").description("Swagger API Teste").contact(contact).version("1.0").build();return apiInfo;}
}

2.3 web.xml 添加默认访问 *.css *.js *.html

<!--3.默认访问--><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.html</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.js</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.css</url-pattern></servlet-mapping>
  • 2.4 Spring 的配置文件添加 swagger-ui 的配置
 <mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources"/><mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars"/>
  • 2.5 对应的类和方法添加 swagger 注解
 @Api(tags="用户模块")                   --  模块注解@ApiOperation("登录功能")               --  方法注解@ApiModel                               --  实体类注解@ApiModelProperty(value = "状态值")     --  实体类属性注解
@Api(tags="用户模块")
@RestController
@RequestMapping("/User")
public class UserController {@Autowiredprivate UserService userService;@ApiOperation("登录功能")@GetMapping(value = "/login")public RespBean login(User user){System.out.println("user的username:"+user.getUsername());System.out.println("user的password:"+user.getPassword());RespBean respBean = userService.login(user.getUsername(), user.getPassword());return respBean;}@ApiOperation("注册功能")@RequestMapping("/register")public void register(){System.out.println("注册方法");}
}

3.SpringMVC 异常处理

  • 3.1 创建全局异常处理对象 HandlerException 添加注解@ControllerAdvice
  • 3.2 添加异常处理方法,参数为异常类型
    添加注解@ExceptionHandler 标记为异常处理方法
    value 代表只针对某个异常进行处理
@ControllerAdvice
@ResponseBody
public class HandlerException {//异常处理,value = AccountException.class 代表只处理 AccountException 异常@ExceptionHandler(value = AccountException.class)public RespBean handlerException(AccountException e){//e.getMessage() 获取异常信息return RespBean.respError(e.getMessage());}/*处理所有的异常@ExceptionHandlerpublic RespBean handlerException(Exception e){}*/
}

4.SpringMVC 拦截器

  • 4.1 创建拦截器类 LoginInterceptor 实现 HandlerInterceptor
  • 4.2 重写 preHandle() true 代表放行 false 代表拦截
/*** @author Ran* @since JDK 1.8**      登录拦截器*/
public class LoginInterceptor implements HandlerInterceptor {//拦截方法      --  true为放行,false为拦截public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {Integer id = (Integer)request.getSession().getAttribute("id");if(id == null){throw new LoginException("用户未登录");}return true;}
}
  • 4.3 在 Spring 配置文件添加拦截器栈,添加登录拦截器,指定需要拦截的请求和不需要拦截的请求以及对应的拦截器类
<!--拦截器栈配置--><mvc:interceptors><!--配置登录拦截器--><mvc:interceptor><!--需要拦截的请求--><!--/*  代表只能拦截 /SpringMVC-interceptor/User/** 代表能拦截   /SpringMVC-interceptor/User/login-->

5.SpringMVC 文件上传

  • 5.1 加载 jar 包
 <!--文件上传 start--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency><!--文件上传 end-->
  • 5.2 在 Spring 配置文件添加文件上传,指定文件上传的大小和编码格式
 <!--文件上传配置--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--文件上传大小限制--><property name="maxUploadSize" value="104857600"/><!--文件上传的编码--><property name="defaultEncoding" value="UTF-8"/></bean>
  • 5.3 添加对应的业务接口方法,方法参数添加 MultipartFile flie
    file.getOriginalFilename() – 获取文件名
    file.transferTo() – 存储文件
*** @author Ran* @since JDK 1.8**      文件上传模块*/
@Api(tags = "文件上传模块")
@RestController
@RequestMapping("/file")
public class FileUploadController {@ApiOperation("文件上传")@PostMapping(value = "/upload",consumes = "multipart/*",headers = "content-type=multipart/form-data")public RespBean upload(@ApiParam(value = "文件") MultipartFile file, HttpServletRequest request, HttpServletResponse response){//1\获取 img 路径并创建目录String realPath = request.getServletContext().getRealPath("/asserts/img");//解决重名//获取文件名String fileName = file.getOriginalFilename();fileName = UUID.randomUUID().toString() +"_"+fileName;//存储文件到服务器try {file.transferTo(new File(realPath,fileName));} catch (IOException e) {e.printStackTrace();}return RespBean.respSuccess("文件上传成功");}
}

day57、MyBaits

报错

lamba表达式错误

打包遇到错误

1 Spring整合MyBatis

  • 1.1 加入 jar 包 – 6个jar包
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--Spring start--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><!--Spring end--><!--druid start --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.23</version></dependency><!--druid end --><!-- mysql start--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql-version}</version></dependency><!-- mysql end--><!--mybatis start--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.5</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><!--mybatis end--><!--lombok start--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok-version}</version></dependency><!--lombok end--><!--测试类加载配置文件 start--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version><scope>test</scope></dependency><!--测试类加载配置文件 end-->
  • 2.添加配置文件
    • jdbc.properties 数据库连接驱动文件
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
# JDBC Pool
jdbc.pool.init=1
jdbc.pool.minIdle=3
jdbc.pool.maxActive=20
# JDBC Test
jdbc.testSql=SELECT 'x' FROM DUAL
  • MyBatis-config.xml MyBatis的配置文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 全局参数 --><settings><!-- 打印 SQL 语句 --><setting name="logImpl" value="STDOUT_LOGGING" /><!-- 使全局的映射器启用或禁用缓存。 --><setting name="cacheEnabled" value="false"/><!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 --><setting name="lazyLoadingEnabled" value="true"/><!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 --><setting name="aggressiveLazyLoading" value="true"/><!-- 是否允许单条 SQL 返回多个数据集 (取决于驱动的兼容性) default:true --><setting name="multipleResultSetsEnabled" value="true"/><!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true --><setting name="useColumnLabel" value="true"/><!-- 允许 JDBC 生成主键。需要驱动器支持。如果设为了 true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false  --><setting name="useGeneratedKeys" value="false"/><!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不映射 PARTIAL:部分 FULL:全部  --><setting name="autoMappingBehavior" value="PARTIAL"/><!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) --><setting name="defaultExecutorType" value="SIMPLE"/><!-- 使用驼峰命名法转换字段。 --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session --><setting name="localCacheScope" value="SESSION"/><!-- 设置 JDBC 类型为空时,某些驱动程序 要指定值, default:OTHER,插入空值时不需要指定类型 --><setting name="jdbcTypeForNull" value="NULL"/></settings>
</configuration>
  • Spring-context.xml      Spring配置文件
    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--开启 Spring 扫描--><context:component-scan base-package="com.qf.ran"/>
</beans>
  • Spring-Mybatis.xml Spring整合Mybatis的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--加载jdbc连接--><context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties"/><!-- 扫描 Mapper --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.qf.ran.dao"/></bean><!-- 配置 SqlSession --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--连接数据源--><property name="dataSource" ref="dataSource"/><!-- 用于配置对应实体类所在的包,多个 package 之间可以用 ',' 号分割 --><!--<property name="typeAliasesPackage" value="cn.qf.spring.mybatis.entity"/>--><!-- 用于配置对象关系映射配置文件所在目录 --><property name="mapperLocations" value="classpath:/mapper/**/*.xml"/><property name="configLocation" value="classpath:/MyBatis-config.xml"></property></bean><!--数据源配置,使用 druid 数据库连接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"init-method="init" destroy-method="close"><!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass --><property name="driverClassName" value="${jdbc.driverClass}"/><!-- 基本属性 url、user、password --><property name="url" value="${jdbc.connectionURL}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><!-- 配置初始化大小、最小、最大 --><property name="initialSize" value="${jdbc.pool.init}"/><property name="minIdle" value="${jdbc.pool.minIdle}"/><property name="maxActive" value="${jdbc.pool.maxActive}"/><!-- 配置获取连接等待超时的时间 --><property name="maxWait" value="60000"/><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="60000"/><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000"/><property name="validationQuery" value="${jdbc.testSql}"/><property name="testWhileIdle" value="true"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><!-- 配置监控统计拦截的filters --><property name="filters" value="stat"/></bean>
</beans>      
  • 3.druid监控中心 web.xml 进行配置监控 SQL 语句的执行效率以及执行次数
 <servlet><servlet-name>DruidStatView</servlet-name><servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class></servlet><servlet-mapping><servlet-name>DruidStatView</servlet-name><url-pattern>/druid/*

2. 动态SQL

<sql id="">   字段名的抽取,使用<include refid=""><if>          判断赋值给字段的参数是否为 null ,不为 null 则进行填充<where>       代替 where 关键词,自动省略 where 后面的 or 或者 and<foreach>     遍历<set>         代替 set 关键词,自动省略","<trim>        自定义标签
<?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.qf.ran.dao.UserMapper"><!--id 属性对应方法名--><!--<insert id="addUser">insert into user(username,password) values(#{username},#{password});</insert>--><!--主键返回sql 语句执行完后返回生成主键,对象的 id 属性接收 id 值--><insert id="addUser" useGeneratedKeys="true" keyProperty="id">insert into user(username,password) values(#{username},#{password});</insert><!--测试 @Param 修饰对象--><insert id="method">insert into user(username,password) values(#{user.username},#{user.password});</insert><delete id="deleteUserById">delete from user where id = #{id};</delete><update id="updateUserById">updateuser<set><if test="username != null and username != ''">username = #{username},</if><if test="password != null and password != ''">password = #{password},</if><if test="sex != null and sex != ''">sex = #{sex}</if></set>whereid= #{id};</update><!--字段抽取封装--><sql id="user_column">id,username,password,sex</sql><!--trim            自定义标签prefix          属性值为添加的前缀prefixOverrides 每个 if 语句允许添加指定的关键字,根据需求删除关键字--><select id="selectUser" resultType="User">select<include refid="user_column"/>fromuser<trim prefix="where" prefixOverrides="and|or"><if test="id != null and id != ''">and id = #{id}</if><if test="username != null and username != ''">and username = #{username}</if><if test="sex != null and sex != ''">or sex = #{sex}</if></trim></select><!--根据对象的属性进行查询--><!-- <include refid="user_column"/> 导入对应的字段数据  --><!--使用 where 标签会自动删除不需要的 and 或者 or--><!--<select id="selectUser" resultType="User">select<include refid="user_column"/>fromuser<where><if test="id != null and id != ''">and id = #{id}</if><if test="username != null and username != ''">and username = #{username}</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select>--><!-- resultType 返回值类型 --><!-- <select id="selectUserById" resultType="com.qf.ran.entity.User">select id,username,password from user where id = #{id};</select>--><select id="getList" resultType="User">select<include refid="user_column"/>fromuser;</select><!-- 根据 id 集合查询多个对象信息--><!-- collection 对应方法中的集合参数 --><select id="selectUserListByIds" resultType="User">select<include refid="user_column"/>fromuserwhereidin<foreach collection="list" open="(" separator="," close=")" item="id">#{id}</foreach></select>
</mapper>

3、其他

  • 更改配置文件需要重新启动项目
  • 下载lombok包需要在File>setting》plugins>搜索lombok插件下载才能正常使用
  • spring --作用于三层 springmvc作用于controller层
  • 与数据库打交道一般用包装类,不用基本数据类型

4、关于学习今日总结

  • 注解
在这里插入代码片

Day58、MyBatis-关联映射

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.qf.ran.dao.UserMapper"><!--id 属性对应方法名--><!--<insert id="addUser">insert into user(username,password) values(#{username},#{password});</insert>--><!--主键返回sql 语句执行完后返回生成主键,对象的 id 属性接收 id 值--><insert id="addUser" useGeneratedKeys="true" keyProperty="id">insert into user(username,password) values(#{username},#{password});</insert><!--测试 @Param 修饰对象--><insert id="method">insert into user(username,password) values(#{user.username},#{user.password});</insert><delete id="deleteUserById">delete from user where id = #{id};</delete><update id="updateUserById">updateuser<set><if test="username != null and username != ''">username = #{username},</if><if test="password != null and password != ''">password = #{password},</if><if test="sex != null and sex != ''">sex = #{sex}</if></set>whereid= #{id};</update><!--字段抽取封装--><sql id="user_column">id,username,password,sex</sql><!--trim            自定义标签prefix          属性值为添加的前缀prefixOverrides 每个 if 语句允许添加指定的关键字,根据需求删除关键字--><select id="selectUser" resultType="User">select<include refid="user_column"/>fromuser<trim prefix="where" prefixOverrides="and|or"><if test="id != null and id != ''">and id = #{id}</if><if test="username != null and username != ''">and username = #{username}</if><if test="sex != null and sex != ''">or sex = #{sex}</if></trim></select><!--根据对象的属性进行查询--><!-- <include refid="user_column"/> 导入对应的字段数据  --><!--使用 where 标签会自动删除不需要的 and 或者 or--><!--<select id="selectUser" resultType="User">select<include refid="user_column"/>fromuser<where><if test="id != null and id != ''">and id = #{id}</if><if test="username != null and username != ''">and username = #{username}</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select>--><!-- resultType 返回值类型 --><!-- <select id="selectUserById" resultType="com.qf.ran.entity.User">select id,username,password from user where id = #{id};</select>--><select id="getList" resultType="User">select<include refid="user_column"/>fromuser;</select><!-- 根据 id 集合查询多个对象信息--><!-- collection 对应方法中的集合参数 --><select id="selectUserListByIds" resultType="User">select<include refid="user_column"/>fromuserwhereidin<foreach collection="list" open="(" separator="," close=")" item="id">#{id}</foreach></select>
</mapper>

2、缓存:

  • 一级缓存(SqlSession)
    • Spring-Mybatis.xml 添加配置
<!--事务处理器容器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><constructor-arg ref="dataSource"/></bean><!--开启事务注解支持--><tx:annotation-driven transaction-manager="transactionManager"/>
  • 指定方法添加注解@Transactional(readOnly = true)
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Override/*开启一级缓存*/
//    /*@Transactional(readOnly = true)*/public User selectUser(User user){userMapper.selectUser(user);userMapper.selectUser(user);userMapper.selectUser(user);userMapper.selectUser(user);userMapper.selectUser(user);return null;}
}
  • 2、二级缓存(mapper)
    • Mybatis-config.xml 配置中cacheEnabled 设置为true
<!-- 使全局的映射器启用或禁用二级缓存。 --><setting name="cacheEnabled" value="true"/>
  • 在指定 XXXMapper.xml 的 mapper 标签里添加
<?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.qf.ran.dao.UserMapper"><!-- 开启当前namespace 的二级缓存--><cache/>
  • 实体类进行序想·列化、
    • public class User implements Serializable

3、今日总结

  • 关于注解
@Transactional(readOnly = true)   开启以及缓存
  • 关于maven依赖包

Day59、quartz、Log框架

报错解决

1、idea控制台中文乱码

1.Logback – 日志框架 记录程序运行状态以及错误信息

  • 依赖的包
 <spring.version>5.2.9.RELEASE</spring.version>
<!-- Logback依赖,还会传递 slf4j 和 logback-core --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency></dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency>
  • 方法:debug(),info(),warn(),error()
 //日志对象private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);public User selectUserByUserId(Long id) {//开发阶段logger.debug("debug:"+id);//追踪正常状态信息logger.info("info:"+id);try{if(id == 11L){//当系统出现不合理的情况但是不影响程序的运行logger.warn("warn:用户id不存在,查询失败");}if(id == 100L){throw new RuntimeException("异常说明:连接数据库失败");}}catch (RuntimeException e){//系统级错误,导致程序无法正常运行logger.error("error:"+e.getMessage());}return null;}
  • 配置文件:logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false-->
<configuration scan="true" scanPeriod="60 seconds" debug="true"><!-- 定义变量,可通过 ${log.path}和${CONSOLE_LOG_PATTERN} 得到变量值 --><!-- 指定日记保存目录 --><property name="log.path" value="D:/log"/><!-- 日志输出格式规定 --><property name="CONSOLE_LOG_PATTERN"value="%d{yyyy-MM-dd HH:mm:ss.SSS} |-[%-5p] in %logger.%M[line-%L] -%m%n"/><!-- 输出到控制台 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!-- Threshold=即最低日志级别,此appender输出大于等于对应级别的日志(当然还要满足root中定义的最低级别)--><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter><encoder><!-- 日志格式(引用变量) --><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder></appender><!-- 输出到磁盘的日志文件中 --><appender name="file" class="ch.qos.logback.core.FileAppender"><file>${log.path}/logback1.log</file><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern></encoder></appender><!-- 滚动追加到文件中 --><appender name="file2" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/logback2.log</file><!--日志文件输出格式--><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>UTF-8</charset> <!-- 设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录文件超过最大尺寸后,会新建文件,然后新的日志文件中继续写入如果日期变更,也会新建文件,然后在新的日志文件中写入当天日志--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 新建文件后,原日志改名为如下  %i=文件序号,从0开始 --><fileNamePattern>${log.path}/logback-%d{yyyy-MM-dd}.%i.log</fileNamePattern><!-- 每个日志文件的最大体量 --><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>5KB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><append>true</append><!-- 日志文件保留天数,1=则只保留昨天的归档日志文件 ,不设置则保留所有日志--><maxHistory>2</maxHistory></rollingPolicy></appender><!--level为日志输出级别:trace   -  debug  -   info  -  warn  -  error--><root level="debug"><appender-ref ref="CONSOLE"/><appender-ref ref="file2"/></root><!--输出到日志文件--><root level="info"><appender-ref ref="file"/></root></configuration>
  • 级别:trace debug info warn error

2.Quartz – 定时任务框架

  • 1、Java代码版本

//1.创建调度器Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();//2.设定任务规则JobDetail jobDetail = JobBuilder.newJob(ClockInJob.class)//指定任务的唯一标识.withIdentity("clockIn", "clockIn").build();//3.设定时间规则CronTrigger trigger = TriggerBuilder.newTrigger().withSchedule(//秒 分 时 日 月 星期数//3 * * * * ?       每分钟的第3秒//0/3 * * * * ?     一开始执行任务,每隔3秒再一次执行//"3/3 * * * * ?"   3秒后每隔3秒执行一次//"0-30 * * * * ?"  0-30秒每一秒执行一次//0 0 20 ? * 6      每周周五晚上8点发周报//0 0 1 1 * ?       每月第一天凌晨1点CronScheduleBuilder.cronSchedule("3/3 * * * * ?")).build();//4.通过调度器绑定任务和时间scheduler.scheduleJob(jobDetail,trigger);//5.开启调度器scheduler.start();Thread.sleep(10000);//删除定时任务scheduler.deleteJob(new JobKey("clockIn", "clockIn"));
  • 2、配置文件版本
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.qf.ran"/><!--1.定义任务的 bean  ,指定任务规则--><bean name="job1" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"><!-- 指定 job 的名称--><property name="name" value="clockIn"/><!-- 指定 job 的组织 --><property name="group" value="clockIn"/><!--指定具体的 job 类--><property name="jobClass" value="com.qf.ran.job.ClockInJob"/></bean><!--2.定义触发器的bean,制定时间规则--><bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><property name="name"  value="trigger1"/><property name="group"  value="trigger1"/><!-- 绑定调度任务 --><property name="jobDetail" ref="job1"/><!--指定时间规则,每隔3秒执行一次--><property name="cronExpression" value="*/3 * * * * ?"/></bean><!--3.创建调度器,将触发器注册到调度器里--><bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><!--触发器栈--><property name="triggers"><list><ref bean="cronTrigger"/></list></property><!-- 添加 quartz 配置,如下两种方式均可 --><!--<property name="configLocation" value="classpath:quartz.properties"></property>--><property name="quartzProperties"><value># 指定调度器名称,实际类型为:QuartzSchedulerorg.quartz.scheduler.instanceName = MyScheduler# 指定连接池org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool# 连接池线程数量org.quartz.threadPool.threadCount = 11# 优先级org.quartz.threadPool.threadPriority = 5# 不持久化joborg.quartz.jobStore.class = org.quartz.simpl.RAMJobStore</value></property></bean></beans>

Day60、项目周

1、报错总结

  • 1\ java.lang.IllegalStateException: Failed to load ApplicationContext
//集成 swagger2 需要添加注解
@WebAppConfiguration
  • 2、swafa找不到属性,属性显示不全
    参考

  • 3、jQuery on()方法绑定动态元素
    要有一个父类

day61、spring-boot

1、spring-boot概要


1. Spring Boot
2. Shiro
3. 运维篇(了解)  Linux  Docker## 微服务#### 微服务组件Spring CloudSpring Cloud AlibabaSpring Cloud Netflix#### 第三方常用框架1. 分布式事务
2. 分布式锁
3. ES
4. Sharding-JDBC
5. Redis
6. 消息中间件
7. Spring Security(选学)
8. Vue(前端)

2、创建Spring Boot项目

## Spring  Boot笔记### 基础1. yml### 数据层1. Mybatis2. Mybatis  Plus  ORM 框架的能力3. JPA (Hibernate)4. Redis(操作map)### web1. Restful2. 参数校验3. 全局异常处理4. 文件上传## 为什么要学习Spirng  Boot1. 导包 
2. 内置web容器(tomcat)
3. 整合配置文件
4. 内置监控## 什么是Spring Boot> spring boot 简化了 spring 的开发难度,配置信息,提供了各种启动器(starter),是新一代的web开发标准, 并且spring cloud的基础## 创建Spring Boot项目### 概要1. Spring Boot 初始化器2. 手动创建(重点掌握)### Maven多继承与多模块如果想pom.xml文件被继承(父pom文件)继承1. `<packaging>pom</packaging>````xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.10</version><relativePath/></parent><packaging>pom</packaging><groupId>com.smart</groupId><artifactId>spring-boot-example</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-example</name></project>

子pom文件

  • parent标签

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0modelVersion><parent><groupId>com.smartgroupId><artifactId>spring-boot-exampleartifactId><version>0.0.1-SNAPSHOTversion>指向pom包,一定要改过来,不然影响后续的打包<relativePath>../pom.xmlrelativePath>parent>
project>

补充知识点

常见的继承标签(可以继承的都可以删除)

  1. groupId

  2. version

  3. properties(包括子标签)

  4. 依赖继承

    1. 可选依赖 dependencyManagement
    2. 直接依赖 dependencies

    build标签是不能够被继承的

    spring-boot-project项目说明标签,可要可不要
    

多模块

  1. 在父pom文件中

    <project><modules><module>spring-boot-basemodule>modules>
    project>
    

    备注:

    1. 不要跨级添加模块

    多模块的好处

    1. ​ 只需要打包一个工程既可打包所有
    2. 后期可配合开发环境,统一版本号

    配置文件配置流程

    1. 把相同配置删除了,是否是继承项目

3、自定义属性

  1. @Value()
  2. @ConfigurationProperties

单值读取

语法
  1. ${属性名}
  2. #{属性名或者EL表达式}
@Data
public class User {@Value("${user.username}")private String username;@Value("${user.password}")private String password;
}
配置文件
user:username: adminpassword: password
Java config注册
@Configuration
public class UserConfig {@Beanpublic User user() {User user = new User();return user;}
}
测试代码
@RestController
@RequestMapping("/user")
public class UserController {@ResourceUser user;@GetMapping("/test")public String test() {return user.getUsername();}}    

批量读取

语法格式
@ConfigurationProperties(prefix = "" ,value="")
说明
属性说明
prefix等价于value配置文件属性前缀
依赖

<dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-configuration-processorartifactId><optional>trueoptional>
dependency>
@Data
@Component
@ConfigurationProperties(prefix = "user.properties")
public class UserProperties {private String username;private String password;
}
配置文件
user:properties:username: adminpassword: password
测试代码
@RestController
@RequestMapping("/user")
public class UserController {@ResourceUserProperties userProperties;@GetMapping("/test2")public String test2() {return userProperties.getUsername();}
}

总结

说明批量读取 @ConfigurationProperties单值读取 @Value
松散语法在yml格式的配置文件中能使用 properties不支持不支持
JSR303数据校验支持不支持
复杂数据类型支持不支持
SpEL不支持支持

补充

配置文件的加载顺序

  1. classpath
  2. config
  3. file

file > classpath config > classpath

在同级目录下

yml或者yaml优先加载 如果出现相同的属性则会被Properties中的配置所覆盖

4、 概要与ymal语法

spring boot 支持两种配置文件格式

  • properties
  • yml 或者 yaml

约定优于配置

配置文件的名称必须是application开头

5、多环境配置

  1. 生产环境
  2. 开发环境
  3. 测试环境

如果各种环境配置信息没有区别的,配置在主配置文件中

application.yml

server:# 修改应用程序端口port: 8888servlet:# 修改应用程序的前缀context-path: "/api/v1"
# 引入多环境配置文件
spring:profiles:active: "dev,db"

application-dev.yml

server:port: 8881logging:level: debug

application-db.yml


通过外面命令指定(了解)

java -jar app.jar --spring.profiles.active=dev

外部执行jar工程包

java -jar app.jar

day62、文件上传和日期型文件

前期准备工作

使用

导入依赖

<dependency><groupId>com.aliyun.ossgroupId><artifactId>aliyun-sdk-ossartifactId><version>3.10.2version>
dependency>

配制

配置文件

aliyun:oss:endpoint: " https://oss-cn-guangzhou.aliyuncs.com"access-key-id: "LTAI5tLzBaVSAe65vuho4o3n"access-key-secret: "K4jFCGp8evfF7gJb3gkjkUhNrScNHc"bucket-name: "smart-2109"

配置属性类

@ConfigurationProperties("aliyun.oss")
@Component
public class OSSConfigProperties {//  https://oss-cn-guangzhou.aliyuncs.comprivate String endpoint;private String accessKeyId;private String accessKeySecret;// smart-2109private String bucketName;
}

配置类

@Configuration
public class AliyunOSSConfig {@Resourceprivate OSSConfigProperties properties;/*** OSS对象注入到容器** @return*/@Beanpublic OSS oss() {return new OSSClientBuilder().build(properties.getEndpoint(), properties.getAccessKeyId(), properties.getAccessKeySecret());}
}

业务层

  1. MultipartFile

    1. 文件的后缀名

    2. 上传文件的流

  2. oss.putObject方法

    1. bucketName
    2. key 文件上传的相对路径+文件名
    3. input 客服端上传文件的流
  3. 获取图片的显示路径

    @ResourceOSS oss;@ResourceOSSConfigProperties properties;// 图片的重名前缀public static final String IMG_PREFIX_FILE = "IMG_";// 云服务器存储的图片的根目录public static final String BUCKET_NAME_IMAGE = "images";@Overridepublic String uploadImage(MultipartFile multipartFile) {/***  2 images/21111/xxx.png*   获取文件的原始名称*/String originalFilename = multipartFile.getOriginalFilename();// 对图片进行重命名String newFileName = getNewFileName(originalFilename);// String key = BUCKET_NAME_IMAGE + File.separator + DateUtil.format(new Date(), "yyyy-MM-dd") + File.separator + newFileName;try {//  1  上传到阿里云OSS服务器PutObjectResult putObjectResult = oss.putObject(properties.getBucketName(), key, multipartFile.getInputStream());} catch (IOException e) {throw new ServiceException(ResultCode.FILE_UPLOAD_ERROR);}return null;}/*** 对图片进行重命名** @param originalFilename* @return*/private static String getNewFileName(String originalFilename) {/*** 自定义命名规则 + 文件的后缀名* IMG_2022031415331234.png* xxxx.png*/// 获取文件的后缀名String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));return String.format("%s%s%s%s", IMG_PREFIX_FILE, DateUtil.format(new DateTime(), DATE_FORMAT), RandomUtil.randomNumbers(4), suffixName);}

获取图片的访问地址

private String getUrl(String bucketName, String key) {Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);String url = oss.generatePresignedUrl(bucketName, key, expiration).toString();return url;
}

完整代码

@Service
public class UploadServiceImpl implements UploadService {public static final String IMG_PREFIX_FILE = "IMG_";public static final String DATE_FORMAT = "yyyyMMddHHmmss";public static final String BUCKET_NAME_IMAGE = "images";@Resourceprivate OSS oss;@Resourceprivate OSSConfigProperties properties;/*** 图片覆盖* /1/20210314/xxx.png* 36655/按着日期对文件归类 // 可以防止图片覆盖* // 对图片重命名** @return*/@Overridepublic String uploadImage(MultipartFile multipartFile) {/*** 获取文件的原始名称*/// 判断文件的格式String originalFilename = multipartFile.getOriginalFilename();// 判断文件是否是上传格式String newFileName = getNewFileName(originalFilename);String key = BUCKET_NAME_IMAGE + File.separator + DateUtil.format(new Date(), "yyyy-MM-dd") + File.separator + newFileName;try {PutObjectResult putObjectResult = oss.putObject(properties.getBucketName(), key, multipartFile.getInputStream());if (!ObjectUtil.isEmpty(putObjectResult.getETag())) {// 表示上传成功return getUrl(properties.getBucketName(), key);} else {throw new ServiceException(ResultCode.FILE_UPLOAD_ERROR);}} catch (IOException e) {throw new ServiceException(ResultCode.FILE_UPLOAD_ERROR);}}/*** 对图片进行重命名** @param originalFilename* @return*/private static String getNewFileName(String originalFilename) {/*** 自定义命名规则 + 文件的后缀名* IMG_2022031415331234.png* xxxx.png*/// 获取文件的后缀名String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));return String.format("%s%s%s%s", IMG_PREFIX_FILE, DateUtil.format(new DateTime(), DATE_FORMAT), RandomUtil.randomNumbers(4), suffixName);}private String getUrl(String bucketName, String key) {Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);String url = oss.generatePresignedUrl(bucketName, key, expiration).toString();return url;}}

配置信息

spring:servlet:multipart:enabled: true#      location: "upload/static/image"# 单个上传的文件最大值max-file-size: 10MB#  一起请求上传文件的最大值max-request-size: 100MB

控制层

    /*** 文件上传* 1. 上传的本地的服务器* 2. 上传到云对象存储  OSS* 3  FastDFS  (技术要求高)* @return*/@PostMapping("/upload/img")public ResponseResult<String> uploadImage(@RequestBody MultipartFile multipartFile) {String url = uploadService.uploadImage(multipartFile);return ResponseResult.success(url);}

测试接口

课外延展:

​ @Configuration注解的更具体用法

@Configuration

SQL

CREATE TABLE banner
(banner_id   int AUTO_INCREMENT COMMENT '主键' PRIMARY KEY,name        varchar(10)                           NOT NULL COMMENT '名称',description varchar(64) DEFAULT ''                NOT NULL COMMENT '描述',img         varchar(255)                          NOT NULL COMMENT '轮播图的路径',link_status int         DEFAULT 1                 NOT NULL COMMENT '1 表示启用  0 表示禁用',link        int         DEFAULT 1                 NOT NULL COMMENT '1 表示全部店铺,  2 表示指定店铺',link_jump   int         DEFAULT 0                 NOT NULL COMMENT '0 表示不跳转商品信息 1  表示跳转商品链接',product_id  bigint      DEFAULT -1                NOT NULL COMMENT '跳转的商品ID',type        int                                   NULL COMMENT '1 表示pc端  2 表示 移动端',create_date datetime    DEFAULT CURRENT_TIMESTAMP NULL COMMENT '表示创建时间',is_del      int         DEFAULT 0                 NOT NULL COMMENT '0 不删除  1 表示删除',CONSTRAINT name UNIQUE (name)   
);

控制层

@PostMapping("/add")
public ResponseResult<Integer> add(@Validated(BannerRequestParams.Add.class) @RequestBody BannerRequestParams banner) {int count = bannerService.add(banner);return ResponseResult.success(count);
}

请求参数

  1. @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)
  2. 接受客服端日期格式格式, 客服端传递过来的是字符串
/*** @author zhangwei*/
@Data
@Validated
public class BannerRequestParams {public interface Add {}public interface Update {}/*** 主键*/@NotNull(groups = Update.class)private Integer bannerId;/*** 名称*/@Length(min = 1, max = 10, message = "最多10个字")private String name;/*** 描述*/private String description;/*** 轮播图的路径*/@NotNullprivate String img;/*** 1 表示启用  0 表示禁用*/private Integer linkStatus;/*** 1 表示全部店铺,  2 表示指定店铺*/private Integer link;/*** 0 表示不跳转商品信息 1  表示跳转商品链接*/private Integer linkJump;/*** 跳转的商品ID*/private Long productId;/*** 1 表示pc端  2 表示 移动端*/private Integer type;//上传时使用@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createDate;}

业务层

  1. 请求参数对象(QO)转化持久化对象(PO)
/*** @author zhangwei*/
@Service
public class BannerServiceImpl implements BannerService {@Resourceprivate BannerMapper bannerMapper;@Overridepublic int add(BannerRequestParams banner) {Banner bannerEntity = new Banner();/*** 第一个参数有值  第二个没值*/BeanUtils.copyProperties(banner, bannerEntity);int count = bannerMapper.insert(bannerEntity);if (count > 0) {return count;} else {throw new ServiceException(ResultCode.ERROR);}}
}

数据层

public interface BannerMapper extends BaseMapper {
}
@Data
@TableName(value = "banner")
public class Banner {/*** 主键*/@TableId(value = "banner_id", type = IdType.INPUT)private Integer bannerId;/*** 名称*/@TableField(value = "`name`")private String name;/*** 描述*/@TableField(value = "description")private String description;/*** 轮播图的路径*/@TableField(value = "img")private String img;/*** 1 表示启用  0 表示禁用*/@TableField(value = "link_status")private Integer linkStatus;/*** 1 表示全部店铺,  2 表示指定店铺*/@TableField(value = "link")private Integer link;/*** 0 表示不跳转商品信息 1  表示跳转商品链接*/@TableField(value = "link_jump")private Integer linkJump;/*** 跳转的商品ID*/@TableField(value = "product_id")private Long productId;/*** 1 表示pc端  2 表示 移动端*/@TableField(value = "`type`")private Integer type;/*** 表示创建时间*/@TableField(value = "create_date")private Date createDate;/*** 0 不删除  1 表示删除*/@TableField(value = "is_del")private Integer isDel;public static final String COL_BANNER_ID = "banner_id";public static final String COL_NAME = "name";public static final String COL_DESCRIPTION = "description";public static final String COL_IMG = "img";public static final String COL_LINK_STATUS = "link_status";public static final String COL_LINK = "link";public static final String COL_LINK_JUMP = "link_jump";public static final String COL_PRODUCT_ID = "product_id";public static final String COL_TYPE = "type";public static final String COL_CREATE_DATE = "create_date";public static final String COL_IS_DEL = "is_del";
}

VO对象

  • @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”)
@Data
public class BannerVo {/*** 主键*/private Integer bannerId;/*** 名称*/private String name;/*** 描述*/private String description;/*** 轮播图的路径*/private String img;/*** 1 表示启用  0 表示禁用*/private Integer linkStatus;/*** 1 表示全部店铺,  2 表示指定店铺*/private Integer link;/*** 0 表示不跳转商品信息 1  表示跳转商品链接*/private Integer linkJump;/*** 跳转的商品ID*/private Long productId;/*** 1 表示pc端  2 表示 移动端*/private Integer type;//json数据序列化指定日期格式@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createDate;
}

配置文件中

spring:# 配置json数据统一的日志解析格式jackson:date-format: "yyyy-MM-dd HH:mm:ss"


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部