1、SpringMVC入门程序:

(1)导入jar包:spring核心jar包、spring-webmvc整合Jar包

(2)配置前端控制器:web.xml文件中

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"><display-name>Springmvc_01</display-name><!-- 配置前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <!-- contextConfigLocation:配置springmvc加载的配置文件(处理处映射器、处理器适配器等等) --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param> </servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- 第一种:*.action,访问以.action结尾由DispatcherServlet进行解析第二种:/,所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析,使用此种方法可以实现RESTful风格的url第三种:/*,这种配置不对,使用这种配置,最终要转发到一个jsp页面,仍然会由DispatcherServlet解析jsp,不能根据jsp页面找到Handle,会报错--><url-pattern>*.action</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list>
</web-app>

(3)springmvc.xml约束:

(4)配置处理器映射器:

(5)配置处理器适配器:

(6)配置视图解析器:

(7)配置Handle:

(8)编写Handle:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"        xmlns:mvc="http://www.springframework.org/schema/mvc"     xmlns:tx="http://www.springframework.org/schema/tx"  xmlns:aop="http://www.springframework.org/schema/aop"  xmlns:context="http://www.springframework.org/schema/context"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"              xsi:schemaLocation="                                               http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd    http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context.xsd    http://www.springframework.org/schema/mvc    http://www.springframework.org/schema/mvc/spring-mvc.xsd  http://www.springframework.org/schema/tx   http://www.springframework.org/schema/tx/spring-tx.xsd  http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd">     <!--        非注解:配置Handler作用:将编写的Handler在spring容器加载<bean id="ItemsController1" name="/queryItems.action" class="com.zwp.controller.ItemsController1"></bean><bean id="ItemsController2" class="com.zwp.controller.ItemsController2"></bean>非注解的处理器映射器第一种:将bean的name作为url进行查找,需要配置Handler是指定beanname(就是url)<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>第二种:简单url映射<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props>对ItemsController1进行url映射,url是key的值,ItemsController1是Handler的id值<prop key="/queryItems1.action">ItemsController1</prop><prop key="/queryItems11.action">ItemsController1</prop><prop key="/queryItems2.action">ItemsController2</prop></props></property></bean>非注解的处理器适配器第一种:要求handler实现Controller接口<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>第二种: 要求handler实现HttpRequestHandler接口<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean> --><!-- 注解方式:配置Handler --><!-- 单个加载方式: --><!-- <bean class="com.zwp.controller.ItemsController3"></bean> --><!-- 批量加载:组件扫描方式: --><context:component-scan base-package="com.zwp.controller"></context:component-scan><!-- 注解的处理器映射器(配对使用)--><!--   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean> --><!-- 注解的处理器适配器(配对使用) --><!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean> --><!-- 实际使用 mvc:annotation-driven代替上面注解适配器和映射器并且默认加载了很多参数绑定方法,比如json转化解析器被默认加载了--><mvc:annotation-driven></mvc:annotation-driven><!-- 视图解析器解析jsp页面,默认使用jstl标签,classpath下得有jstl的包 -->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"></property><property name="suffix" value=".jsp"></property></bean>
</beans>
//编写Hander:实现controller接口:
public class ItemsController1 implements Controller{@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {    //调用service查询数据库,查询商品列表,这里使用静态数据List<Items> itemsList=new ArrayList<Items>();Items items1=new Items();items1.setName("键盘");items1.setPrice(80.0f);items1.setDetail("机械键盘");Items items2=new Items();items2.setName("苹果手机");items2.setPrice(4000.0f);items2.setDetail("iphone6");itemsList.add(items1);itemsList.add(items2);//返回modelAndViewModelAndView modelAndView=new ModelAndView();//相当于request的setAttribute,在jsp页面通过itemsList取数据modelAndView.addObject("itemsList", itemsList);//指定视图modelAndView.setViewName("/WEB-INF/jsp/Items/itemsList.jsp");return modelAndView;}}

至此,一个简单的入门springmvc程序就编写完成,只需要在网页访问响应的地址就可以了,我的访问地址是:

http://localhost:8080/Springmvc_01/queryItems.action

2、非注解的处理器映射器和适配器:

多个映射器可以共存,前端控制器判断url能让哪些映射器处理,就让正确的映射器处理。

//编写Hander:使用第二种处理器适配器,需要实现HttpRequestHandler接口:
public class ItemsController2 implements HttpRequestHandler{@Overridepublic void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<Items> itemsList=new ArrayList<Items>();Items items1=new Items();items1.setName("键盘");items1.setPrice(80.0f);items1.setDetail("机械键盘");Items items2=new Items();items2.setName("苹果手机");items2.setPrice(4000.0f);items2.setDetail("iphone6");itemsList.add(items1);itemsList.add(items2);//设置模型数据request.setAttribute("itemsList", itemsList);//设置视图:request.getRequestDispatcher("/WEB-INF/jsp/Items/itemsList.jsp").forward(request, response);//此方法可以通过修改response,设置响应的数据格式,比如json数据
//      response.setCharacterEncoding("utf-8");
//      response.setContentType("application/json;charset=utf-8");
//      response.getWriter().write("json串");}
}

3、注解的处理器映射器和适配器(配对使用):

