Mybatis和SpringMVC相关问题

一、什么是SpringMVC?

SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级web框架,通过把Model、view、Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发、减少出错,方便组内开发人员之间的配合。

二、SpringMVC的工作原理

1.用户发送请求至前端控制器DispatcherServlet(前端控制器)。
2.DispatcherServlet收到请求后,调用Handler Mapping处理器映射器,请求获得Handler(消息处理);
3.处理器映射器根据请求URL找到具体的处理器,生成处理器对象以及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
4.DispatcherServlet调用HandlerAdapter处理器适配器;
5.HandlerAdapter经过适配调用具体处理器(Handler,也叫后端控制器);
6.Handler执行完成返回ModelAndView;
7.HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
8.DispatcherSelvert将ModelAndView传给ViewResolver视图解析器进行解析;
9.ViewReslover解析后返回具体的View;
10.DispatcherServlet对View进行渲染视图(就是将模型数据填充至试图中)。
11.DispatcherServlet响应用户。

三、SpringMVC常用的注解有哪些

1.RequsetMapping:可用于处理请求url映射的注解,可用于类或方法上;用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
2.RequestBody:注解实现接受http请求的json数据,将json转换为Java对象。
3.ResponseBody:注解实现将Controller方法返回对象转换为json对象响应给用户。

四、@Controller和@RestController的区别?

都是用来表示Spring某个类是否可以接受HTTP请求。@RestController注解相当于@RequsetBody和@Controller合在一起的作用。
如果只是使用@RestController注解Controller类,则Controller类中的方法无法返回jsp页面,或者html。配置的视图解析器。InternalResourceViewResolver不起作用,返回的内容就是return里的内容。
如果要返回指定页面,则需要使用@Controller配合视图解析器才行;如果需要返回JSON,XML内容到页面,则需要在对应方法上加上@ResponseBody注解。

五、Mybatis中的#和$区别

Mybatis的SQL XML映射文件中,有关参数传递方法由两种,分别是#{}和${}。

select * from user where name = "yzz";
select * from user where name = #{name};
select * from user where name = ${name};

动态SQL是Mybatis的特性之一,也是它用于其他ORM框架的一个重要原因。Mybatis在对SQL语句进行预编译之前,会对sql进行动态解析,解析为一个Boundsql对象,也是在此处对动态SQL进行处理的。再动态SQL解析阶段,#{}和${}会有不同的表现。
BoundSql更像是一个中转站,mybatis在执行一次CRUD操作过程中产生的中间数据的集中点。
#{}在动态解析的时候,会解析成一个参数标记符。

select * from user where name = #{name};
select * from user where name = ?;

${}在动态解析的时候,会将我们传入的参数当作String字符串填充到我们的语句中。

select * from user where name = ${name};
select * from user where name = "yzz";

所以,${}变量替换阶段在动态SQL解析阶段,而#{}变量的替换的替换是在DBMS中。
#{}变量的替换的替换是在DBMS,会导致Mybaits创建PreparedStatement参数并安全的设置参数,这样就避免的sql注入问题。
#{}方式能够很大程度上防止sql注入。¥{}方式一般用于传入数据库对象,例如传入表名。
SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。
在实际开发中,尽量使用#{}方式

六、当实体类中的属性名和表中的字段名不一样怎么办?

1.通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
2.通过来映射字段名和实体类属性名的一一对应关系。

七、模糊查询的like语句怎么写

1.在Java代码中添加sql通配符。

String wildcardname = "%smi%";
list<name> names = mapper.selectlike(wildcardname);

<select id = "selcetlike">
select * from foo where bar like #{value}
</select>

2.在sql语句中拼接通配符,会引起sql注入。

String wildcardname = "smi";
list<name> names = mapper.selectlike(wildcardname);

<select id = "selectlike">
select * from foo where bar like "%"${value}"%"
</select>

八、Mybatis实现一对一有几种方式?具体怎么操作?

1.有联合查询和嵌套查询,联合查询时几个表联合查询,只查询一次,通过在resultMap里面配置association节点配置一对一的类就可以完成;
2.嵌套查询是先查一个表,根据这个表里面的结果的外键id,去在另外一个表里查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。

九、Mybatis实现一对多有几种方式,怎么操作的的?

两种。
1.联合查询:几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成;
2.嵌套查询:先查一个表,根据这个表里面的结果的外键id,去在另外一个表里面查询数据,也是通过配置collection,但另外一个表查询要通过select节点配置。

