144 SSM与SSH
文章目录
- 一、SSM说明
- 二、实践:
- 三、项目目录
- SSM与SSH
- MyBatis与Hibernate的优劣
- SH和SSM对比异同点、各自优势
- SSH和SSM定义
- 共同点:
- 不同点:
- SSH和SSM的实现原理
- Struts2 的实现原理
- SpringMVC 的实现原理:
- 总结
一、SSM说明
ssm(Spring、SpringMVC、mybatis)整合:
配置文件的整合:SpringMVC的配置文件(mvc.xml)单独一个、Spring的配置文件(applicationContext.xml)与mybatis的配置文件(mybatis-config.xml)可以选择整合成一个,也可以选择保留mybatis-config.xml,只不过其里面的数据源配置,mapper文件注册等要在applicationContext.xml里面写,仅仅保留一些< settings> < plugin>标签,不过还是建议整合成一个,
mvc.xml 与 applicationContext.xml 中的关于 注解扫描 的配置
- 两个工厂不能有彼此侵入,即,生产的组件不能有重合。
- 告知SpringMVC 哪些包中 存在被注解的类
use-default-filters=true凡是被@Controller @Service @Repository注解的类, 都会被扫描,
use- default- filters=false默认不扫描包内的任何类,只扫描include- filter中指定的类,只扫描被@Controller注解的类 - mvc.xml :
<!-- 注解扫描 下面这些配置是指SpringMVC在扫描com.wlw包下的注解时,只扫描有Controller注解的类(就是类名之上加了@Controller的类),其他的忽略--><context:component-scan base-package="com.wlw" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter></context:component-scan>
4. applicationContext.xml
<!--扫描注解 下面这些配置是指Spring在扫描com.wlw包下的注解时,不扫描有Controller注解的类(就是类名之上加了@Controller的类,因为这样的类被SpringMVC扫描了,区分职责关系,可以对比mvc.xml文件),其他的都要扫描--><context:component-scan base-package="com.wlw" use-default-filters="true"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>
整个项目有大致三个配置文件 web.xml 、 mvc.xml (SpringMVC配置文件)、 applicationContext.xml (Spring配置文件), 在web.xml文件中会声明另外两个配置文件地址,当tomcat启动时,会加载web.xml文件,进而加载另外两个配置文件,创建springmvc工厂(子工厂)与spring工厂(父工厂);
xml配置文件与注解之间的选择:在我们自己写的代码中,service层(xxxServiceImpl)用注解(@Service)来声明bean、用注解(@Autowired @Qualifier(“userDao”))来自动注入dao、用注解(@Transactional 来配置事务); controller层使用注解(@Controller)来声明bean、用注解(@Autowired @Qualifier(“userServiceImpl”))来自动注入 service。
SpringMVC配置文件(mvc.xml)中写的是:开启注解扫描、注解驱动、视图解析器、静态资源访问、拦截器、异常解析器、文件上传解析器等
Spring配置文件(applicationContext.xml)中写的是: DataSource、SqlSessionFactory、DAO接口 MapperScannerConfigurer、扫描注解、事务管理器、开启事务注解等 (其中之前在mybatis所作的配置,是写在SqlSessionFactory这个bean中的)
二、实践:
第一步:在 pom.xml文件中导入依赖,声明打包方式,更改maven编译规则,让xxxMapper.xml文件可以被编译,之后再第一次运行时,可查看target/classes文件中是否有对应的xxxMapper.xml,看是否编译成功
第二步:在main文件下新建webapp文件夹,在webapp文件下新建WEB-INF文件夹,并在WEB-INF文件夹下新建web.xml文件,这是web项目的配置文件,随着tomcat服务器启动而被加载,里面配置基本都是servlet组件,基本包括SpringMVC工厂(前端(核心)控制器)和Spring工厂,以及对post请求中,中文参数乱码的处理;并且项目的前端页面组件放在webapp文件夹下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!-- SpringMVC前端(核心)控制器1. 前端,接收所有请求2. 启动SpringMVC工厂 mvc.xml3. 负责springMVC流程调度--><servlet><servlet-name>mvc_wlw</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 局部参数,声明mvc配置文件位置--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:mvc.xml</param-value></init-param><!-- 懒汉式 饿汉式加载 可选--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>mvc_wlw</servlet-name><url-pattern>/</url-pattern><!--<url-pattern>*.action</url-pattern>--></servlet-mapping><!-- 此过滤器会进行:request.setCharactorEncoding("utf-8"); 对post请求中,中文参数乱码有效--><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>/*</url-pattern></filter-mapping><!-- 启动Spring工厂 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param>
</web-app>
- 第三步:在src/main/resources写mvc.xml 与 applicationContext.xml;
- mvc.xml
- applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 注解扫描 下面这些配置是指SpringMVC在扫描com.wlw包下的注解时,只扫描有Controller注解的类(就是类名之上加了@Controller的类),其他的忽略--><context:component-scan base-package="com.wlw" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter></context:component-scan><!-- 注解驱动 --><mvc:annotation-driven><!-- 安装FastJson,转换器 --><mvc:message-converters><bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><!-- 声明转换类型:json (将java对象转成josn)--><property name="supportedMediaTypes"><list><value>application/json</value></list></property></bean></mvc:message-converters></mvc:annotation-driven><!-- 视图解析器作用:1.捕获后端控制器的返回值="hello"2.解析: 在返回值的前后 拼接 ==> "/hello.jsp"--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 前缀 --><property name="prefix" value="/"></property><!-- 后缀 --><property name="suffix" value=".jsp"></property></bean><!-- 处理静态资源访问--><mvc:default-servlet-handler/><!--拦截器--><mvc:interceptors><mvc:interceptor><mvc:mapping path="/loger/test1"/> <!--要拦截的路径--><bean class="com.wlw.interceptor.MyInterceptor"></bean></mvc:interceptor></mvc:interceptors><!--异常解析器--><bean class="com.wlw.resolver.MyExceptionResolver"/><!--文件上传解析器-->
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"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/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--整合时,DAO放在工厂中(bean标签)是由MapperScannerConfigurer 来帮我们完成的 ,而MapperScannerConfigurer 又需要sqlSessionFactory支持 , sqlSessionFactory 又需要DataSource--><!-- DataSource --><!-- 导入文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--创建数据源--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><!--基本配置--><property name="driverClassName" value="${jdbc.driverClass}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><!-- 配置初始化大小、最小、最大 --><property name="initialSize" value="${jdbc.init}"/><property name="minIdle" value="${jdbc.minIdle}"/><property name="maxActive" value="${jdbc.maxActive}"/><!-- 配置获取连接等待超时的时间 ms--><property name="maxWait" value="60000"/><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="60000"/><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="300000"/></bean><!-- SqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 注入连接池 --><property name="dataSource" ref="dataSource"></property><!-- (注册xxxDao-mapper文件)注入dao-mapper文件信息,如果映射文件和dao接口 同包且同名,则此配置可省略(要注意因为把mapper文件放在了dao文件夹下,所以要在pom.xml中更改maven编译规则)--><property name="mapperLocations"><list><value>classpath:com/wlw/dao/*.xml</value></list></property><!-- 为实体类起别名 --><property name="typeAliasesPackage" value="com.wlw.entity"></property><property name="plugins"><array><bean class="com.github.pagehelper.PageInterceptor"><property name="properties"><props><!-- 页号 调整到合理的值 0 max --><prop key="reasonable">true</prop></props></property></bean></array></property></bean><!-- DAO接口 MapperScannerConfigurer--><!-- mapperScannerConfigurer 管理DAO实现类的创建,并创建DAO对象,存入工厂管理,当执行完这个配置之后,在工厂中就会有一个id为userDAO 的bean,而这个bean就是UserDAO实现类的对象 --><bean id="mapperScannerConfigurer9" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!-- dao接口所在的包 如果有多个包,可以用逗号或分号分隔 <property name="basePackage" value="com.a.dao,com.b.dao"></property>--><property name="basePackage" value="com.wlw.dao"></property><!-- 如果工厂中只有一个SqlSessionFactory的bean,此配置可省略 --><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean><!--扫描注解 下面这些配置是指Spring在扫描com.wlw包下的注解时,不扫描有Controller注解的类(就是类名之上加了@Controller的类,因为这样的类被SpringMVC扫描了,区分职责关系,可以对比mvc.xml文件),其他的都要扫描--><context:component-scan base-package="com.wlw" use-default-filters="true"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan><!-- 1. 引入一个事务管理器,其中依赖DataSource,借以获得连接,进而控制事务逻辑 --><bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!--开启事务注解 只针对 这个@Transactional 事务注解--><tx:annotation-driven transaction-manager="tx"/>
</beans>
三、项目目录
D:\Program Files\IDEAworkspace\projects\JavaWeb_high\SSM_exam01
SSM与SSH
MyBatis与Hibernate的优劣
无论MyBatis或Hibernate都可以被称为ORM框架,Hibernate的设计理念是面向POJO的,而MyBatis不是。
Hibernate是一个标准的ORM框架,基本不需要编写SQL就可以通过映射关系来操作数据库,是一种全表映射的体现,维护关系比较复杂,sql语句自己生成,这就造成了对sql语句优化,修改比较困难。;而MyBatis需要我们提供SQL语句去运行,这就对sql修改和优化非常容易实现,程序员不必精通sql,只要懂得操作POJO就能够操作对应数据库的表。
在之前的时候,管理系统时代,首先是实现业务逻辑,然后才是性能,所以Hibernate在当时是主流。;而现在在移动互联网时代,MyBatis是首选,不屏蔽SQL,程序员可以自己制定SQL规则,能更加精确定义SQL,从而优化性能。更符合移动互联网高并发,大数据,高性能,高响应的要求。
Hibernate和MyBatis的增、删、查、改,对于业务逻辑层来说大同小异,对映射而言Hibernate的配置不需要接口和SQL,而MyBatis是需要的。对于Hibernate而言,不需要编写大量的SQL,就可以完全映射,同时提供了日志、缓存、级联(级联比MyBatis强大)等特性,此外还提供HQL (Hibernate Query Language)对POIO进行操作,使用十分方便,但是它也有**致命的缺陷:**由于无须SQL,当多表关联超过3个的时候,通过Hibernate的级联会造成太多性能的丢失,又或者我现在访问一个财 务的表,然后它会关联财产信息表,财产又分为机械、原料等.显然机械和原料的字段是不一样的,这样关联字段只能根据特定的条件 变化而变化,而Hibernate无法支持这样的变化。遇到存储过程,Hibernate只能作罢。更为关键的是性能,在管理系统的时代,对于性能的要求不是那么苛刻,但是在互联网时代性能就是系统的根本,响应过慢就会丧失客户,试想一下谁会去用一个经常需要等待超过10 秒以上的应用呢? **以上的问题MyBatis都可以解决,MyBatis 可以自由书写SQL、支持动态SQL、处理列表、动态生成表名,支持存储过程。**这样就可以灵活地定义查询语句,满足各类需求和性能优化的需要,这些在互联网系统中是十分重要的。
但MyBatis也有缺陷。首先,它要编写SQL和映射规则,其工作量稍微大于 Hibernate.其次,它支持的工具也很有限,不能像Hibernate那样有许多的插件可以帮助生成映射代码和关联关系,而即使使用生成工具,往往也需要开发者进一步简化, MyBatis 通过手工编码,工作量相对大些。
使用环境:对于性能要求不太苛刻的系统,比如管理系统、ERP 等推荐使用Hibernate;而对于性能要求高、响应快、灵活的系统则推荐使用MyBatis.
总1:
- Hibernate:
- 优点:面向对象开发,不需要自己写sql语句。如果进行数据库迁移不需要修改sql语句,只需要修改一下方言。使用方便
- 缺点:hibernate维护数据表关系比较复杂。完全是有hibernate来管理数据表的关系,不易维护,不易优化,不能开发比较复杂的业务。不容易写出高性能的程序。
- 适合范围:适合需求固定,对象数据模型稳定,性能要求不太苛刻的系统,中小型项目,比如:企业OA系统,管理系统
- MyBatis:
- 优点:对sql的优化,修改比较容易,可以灵活地定义查询语句,满足各类需求和性能优化的需要
- 缺点:工作量大,大型复杂系统需要写很多的sql语句
- 适合范围:适合开发需求变更频繁的系统,比如:互联网项目。
- Hibernate:
总2:
两者的相同点
Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
Hibernate和MyBatis都支持JDBC和JTA事务处理。
两者各自优势
- MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
- MyBatis容易掌握,而Hibernate门槛较高。
- Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
- Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
- Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
- Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳,更新操作不能指定刷新指定记录,会清空整个表,但是也可以使用第三方缓存。
- Hibernate 封装性好,屏蔽了数据库差异,自动生成SQL语句,应对数据库变化能力较弱,SQL语句优化困难。
- MyBatis仅实现了SQL语句和对象的映射,需要针对具体的数据库写SQL语句,应对数据库变化能力较强,SQL语句优化较为方便。
SH和SSM对比异同点、各自优势
SSH和SSM定义
SSH 通常指的是 Struts2 做控制器(Action),Spring 管理各层的组件,Hibernate 负责持久化层。
SSM 则指的是 SpringMVC 做控制器(controller),Spring 管理各层的组件,MyBatis 负责持久化层。
共同点:
1.Spring依赖注入DI来管理各层的组件。
2.使用面向切面编程AOP管理事物、日志、权限等。
不同点:
1.Struts2 和 SpringMVC 控制器(controller)控制视图和模型的交互机制的不同,
2.Struts2是Action类级别,SpringMVC是方法级别,更容易实现RESTful风格。
SSH和SSM的实现原理
Struts2 的实现原理
Struts2框架执行步骤(Struts2使用Filter嵌入):
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5、ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。
9、将处理结果返回给客户端
SpringMVC 的实现原理:
SpringMVC框架执行步骤(SpringMVC使用Servlet嵌入):
1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.
2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。
3-4、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。
5、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。
6、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。
7、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。
总结
SSM和SSH不同主要在MVC实现方式,以及ORM持久化方面不同(Hiibernate与Mybatis)。SSM越来越轻量级配置,将注解开发发挥到极致,且ORM实现更加灵活,SQL优化更简便;而SSH较注重配置开发,其中的Hiibernate对JDBC的完整封装更面向对象,对增删改查的数据维护更自动化,但SQL优化方面较弱,且入门门槛稍高。
Spring家族:
144 SSM与SSH相关推荐
- java ssh优势_java框架组合ssm和ssh各自的优势是什么?
SSM和SSH不同主要在MVC实现方式,以及ORM持久化方面不同(Hiibernate与Mybatis). SSM优势: SSM越来越轻量级配置,将注解开发发挥到极致,且ORM实现更加灵活,SQL优化 ...
- SSM和SSH框架对比
SSM和SSH框架对比 1. SSH:Spring+Struts2+Hibernate SSM:Spring+SpringMVC+MyBaitis 两个框架都是IoC容器+MVC框架+ORM框架.Io ...
- Springboot,SSM及SSH的概念、优点、区别及缺点
Springboot的概念: 是提供的全新框架,使用来简化Spring的初始搭建和开发过程,使用了特定的方式来进行配置,让开发人员不在需要定义样板化的配置.此框架不需要配置xml,依赖于像MAVEN这 ...
- SSM框架+SSH框架简介
SSM框架 Spring+SpringMVC+MyBatis Spring:Spring是一个开源框架.它的目标是是使现有的JavaEE技术更容易使用和养成良好的编程习惯.它是一个轻量级的框架,渗透了 ...
- SSM、SSH框架 | Mybatis | Spring | Maven
1.三层架构 1.1 表现层: 用于展示数据 1.2 业务层: 处理业务需求 1.3 持久层: 直接和数据库进行交互 1.4 架构间的关系 1.5 框架组合 1.5.1 SSH:Struts .Spr ...
- SSH与SSM的区别以及相关技术的流行度
先来百度一下,看看目前在流行啥 百度搜索搜索关键词 百度返回数量 SSM Java SSH Java 可以看到是SSM胜出. 所在分层 SSH SSM 页面层(View) JSP JSP(已经被thy ...
- Java Web学习总结(28)——Java Web项目MVC开源框架SSH和SSM比较
SSH和SSM定义 SSH 通常指的是 Struts2 做控制器(controller),spring 管理各层的组件,hibernate 负责持久化层. SSM 则指的是 SpringMVC 做控制 ...
- SSM框架和SSH框架的详细对比
最近了解到SSH框架的使用的企业越来越少了,SSM框架更受青睐,我就了解了一下两种框架体系的区别.反正都要学,现在我已经学过了SSH框架,接下来就是学SSM框架了. 声明:下边的内容是我转载 学习的. ...
- Java面试题:SSH和SSM原理对比总结以及牵扯到的面试问题
当下流行的两种企业开发MVC开源框架,是我们Java程 序猿必备知识能力.MVC是Model-View-Controller的简写."Model" 代表的是应用的业务逻辑dao层. ...
最新文章
- 【C++】Google C++编码规范(四):其他C++
- python姓名输出语句_Python最基本的输入输出详解
- MachineLearning(4)-核函数与再生核希尔伯特空间
- 【机器学习】Bagging和Boosting的区别(面试准备)
- 2017年最新的全国省市sql数据
- NBOOT分析-NBOOT.c(2)
- C语言 一个字符串翻转函数的编写
- 未来教育计算机二级考试系统出错,未来教育计算机二级模拟考试系统
- 机器视觉算法包halcon介绍
- 联想换机助手_Smart Switch.apk下载|S换机助手下载 v3.4.04 安卓版_最火软件站
- PLC数据采集解决方案及数采网关
- MarkDown 下载-安装
- Java web项目中获取WebRoot目录下的文件
- C语言switch练习之输入某年某月某日,判断这一天是这一年的第几天。
- java实现断点续播_哪些播放器有断点续播和定点播放功能?
- qt之QSqlQuery类执行SQL语句
- 建设智能工厂建设,主要划分为哪几步?
- HTTP状态201(Created)
- 软件需求工程 高校教学平台 用户手册
- 计算机音乐数字谱抖音,抖音计算器谱子有哪些 计算器音乐乐谱大全
热门文章
- 学计算机大专需要买笔记本吗,上大学该买电脑吗?学长:买的时候以为是刚需,买了变成“鸡肋”...
- 美团前端一面高频面试题
- html div flex,利用css flex实现垂直居中
- 44 RT-Thread Nano移植到stm32F103CBT6 (STD标准库)
- AE牛顿动力学插件Motion Boutique Newton 3 Mac破解版
- 【随感】8月工作总结:这个月我去干啥了?
- 微信小程序蓝牙打印以及打印二维码
- 2022-2023 Java毕业设计指导
- 人工智能高性能计算、神经形态计算和量子计算介绍
- 九度题目1173:查找