赞
踩
同样作为实习求职者,一定会问到一些项目中的你所用到的框架,提到框架问题,避免少不了一些基础问题,于是我总结了一些有关于SSM框架常会被问到的问题,如下:
mybatis是一个持久层ORM框架。它内部封装了jdbc,使得开发更简洁,更高效。
Mybatis使开发者只需要关注sql语句本身,简化JDBC操作,不需要在关注加载驱动、创建连接、处理SQL语句
等繁杂的过程。
MyBatis可以通过xml或注解完成ORM映射关系配置。
JDBC是Java提供的一个操作数据库的API; MyBatis是一个持久层ORM框架,底层是对JDBC的封装。
MyBatis对JDBC操作数据库做了一系列的优化:
(1) mybatis使用已有的连接池管理,避免浪费资源,提高程序可靠性。
(2) mybatis提供插件自动生成DAO层代码,提高编码效率和准确性。
(3) mybatis 提供了一级和二级缓存,提高了程序性能。
(4) mybatis使用动态SQL语句,提高了SQL维护。(此优势是基于XML配置)
(5) mybatis对数据库操作结果进行自动映射
ORM的全称是Object Relational Mapping,即对象关系映射。
描述的是对象和表之间的映射。操作Java对象,通过映射关系,就可以自动操作数据库。
在ORM关系中,数据库表对应Java中的类,一条记录对应一个对象,一个属性对应一个列。
常见的ORM框架:Mybatis、Hibernate
注解、XML
1.#{}实现的是sql语句的预处理参数,之后再sql中用?号代替,使用时不需要关注数据类型,Mybatis
自动实现数据类型的转换,并且可以防止SQL注入;
2.${}实现的是sql语句的直接拼接,不做数据类型转换,需要自行判断数据类型,不能防止SQL注入;
3.在某些特定情况下必须使用${},如:在分表存储的情况下,对哪张表的查询是不确定的,也就是sql语句不能写
死,表明是动态的,查询条件是固定的,此时表明只能使用${}方式进行字符串拼接,这样:slect * from ${tableName}
where id = #{id}
总结:#{}占位符,用于参数传递; ${}用于SQL拼接
1. 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致
2.使用通用Mapper时,可以通过@Column注解设置
3.如果进行自定义查询,可以通过@Result进行设置
【了解】4.如果使用的xml配置,通过<resultMap>进行配置
1.使用通用Mapper的Criteria进行like语句的拼凑
2.使用#{}占位符方式,参数前后拼凑%。(select * from t_user where username like #{username} ,username数据
为"%jack%")
【了解】3.使用${}字符串拼接方式,可能引发sql注入问题:select * from t_user where username like
'%${username}%'
Dao接口在使用时,MyBatis创建接口对应的代理类。
在调用对应的方法时,执行的是代理类对应的方法。
代理类的方法上添加的注解完成增删改查的操作,如果是查询将结果封装到方法返回值类型声明的对象中。
不能重载的,
因为是全限定名+方法名的必须唯一。
使用第三方分页助手:PageHelper
使用方式:
在将要执行查询sql语句之前使用分页助手:PageHelper.startPage(pageNum:页码, pageSize:每页显示数量);
使用MyBatis插件(也称为拦截器)机制,对需要使用分页的功能进行增强。也就是重写SQL,根据不同的数据库生
产不同的分页语句。
Mysql生成limit语句,Oracle借助rownum生产对应子查询语句。
提供POJO和表之间的映射关系,查询结果就可以完成封装。
1.使用通用Mapper,需要在POJO上字段上使用@Column注解
2.如果是自定义查询,需要通过Dao接口里使用@Result注解
3.如果是xml,需要使用<resultMap>配置映射关系
动态SQL标签主要是基于XML进行配置的
不过注解也支持部分动态标签,@Select("<script> select * from user where 1=1 <if test='username != null '> and
username = #{username} </if> </script>")
Hibernate是全自动的ORM框架,也就是使用hibernate不用编写任何SQL语句。关联对象直接调用对应方法,可以自
动完成数据的查询。
MyBatis封装了JDBC基本操作,但仍需要编写SQL语句,也称为半自动ORM框架。使用通过Mapper可以简化
MyBatis单表操作,多表仍需要自己编写SQL语句。
Mybatis的缓存机制分为一级缓存和二级缓存
1.一级缓存:一级缓存的作用域是sqlSession会话级,相当于JDBC的Connection连接。一级缓存默认开启,用户不
能手动配置。当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓
存(内存),第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率;
2.二级缓存:二级缓存的作用域为同一个mapper的namespace,是跨sqlSession的,同一个namespace中不同的查
询SQL可以从二级缓存中命中。二级缓存默认关闭,但是可以通过配置进行开启。
二级缓存的对象必须序列化,例如:User对象必须实现Serializable接口。
Mybatis中,执行select时,查询数据会被缓存;当执行insert、update、delete等操作的时候,缓存则会被清除
resultType和resultMap功能类似 ,都是返回对象信息 ,但是resultMap要更强大一些 ,可自定义。因为resultMap
要配置一下,表和类的一一对应关系,所以说就算你的字段名和你的实体类的属性名不一样也没关系,都会给你映
射出来,但是,resultType就比较鸡肋了,必须字段名一样,比如说 cId和c_id 这种的都不能映射 。
namespace用于标识不同的XML配置文件。这样不同xml文件中sql语句的id相同也不会有冲突。
注解开发没有类似要求,只要保证接口全限定名不同即可(包+类名)
不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复。
MyBatis通过namespace+id来进行不同XML标识。
在xml配置文件,根据数据的不同,动态拼凑对应的SQL语句。
例如:
<if>用于处理条件成立时显示部分SQL语句
<where> 如果有条件就显示 where 子句,如果没有条件则不显示。
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象
proxy会拦截接口方法,转而执行接口方法所对应的MappedStatement所代表的sql,然后将sql执行结果返回。
MappedStatement解释:MappedStatement维护了一条<select|update|delete|insert>节点的封装,包括了传入参数映射
配置、执行的SQL语句、结果映射配置等信息。如以下一个<select/>节点
<select id="selectAuthorLinkedHashMap" resultType="java.util.LinkedHashMap">
select id, username from author where id = #{value}
</select>
Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。
Spring为不同的层都提供的企业级解决方案:
web层:spring mvc
service层:spring
dao层:JDBCTemplate
Spring的核心思想是IoC(控制反转)和AOP(面向切面编程)
IoC:Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。Ioc意味着将你设计好的对象交给容
器控制,而不是new。
IoC 控制反转,指将对象的创建权,反转到Spring容器
AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想。在程序运行的时候,动态地将代码
切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。
基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,对原有业务方法进行增强 !
1.方便解耦,简化开发 (高内聚低耦合)
Spring就是一个大工厂(容器),用于创建对象(bean)和维护对象间的依赖关系。
2.AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能.
声明式事务的支持 ,只需要通过配置就可以完成对事务的管理,而无需手动编程
3.方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
4.方便集成各种优秀框架
Spring支持各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)
5.降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降
低
1.基于XML配置
在XML文件中通过<bean>元素定义Bean,如:<bean class="com.czxy.UserService">
2.基于注解配置
在Bean实现类处通过标注@Component或衍型类(@Repository、@Service及@Controller)定义Bean
3.基于Java类配置
在标注了@Configuration的Java类中,通过在类方法上标注@Bean定义一个Bean。方法必须提供Bean的实例化逻
辑
1.在指定类中添加指定注解,配置类添加@ComponentScan注解进行包扫描,就可以完成bean的配置。
2.相关注解
@Component 通用组件类
@Controller 用于配置web层的controller类
@Service 用于配置service层的service类
@Repository 用于配置dao层dao类
@Bean 用于配置第三方实例,只能修饰方法。
1.Spring组件扫描:
在spring的配置类中使用@ComponentScan(basePackages = "com.czxy")可以扫描com.czxy包以及子包下添加了指定注解的类。
常见的注解有: @Component、@Service、@Controller、@Repository
2.SpringBoot扫描机制
1)默认扫描规则,SpringBoot中会自动扫描启动类所在包及其子包中的所有添加了指定注解类
2)使用@ComponentScan注解可以覆盖默认扫描规则。
两个注解都可以完成依赖注入功能。
1.@Autowired:
@Autowired : 默认是以byType按类型自动注入。
@Autowired + @Qualifier("名称"):将按照名称自动注入
2.@Resource:
@Resource() 如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称注入,
如果注解写在setter方法上默认取属性名进行注入。
当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就
只会按照名称进行装配。
@Resource(name="") 将按照名称自动注入
事务就是业务中的一组操作,要么全部成功,要么全部失败
Spring通过平台事务管理器(PlatformTransactionManager)进行事务管理
事务管理器通过事务定义(TransactionDefinition)进行具体的事务操作。
事务定义通过4方面对事务进行详细描述
1.readOnly:是否只读
2.timeout:超时时间
3.isolationLevel:事务隔离级别,隔离级别4种:读未提交、读已提交、可重复读、串行化
4.propagationBehavior:传播行为,共7种,常见的有:必须有事务 PROPAGATION_REQUIRED、每次必须新的
PROPAGATION_REQUIRES_NEW
DI:Dependency Injection 依赖注入,在Spring框架创建Bean对象时,动态的将依赖对象注入到Bean组件
IoC 控制反转,指将对象的创建权,反转到Spring容器 ,
DI 依赖注入,指Spring创建对象的过程中,将对象依赖属性通过配置进行注入
DI依赖注入不能单独存在,必须在IoC控制反转的基础上才能完成。
代理模式:分为静态代理、JDK动态代理、cglib代理
1.静态代理
代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的引用,实际执行时通过调用代理类的
方法、实际执行的是被代理类的方法。
2.jdk动态代理:必须有接口和实现类(目标类),通过工具类Proxy生产接口对应的代理类,从而对目标类进行增
强。
3.Cglib代理:Cglib代理生成的代理类是目标类的子类,所以目标类不能使用final修饰。
AOP
Spring AOP通过代理的方式,对目标类进行增强。
Spring aop底层默认使用JDK动态代理,通过配置可以修改成cglib代理。
1.目标类(target):需要被增强的类。
2.连接点(Joinpoint):可能被增强的点,目标类中的所有方法。
3.切入点(Pointcut):将会被增强的连接点,目标类中被增强的方法。
4.通知/增强(Advice):对切入点增强的内容。增强的内容通常以方法的形式体现的。增强执行的位置不同,称呼
不同。
5.切面(Aspect):通知和切入点的结合。一个通知对应一个切入点就形成一条线,多个通知对应多个切入点形成
多条线,多条线形成了一个面,我们称为切面。
6.织入(Weaving): 生成切面并创建代理对象的过程。(将通知和切入点的结合,并创建代理对象的过程)
7.引介(Introduction):一种特殊的增强
MVC设计模式: Model-View-Controller简写。
MVC是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的设计方法。它把软件系统分为三个基
本部分:模型(Model)、视图(View)和控制器(Controller)。
控制器Controller:对请求进行处理,负责选择视图;
视图View:用户与程序交互的界面;
模型Model:用于业务处理
SpringMVC是一个MVC框架,springmvc的工作流程:
1. 发送请求:在浏览器输入请求路径,发送请求,前端控制器连接所有的请求。
2. 获得处理器:核心控制器(DispatcherServlet)接收到请求,通过处理器映射器(handlerMapping)获得对应的
处理器(Handler)
大白话:根据请求路径获得对应的controller。
3. 执行处理器:通过处理器适配器(HandlerAdapter)执行处理器(Handler),并返回视图模型对象
(ModelAndView)
大白话:执行controller方法。如果方法返回的字符串,底层也会转换成ModelAndView。
4. 解析视图:通过视图解析器(ViewResolver)解析ModelAndView中的视图,将逻辑视图解析成真正的视图。
5. 渲染视图:将Model中的数据渲染到视图(View)中
6. 响应结果
大白话:将模型数据(查询结果)渲染到jsp页面中,并将处理结果响应给浏览器。
流程图:
Spring框架的核心控制器(前端控制器)是DispatherServlet
他的核心功能就是分发请求,请求会被分发给对应处理的类handler。
使用@ResponseBody注解,将返回json数据。
1.如果在方法使用该注解,当前方法返回json数据。
2.如果在类上使用该注解,当前类中所有的方法,都将返回json数据。
优点:
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用
缺点:
1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据
库,以此获取相应的数据,如今却必须通过中间层来完成。
2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设
计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
1.地址栏参数或普通表单请求,如:age=18&gender=man,SpringMVC方法参数需要使用@RequestParam("参数
名")获得参数值。
2.提交json类型数据,SpringMVC 方法参数需要使用@RequestBody 将数据封装到java对象中。
3.路径占位符:如 http://localhost:8080/user/findById/1,使用@RequestMapping("findById/{id}")匹配路径,使用
@PathVariable("id")获得对应的参数值。
4.文件上传,修改表单请求为"multipart/form-data"方式,SpringMVC采用MultipartFile参数类型接
收数据
其实问题相当于SpringMVC的执行流程,DispatcherServlet用来处理所有的HTTP请求和请求响应,回答SpringMVC的执行流程即可。
@Controller 是@Component的派生注解,功能就是将被修饰的类添加到spring容器。
字面意思,用于修饰Controller层的组件,提高可读性。
修饰方法,将请求路径映射到Controller对应的处理方法上。
修饰类,给请求路径添加访问前缀(二级路径)
使用 @ResponseBody 注解将Java集合转换json数组,并将结果响应给浏览器。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。