十、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载LazyLoadingEnabled = true or false。
它的原理是,使用CGLIB创建目标对象的代理对象,调用目标方法时,进入拦截器方法,比如调用a.getb().getName(),拦截器invoke()方法发现a.getb()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有了值,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
不光是Mybatis,包括Hibernate支持延迟记载的原理都是一样的

十一、什么是Mybatis的接口绑定?有哪些实现方式?

接口绑定,就是在Mybatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调用接口方法就可以,这样比起原来的SqlSession提供的方法更灵活的选择和设计。
接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select、@update等注解,里面包含SQL语句来绑定;另外一种就是通过XML里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。当sql语句比较简单的时候,用注解绑定,当Sql语句比较复杂时候,用xml绑定,一般用xml绑定的比较多。

十二、使用Mybatis的mapper接口调用有哪些要求?

1.mapper接口方法名和mapper.xml中定义的每个sql的id相同;
2.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同;
3.Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;
4.Mapper.xml文件中的namespace即是mapper接口的类路径。

十三、Mybaits中的一级缓存和二级缓存?

缓存:是指将程序或系统调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。
1.一级缓存
SqlSession时Mybatis最重要的构建之一,可以简单的认为Mybatis一系列的配置的目的是生成类似JDBC生成的Connection对象的SqlSession,这样才能与数据库开启沟通,通过SQL Session可以实现增删改查。
它指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域内,该区域的结构是一个Map,在同一个SqlSession中,执行相同的查询sql,第一次会去数据库中查询,并写道缓存中。当执行SQL查询中发生了增删改的操作,Mybatis会把SqlSession的缓存清空。一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,不想使用一级缓存,可以把缓存以及缓存的范围指定为STATEMENT。

<setting name = "localCacheScope" value = "STATEMENT"> //不建议修改

一级缓存实际上就是使用PerpetualCache维护的,PerpetualCache实现原理内部是通过一个简单的HashMap来实现,没有其他限制。
2.二级缓存
它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其内存,但是其中缓存的是数据而不是对象,所以从二级缓存再次查询出的结果的对象与第一次存入的对象是不一样的
3总结:
一级缓存:Sqlsession级别的缓存,缓存的是对象,当发生修改、更新等操作一级缓存会清空。
二级缓存:SqlSessionFactory级别的缓存,缓存的是数据,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,当命中二级缓存时,通过存户的数据构造对象返回。
查询数据的流程:二级缓存>一级缓存>数据缓存

十四、SQL注入问题

SQL注入指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击所要的操作,主要原因时程序没有细致的过滤用户输入的数据,导致非法数据请入系统。
1.数字型注入:
假设存在一条URL为:HTTP://www.aaa.com/test.php?id=1可以对后台的SQL语句猜测为:

SELECT * FROM table WHERE id = 1

在输入框中输入and 1 = 1
SQL语句变为:SELECT * FROM table WHERE id = 1 and 1 = 1语句正确,执行正藏,返回的数据与原始请求无关。
2.字符型注入
当输入参数为字符串时,则可能存在字符型注入漏洞。数字型与字符型注入最大的区别在于:数字型不需要单引号闭合,而字符型一般需要单引号闭合。
字符型注入最关键的时如何闭合SQL语句以及注释多余的代码:
假设后台的SQL语句为:

SELECT * FROM table WHERE username = 'admin'

输入:admin’ and 1 = 1 –
注意在admin后有一个单引号,用于字符串的闭合,最后还有个注释符 --。
SQL语句变为:

SELECT * FROM table WHERE username = 'admin' and 1 = 1 -- 

3.其他类型
POST注入:注入字段在POST数据中
Cookie注入:注入字段在Cookie数据中
延时注入:使用数据库延时特性注入
base64注入:注入的字符串需要经过base64加密
4.预防SQL注入的方法

严格限制Web应用的数据库的操作权限,给连接数据库的用户提供满足需要的最低权限,最大限度地减少注入攻击对数据库地危害。
校验参数的数据格式是否合法(可以使用正则表达式或特殊字符进行判断)
对进入数据库地特殊字符进行转义处理,或编码转换。
预编译SQL(Java中使用PrepaerdStatement),参数化查询方式,避免SQL拼接。
报错信息不要包含SQL信息输出到Web页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值