     <!-- 注解的处理器映射器(配对使用)--><!--   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean> --><!-- 注解的处理器适配器(配对使用) --><!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean> --><!-- 实际使用 mvc:annotation-driven代替上面注解适配器和映射器并且默认加载了很多参数绑定方法,比如json转化解析器被默认加载了--><mvc:annotation-driven></mvc:annotation-driven>

(1)开发Handler:

//@Controller:表明这是一个控制器,不需要实现任何接口
@Controller
public class ItemsController3{//使用@RequestMapping注解,实现方法名和url进行映射,一个方法对应一个url//建议方法名和url一样@RequestMapping("queryItems")public ModelAndView queryItems() throws Exception {    //调用service查询数据库,查询商品列表,这里使用静态数据List<Items> itemsList=new ArrayList<Items>();Items items1=new Items();items1.setName("键盘");items1.setPrice(80.0f);items1.setDetail("机械键盘123");Items items2=new Items();items2.setName("苹果手机");items2.setPrice(4000.0f);items2.setDetail("iphone6s");itemsList.add(items1);itemsList.add(items2);//返回modelAndViewModelAndView modelAndView=new ModelAndView();//相当于request的setAttribute,在jsp页面通过itemsList取数据modelAndView.addObject("itemsList", itemsList);//指定视图modelAndView.setViewName("Items/itemsList");return modelAndView;}
}

(2)在springmvc中加载Handler:

       <!-- 注解方式:配置Handler --><!-- 单个加载方式: --><!-- <bean class="com.zwp.controller.ItemsController3"></bean> --><!-- 批量加载:组件扫描方式: --><context:component-scan base-package="com.zwp.controller"></context:component-scan>

4、视图解析器:前缀和后缀:

       <!-- 视图解析器解析jsp页面,默认使用jstl标签,classpath下得有jstl的包 -->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"></property><property name="suffix" value=".jsp"></property></bean>   

5、RequestMappering的作用:

(1)用在类上面:窄化url;

(2)用上方法上面:映射url路径;

(3)用在方法上面:通过method属性,限制http请求。

6、Controller三种返回值:ModelAndView、String、void:

(1)返回ModelAndView:

需要在方法结束时,定义ModelAndView,将model和view分别进行设置。

        //controller第一种返回值:ModelAndView//商品查询列表@RequestMapping("/queryItems")public ModelAndView queryItems(HttpServletRequest request,ItemsQueryVo itemsQueryVo) throws Exception {       //调用service查询数据库,查询商品列表List<ItemsCustom> itemsList=itemsService.selectItemsList(itemsQueryVo);//返回modelAndViewModelAndView modelAndView=new ModelAndView();//相当于request的setAttribute,在jsp页面通过itemsList取数据modelAndView.addObject("itemsList", itemsList);//指定视图modelAndView.setViewName("Items/itemsList");return modelAndView;}

(2)返回String:

如果controller方法返回String,表示返回逻辑视图名。真正视图(jsp路径)=前缀+逻辑视图名+后缀。

