加载配置:配置有两种形式,一种是XML配置文件,另一种是Java代码的注解.MyBatis将SQL的配置信息加载成为一个个的MappedStatement对象(包括了传入参数映射配置,执行的SQL语句,结果映射配置),并将其存储在内存中.
SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以使Map,JavaBean或者基本数据类型),MyBatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数.
SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果.
结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap,JavaBean或者基本数据类型,并将最终结果返回
2、列举MyBatis的常用API及方法
SqlSessionFactoryBuilder该对象负责根据MyBatis配置文件SqlMapConfig.xml构建SqlSessionFactory实例.
SqlSessionFactory该对象负责创建SqlSession对象实例
SqlSession该对象包含了所有执行SQL操作的方法,用于执行SQL操作的方法,用于执行已映射的SQL语句.
3、JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
解决: Mybatis自动将java对象映射至sql语句。
对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象。
4、MyBatis编程步骤是什么样的?
-
创建SqlSessionFactory
-
通过SqlSessionFactory创建SqlSession
-
通过sqlsession执行数据库操作
-
调用session.commit()提交事务
-
调用session.close()关闭会话
5、简单的说一下MyBatis的一级缓存和二级缓存?
Mybatis首先去缓存中查询结果集,如果没有则查询数据库,如果有则从缓存取出返回结果集。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
Mybatis的二级缓存即查询缓存,它的作用域是一个mapper的namespace,即在同一个namespace中查询sql可以从缓存中获取数据。二级缓存是可以跨SqlSession的。
6、对于Hibernate和MyBatis的区别与利弊,谈谈你的看法
-
MyBatis非常简单易学,与Hibernate相对较复杂,门槛较高;
-
二者都是比较优秀的开源产品;
-
那MyBatis的灵活性将比Hibernate更适合;
-
系统数据处理量大,性能要求极为苛刻,这往往意味着我们必须通过经过高度优化的SQL语句(或存储过程)才能达到系统性能设计指标.在这种情况下MyBatis会有更好的可控性和表现;
7、MyBatis中使用#和$书写占位符有什么区别?
#是预编译处理,$是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;Mybatis在处理${}时,就是把${}替换成变量的值。使用#{}可以有效的防止SQL注入,提高系统安全性。
8、解释一下MyBatis中命名空间(namespace)的作用。
项目中可能存在大量的SQL语句,这时候为每个SQL语句起一个唯一的标识(ID)就变得并不容易了。为了解决这个问题,在MyBatis中,可以为每个映射文件起一个唯一的命名空间,这样定义在这个映射文件中的每个SQL语句就成了定义在这个命名空间中的一个ID。只要我们能够保证每个命名空间中这个ID是唯一的,即使在不同映射文件中的语句ID相同,也不会再产生冲突了。
9、MyBatis中的动态SQL是什么意思?
对于一些复杂的查询,我们可能会指定多个查询条件,但是这些条件可能存在也可能不存在,例如在58同城上面找房子,我们可能会指定面积、楼层和所在位置来查找房源,也可能会指定面积、价格、户型和所在位置来查找房源,此时就需要根据用户指定的条件动态生成SQL语句。如果不使用持久层框架我们可能需要自己拼装SQL语句,还好MyBatis提供了动态SQL的功能来解决这个问题。MyBatis中用于实现动态SQL的元素主要有:- if- choose / when / otherwise- trim- where- set- foreach。下面是映射文件的片段。
<select id="foo" parameterType="Blog" resultType="Blog"> select * from t_blog where 1 = 1 <if test="title != null"> and title = #{title} </if> <if test="content != null"> and content = #{content} </if> <if test="owner != null"> and owner = #{owner} </if> </select>
10、Spring有哪些优点?
轻量级:Spring在大小和透明性方面绝对属于轻量级的,基础版本的Spring框架大约只有2MB。
控制反转(IOC):Spring使用控制反转技术实现了松耦合。依赖被注入到对象,而不是创建或寻找依赖对象。
面向切面编程(AOP): Spring支持面向切面编程,同时把应用的业务逻辑与系统的服务分离开来。
容器:Spring包含并管理应用程序对象的配置及生命周期。
MVC框架:Spring的web框架是一个设计优良的web MVC框架,很好的取代了一些web框架。
事务管理:Spring对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。
异常处理:Spring提供一个方便的API将特定技术的异常(由JDBC, Hibernate, 或JDO抛出)转化为一致的、Unchecked异常
11、Spring中AOP的应用场景、Aop原理、好处?
aop指的是面向切面编程,就是在不修改源代码的基础上,通过预编译或者运行期动态代理的方式,给程序动态统一的添加功能的方式。aop可以对业务逻辑的各个部分进行隔离,降低了程序的耦合度,一般有大量相同功能,重复代码比较多的时候用。比如说管理事务、权限校验等
原理:AOP是面向切面编程,是通过动态代理的方式为程序添加统一功能,集中解决一些公共问题。
优点:
1.各个步骤之间的良好隔离性耦合性大大降低
2.面向切面编程,扩展功能不是修改源代码实现
12、Spring中IOC的作用与原理?对象创建的过程。
IOC控制反转也可以叫依赖注入ID,以前我们都是自己new对象,现在创建和管理对象都交给spring容器来做,现在只要做好配置,ioc容器通过注入解决依赖关系。
比如有一个类,在类里面有方法(不是静态的方法),调用类里面的方法,创建类的对象,使用对象调用方法,创建类对象的过程,需要new出来对象。IOC把对象的创建交给spring配置创建类对象。
IOC底层原理使用技术:
xml配置文件
dom4j解决xml
工厂设计模式
反射
13、有哪些不同类型的IOC(依赖注入)
构造器依赖注入:构造器依赖注入在容器触发构造器的时候完成,该构造器有一系列的参数,每个参数代表注入的对象。
Setter方法依赖注入:首先容器会触发一个无参构造函数或无参静态工厂方法实例化对象,之后容器调用bean中的setter方法完成Setter方法依赖注入
14、Spring常见创建对象的注解?
@Component@Controller@ Service@ Repository
15、Spring中用到的设计模式
简单工厂、工厂方法、单例模式、适配器、包装器、代理、观察者、策略、模板方法
16、Spring的优点?
-
降低了组件之间的耦合性 ,实现了软件各层之间的解耦
-
可以使用容易提供的众多服务,如事务管理,消息服务等
-
容器提供单例模式支持
-
容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
-
容器提供了众多的辅助类,能加快应用的开发
-
spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
-
spring属于低侵入式设计,代码的污染极低
-
独立于各种应用服务器
-
spring的DI机制降低了业务对象替换的复杂性
-
Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring 的部分或全部
17、Spring Bean的作用域之间有什么区别?
singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。
request:每一次http请求会产生一个新的Bean实例。
Session:确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。
18、Spring管理事务有几种方式?
有两种方式:
编程式事务,在代码中硬编码。(不推荐使用)
声明式事务,在配置文件中配置(推荐使用)声明式事务又分为两种:
-
基于XML的声明式事务
-
基于注解的声明式事务
19、spring中的核心类有那些,各有什么作用?
BeanFactory:产生一个新的实例,可以实现单例模式
BeanWrapper:提供统一的get及set方法
ApplicationContext:提供框架的实现,包括BeanFactory的所有功能
20、说SpringIOC,SpringAOP?
SpringIOC ,其实就是依赖注入、控制反转。相当于把每个bean与bean之间的关系交给第三方容器管理。而这个容器就是spring
SpringAOP 面向切面的编程,或AOP是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。SpringAop 就是用 Java的动态代理
21、Spring的底层实现机制是什么
使用Demo4j(解析XML)+Java反射机制
Demo4j 其实就是解析XML。使用反射机制实例化bean。
22、SpringAOP用到了什么代理
JDK动态代理:对实现了接口的类生成代理
CGLib代理机制:对类生成代理
23、动态代理与静态代理区别?
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
24、Spring注入有那些方式?
Set注入
构造器注入
静态工厂的方法注入
实例工厂的方法注入
25、Spring有那些注解?
@Autowired(按类型注入)
@Service(标示为注入为服务层)
@Resource(按名称注入)
@Controller(标识控制器bean id)
@RequestMapping(表示映射URL路径)
26、简述Spring的优缺点?
1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦
2.可以使用容易提供的众多服务,如事务管理,消息服务等
3.容器提供单例模式支持
4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
5.容器提供了众多的辅助类,能加快应用的开发
6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
7.spring属于低侵入式设计,代码的污染极低
8.独立于各种应用服务器
9.spring的DI机制降低了业务对象替换的复杂性
10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部
缺点:
使用到了大量反射机制。反射机制非常占内存
27、Bean的调用方式有哪些?
有三种方式可以得到Bean并进行调用:
//使用BeanWrapper HelloWorld hw=new HelloWorld(); BeanWrapper bw=new BeanWrapperImpl(hw); bw.setPropertyvalue(”msg”,”HelloWorld”); system.out.println(bw.getPropertyCalue(”msg”)); //使用BeanFactory InputStream is=new FileInputStream(”config.xml”); XmlBeanFactory factory=new XmlBeanFactory(is); HelloWorld hw=(HelloWorld) factory.getBean(”HelloWorld”); system.out.println(hw.getMsg()); //使用ApplicationConttext ApplicationContext actx=new FleSystemXmlApplicationContext(”config.xml”); HelloWorld hw=(HelloWorld) actx.getBean(”HelloWorld”); System.out.println(hw.getMsg());
28、Spring里面如何配置数据库驱动
//使用”org.springframework.jdbc.datasource.DriverManagerDataSource”数据源来配置数据库驱动。示例如下: <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>org.hsqldb.jdbcDriver</value> </property> <property name="url"> <value>jdbc:hsqldb:db/appfuse</value> </property> <property name="username"><value>abc</value></property> <property name="password"><value>abc</value></property> </bean>
29、如何在Web项目中配置Spring的IoC容器
如果需要在Web项目中使用Spring的IoC容器,可以在Web项目配置文件web.xml中做出如下配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
30、如何在Web项目中配置Spring MVC
要使用Spring MVC需要在Web项目配置文件中配置其前端控制器DispatcherServlet,如下所示:
<servlet> <servlet-name>example</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping>
31、springMVC的流程?
-
用户发送请求至前端控制器DispatcherServlet
-
DispatcherServlet收到请求调用HandlerMapping处理器映射器。
-
处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
-
DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
-
执行处理器(Controller,也叫后端控制器)。
-
Controller执行完成返回ModelAndView
-
HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
-
DispatcherServlet将ModelAndView传给ViewReslover视图解析器
-
ViewReslover解析后返回具体View
-
DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
-
DispatcherServlet响应用户
32、Springmvc的优点
-
它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是 java组件.并且和Spring提供的其他基础结构紧密集成.
-
可以任意使用各种视图技术,而不仅仅局限于JSP
-
支持各种请求资源的映射策略
-
它应是易于扩展的
33、SpringMVC与Struts2的主要区别?
springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
springmvc是基于方法开发,传递参数是通过方法形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request对象内容进行解析成方法形参,将响应数据和页面封装成ModelAndView对象,最后又将模型数据通过request对象传输到页面。 Jsp视图解析器默认使用jstl。
34、SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决
是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的
解决方案是在控制器里不要定义static的全局变量
35、SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代
一般用@Conntroller注解,表示是表现层,不能用别的注解代替.
36、@RequestMapping注解用在类上面有什么作用
用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
37、怎么样把某个请求映射到特定的方法上面
直接在方法上面加上注解@RequestMapping,并且在这个注解里面写上要拦截的路径
38、如果在拦截请求中,我想拦截get方式提交的方法,怎么配置
可以在@RequestMapping注解里面加上method=RequestMethod.GET
39、如果在拦截请求中,我想拦截提交参数中包含"type=test"字符串,怎么配置
可以在@RequestMapping注解里面加上params="type=test"
40、我想在拦截的方法里面得到从前台传入的参数,怎么得到
直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样
41、如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象
直接在方法中声明这个对象,SpringMvc就自动会把属性赋值到这个对象里面
42、怎么样在方法里面得到Request,或者Session
直接在方法的形参中声明request,SpringMVC就自动把request对象传入
43、SpringMvc中函数的返回值是什么.
返回值可以有很多类型,有String, ModelAndView,当一般用String比较好
44、SpringMvc怎么处理返回值的
SpringMvc根据配置文件中InternalResourceViewResolver的前缀和后缀,用前缀+返回值+后缀组成完整的返回值
45、SpringMVC怎么样设定重定向和转发的
在返回值前面加"forward:"就可以让结果转发,譬如"forward:user.do?name=method4"
在返回值前面加"redirect:"就可以让返回值重定向,如"redirect:http://www.baidu.com"
46、SpringMvc用什么对象从后台向前台传递数据的
通过ModelMap对象,可以在这个对象里面用put方法,把对象加到里面,前台就可以通过el表达式拿到
47、SpringMvc中有个类把视图和数据都合并的一起的,叫什么
叫ModelAndView
48、怎么样把ModelMap里面的数据放入Session里面
可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key
49、SpringMvc怎么和AJAX相互调用的
通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象
具体步骤如下:
-
加入Jackson.jar
-
在配置文件中配置json的映射
-
在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解
50、当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理
要加上@ResponseBody注解
51、SpringMvc里面拦截器是怎么写的
有两种写法,一种是实现接口,另外一种是继承适配器类,然后在SpringMvc的配置文件中配置拦截器即可:
<!-- 配置SpringMvc的拦截器 --> <mvc:interceptors> <!-- 配置一个拦截器的Bean就可以了 默认是对所有请求都拦截 --> <bean id="myInterceptor" class="com.et.action.MyHandlerInterceptor"></bean> <!-- 只针对部分请求拦截 --> <mvc:interceptor> <mvc:mapping path="/modelMap.do" /> <bean class="com.et.action.MyHandlerInterceptorAdapter" /> </mvc:interceptor> </mvc:interceptors>
52、如何解决POST请求中文乱码问题,GET的又如何
在web.xml中加入如下过滤器:
<filter> <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
以上可以解决post请求乱码问题。对于get请求中文参数出现乱码解决方法有两个:
修改tomcat配置文件添加编码与工程编码一致,如下:
<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
另外一种方法对参数进行重新编码:
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码