 //Controller第二种返回值:String //@RequestParam里边指定指定requset传入参数和形参进行绑定//通过required属性指定参数是否必须要传入;通过defaultValue可以设置默认值,如果id参数没有传入,将默认值和形参绑定//商品信息修改页面显示:@RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})public String editItems(Model model,@RequestParam(value="id",required=true) Integer items_id) throws Exception{    //调用service查询数据库,根据id查询商品信息ItemsCustom itemsCustom=itemsService.findItemsById(items_id);if(itemsCustom==null){throw new CustomException("修改的商品信息不存在");}//通过形参中的model将model传到页面上;model.addAttribute("itemsCustom", itemsCustom);//返回逻辑视图名return "Items/editItems";}

--redirect从定向:

特点:浏览器地址栏中的url会变化,修改提交的request数据无法传到重定向地址中。

--forward页面转发:

特点:通过forward进行页面转发,浏览器地址栏url不变,request可以共享。

//重定向:
return "redirect:queryItems.action";
//页面转发:
return "forward:queryItems.action";

(3)void:

在controller方法形参上可以定义request和response,使用request和response指定响应结果:

①使用request转向页面,如下:

request.getRequestDispatcher("页面路径").forward(request,response);

②通过response页面重定向:

response.sendRedirect("url");

③也可以通过response指定响应结果,例如响应json数据如下:

response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");

7、参数绑定:

(1)参数绑定过程:从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。

springmvc中,接收页面提交的数据是通过方法形参来接收,而不是像struts2在controller类定义成员变量接收。

(2)默认支持的类型:

    直接在controller方法形参上定义下边类型的对象,就可以使用这些对象。在参数绑定过程中,如果遇到下边类型直接进行绑定:

①HttpServletRequest:通过request对象获取请求信息;

②HttpServletResponse:通过response处理响应信息;

③HttpSession:通过session对象得到session中存放的对象;

④Model/ModelMap:model是一个接口,modelmap是一个接口实现;作用:将model数据填充到request域。

⑤还支持一些简单类型的参数绑定:通过@PequestParam对简单类型的参数进行绑定。

如果不使用@PequestParam,要求request传入的参数名称和controller方法的形参名称一致,方可绑定成功。

如果使用@PequestParam,不限制request传入的参数名称和controller方法的形参名称一致。

8、参数绑定:简单类型的pojo绑定:

页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo。

9、自定义参数绑定:

--自定义参数绑定实现日期类型绑定:

对于controller形参中的pojo对象,如果属性中有日期类型,需要自定义参数绑定。

将请求日期数据串转成日期类型,要转换的日期类型和pojo中日期属性类型保持一致。

(1)springmvc.xml配置文件:

       <!--conversion-service="conversionService:注入自定义参数绑定"  --><mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
       <!-- 自定义参数绑定 --><bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><!-- 转化器 --><property name="converters"><list><!-- 日期类型装换器 --><bean class="com.zwp.ssm.controller.converter.CustomDateConverter"></bean></list></property></bean>     

(2)自定义的绑定器:

//自定义参数绑定:
//实现啊Converter接口,<转化前格式,转化后格式>,
//转化后的格式要和接收的pojo中的属性类属性一致
public class CustomDateConverter implements Converter<String,Date>{@Overridepublic Date convert(String source) {//自定义日期格式绑定器: SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");try{//转换成功直接返回return simpleDateFormat.parse(source);}catch(Exception e){e.printStackTrace();}//如果参数绑定失败,返回nullreturn null;}
}

10、参数绑定:包装类型的pojo:

11、参数绑定:数组绑定:


12、参数绑定:list绑定:

通常在需要批量提交数据时,将提交的数据绑定到list<pojo>中,比如,成绩录入(录入多门成绩,批量提交)。

13、参数绑定:Map绑定:

在包装类中定义Map对象,并添加get/set方法,action使用包装对象接收。

包装类中的定义Map对象如下:

14、validation校检:

项目中,通常使用较多的是前端的校检,比如页面中的js校检。对于安全要求较高点建议在服务端进行校验。

(1)服务端检验:

控制层controller,校验页面请求的参数的合法性。在服务端控制层controller校验,不区分客户端类型(浏览器、手机客户端、远程调用)。

业务层service(使用较多):主要检验关键业务参数,仅限于service接口中使用的参数。

持久层dao:一般不进行校验。

(2)springmvc校验:

springmvc使用hibenate的校验框架(和hibernate没有任何关系)

校验思路:页面提交请求参数,请求到controller方法中,使用validation进行校验。如果检验出错,将错误信息展示到页面。

步骤:

①导入jar包:

(hibernate-validator.5.x.x和validation-api.1.0.0版本冲突,使用hibernate-validator.4.x.x)

②配置校验器:(springmvc.xml文件中)

       <!-- 校验器: --><bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"><!-- hibernate校验器 --><property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property><!-- 指定校验使用的资源文件,如果不指定则默认使用classpath下的ValidationMessage.properties --><property name="validationMessageSource" ref="messageSource"></property>     </bean><!-- 校验错误信息配置文件 --><bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><!-- 资源文件名 --><property name="basenames"><list><value>classpath:CustomValidationMessage</value></list></property><!-- 资源文件编码格式 --><property name="fileEncodings" value="utf-8"></property><!-- 对资源文件内容缓存时间,单位秒 --><property name="cacheSeconds" value="120"></property></bean>

(3)检验器注入到处理器适配器中:

      <!-- validator="validator":注入校验器 --><mvc:annotation-driven validator="validator"></mvc:annotation-driven>

(4)错误信息文件:CustomValidationMessage.properties

#添加校验错误提交信息
items.name.length.error=请输入1到30个字符的商品名称
items.creatime.isNull=生产日期不能为空

(5)在pojo中添加校验规则:

//在pojo中添加校验规则
public class Items {private Integer id;//校验名称在1-30个字符之间,message是校验出错的显示信息//groups:定义校检器分组,可以定义多个分组@Size(min=1,max=30,message="{items.name.length.error}",groups={ValidGroup1.class})private String name;private Float price;private String pic;//校验生产日期不能为空@NotNull(message="{items.creatime.isNull}")private Date creatime;private String detail;}

(6)在controller中捕获错误信息:

 //商品信息修改提交//在需要校检的poji前面加上@Validated,在需要校检的pojo后面加上BindingResult bindingResult接收校检出错的信息//Validated和BindingResult必须配对出现,且顺序不能改变@RequestMapping(value="/editItemsSubmit",method={RequestMethod.POST,RequestMethod.GET})public String editItemsSubmit(Model model,HttpServletRequest request,Integer id,@ModelAttribute("itemsCustom") @Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,BindingResult bindingResult,MultipartFile items_pic) throws Exception{if(bindingResult.hasErrors()){List<ObjectError> allErrors=bindingResult.getAllErrors();//自定义一个list接受自己编码后的提示字符串,在把自己定义的list传到界面,//这样就解决了把乱码传到界面的问题了List<String> listErrors=new ArrayList<>();for(ObjectError objectError:allErrors){//System.out.println(objectError.getDefaultMessage());//把返回错误的提示再次编码String strError=new String(objectError.getDefaultMessage().getBytes("ISO-8859-1"),"UTF-8"); listErrors.add(strError);//把编码好的错误提示信息加自己定义好list集合里面去}model.addAttribute("allErrors", listErrors);return "Items/editItems";}return "forward:queryItems.action";
}

(7)在页面中显示错误信息:

15、validation分组检验:

每个controller方法需要不同的校验。

解决方法:定义多个校验分组(其实是一个java接口),分组中定义有哪些规则,每个controller方法使用不同的校验分组。

(1)创建分组接口类:

public interface ValidGroup1 {//接口不需要定义任何方法,仅是对不同的校验规则进行分组//此分组只对商品名称长度进行校验}

(2)定义分组:(使用groups)

(3)在controller指定使用哪个分组:

16、数据回显:

(1)简单类型的数据回显:使用model的方法。

model.addAttribute("id",id);

(2)pojo类型的数据回显:

第一种:默认方式:

pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写)

第二种:使用@ModelAttribute:指定pojo回显到页面在request中的key。

--@ModelAttribute还可以将方法的返回值传到页面:

页面上可以得到itemTypes数据:

第三种:使用model方式:

//可以直接使用model将提交pojo回显到页面
model.addAttribute("items",itemsCustom);

接下篇:SpringMVC框架--学习笔记(下):https://blog.csdn.net/a745233700/article/details/81045960

SpringMVC框架--学习笔记(上)相关推荐

  1. SpringMVC框架--学习笔记(下)

    接上篇:SpirngMVC框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81038382 17.全局异常处理: 系统中异常包 ...

  2. [Spring+SpringMVC+Mybatis]框架学习笔记(四):Spring实现AOP

    上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC 下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(五):SpringA ...

  3. mybatis框架--学习笔记(上)

    使用JDBC操作数据库的问题总结: (1)数据库连接,使用时创建,不使用时立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接. (2) ...

  4. 27Vert.X框架学习笔记

    vert.x框架学习笔记 文章目录 1 Vert.x简明介绍 1.1 Vert.x能干什么 1.2 Vert.x快速体验 1.3 Vert.x的简单介绍 1.4 Vert.x的一些优势 1.4.1 异 ...

  5. mybatis框架--学习笔记(下)

    上篇:mybatis框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81034021 8.高级映射: (1)一对一查询: ①使 ...

  6. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

  7. python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式

    本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式.分享给大家供大家参考,具体如下: 表单介绍 表单是HTML页面中负责数据采集功能的部件.由表单标签,表单域和表单按钮组成.通过表单,将 ...

  8. php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 以实例程序invo为例(invo程序放在网站根目录下的invo文件夹里,推荐php版本>=5.4) 环境不支持伪静态网址时的配置 第一步: 在app\con ...

  9. Samza框架-----学习笔记

    Samza框架-----学习笔记 基本概念: 作业:是对一组输入流进行处理转化成输出流的程序. 分区: Samza的流数据单位既不是Storm中的元组,也不是Spark Streaming中的DStr ...

最新文章

  1. 这个类库可以帮助你理解Java中的函数式编程
  2. 程序员第一次相亲,因请女方吃肯德基而被怒删!
  3. 汇编小程序---计算十以内两个数的相加
  4. ASP.NET MVC中权限控制的简单实现
  5. 这批.Net程序员水平不行啊!居然ASP.NET Core Middleware都不会用
  6. 别人叫我程序猿,我称自己攻城狮。没日没夜写代码,不知何日涨工资?
  7. 北京大学计算机科学李丰,中文智能问答系统作业解析-北京大学计算机科学技术研究所.PDF...
  8. 网站左角悬浮图双十一抢红包活动代码
  9. leetcode - 638. 大礼包
  10. 当关闭子窗口时刷新父窗口
  11. 从零开始学UC(1)之Microsoft Lync Server介绍
  12. 工具类软件操作手册_小规模纳税人开票前完成开票软件升级,关于1%税率的发票...
  13. java毕设项目教务排课系统(附源码)
  14. matlab绘制roc曲线,手把手画ROC曲线
  15. 6319. 【省选组】【USACO 2019 February Platinum】Problem 3. Mowing Mischief
  16. becon帧 wifi_beacon帧
  17. linux使用及shell常用命令技巧
  18. 使用for循环编写倒立反方向直角三角形
  19. 食品科学与工程考研可以考计算机吗,食品科学与工程女汉子,对于考研比较迷茫,有几个问题麻烦各位前辈指点迷津,谢谢 。 - 考研 - 小木虫 - 学术 科研 互动社区...
  20. “压缩(zipped)文件夹“G:\Program\Wechat WeChatFiles(wxid cqpx72n77z9x22 FileStorage\File 2022-12 基...

热门文章

  1. 八十七、Python | 十大排序算法系列(上篇)
  2. 深圳内推 | 腾讯AI Lab自然语言处理中心招聘NLP研究型实习生
  3. NAACL 2021 | QA-GNN:基于语言模型和知识图谱的问答推理
  4. CVPR 2021 | 破坏方法失效,新框架MagDR让Deepfake稳定难攻
  5. TPAMI 2020 | 高分辨率网络对计算机视觉任务的影响
  6. 立足前沿 直击热点 搭建平台,2018中国人工智能大会在深圳拉开帷幕
  7. Docker笔记整理
  8. Spring来装配组件
  9. sql 取重复key中的第一条_SQL每日一题
  10. 音频管理_人力资源管理师考试历年真题试卷+视频教程+音频讲义合集分享