对Spring的理解
spring是一个轻量级的开源框架,贯穿持久层、业务逻辑层、控制层。让每个功能模块均可以独立的分开,下降耦合度,提升代码复用度。spring经过控制反转下降耦合性,一个对象的依赖经过被动的注入而非主动的new。spring还包括面向切面、MVC整合等等。以上是我对spring的浅显认识。html
Spring IOC的理解
控制反转,指由Spring来控制对象的生命周期和对象间的关系。之前对象的建立时机是由本身把握的,开发人员主动建立对象,如今由IOC容器建立,而后注入。全部的类都会在IOC容器中注册,告诉spring你是什么,你须要什么,spring容器在合适的时机将你所须要的东西给你,控制对象生命周期的再也不是引用它的对象而是spring容器。前端
spring先加载xml文件,Bean先在spring容器中注册,而后会进行初始化Bean,再将Bean存到容器的缓存区(Map),谁须要就给它注入,并且缓存区的对象还在,一直在,这属于单例,直到关闭spring。(scope见下面)java
DI:依赖注入,动态的向某个对象注入它所须要的对象。spring
SpringAOP(拦截器的实现原理)
http://www.cnblogs.com/xiaolovewei/p/7919763.htmlsql
Spring事务
http://www.cnblogs.com/xiaolovewei/p/9418874.html数据库
Spring 中的scope ,也就是Bean的做用域
scope有Singleton、Prototype、request、session、global session。其中主要的是singleton和prototype。编程
singleton指的是IOC容器中只存在一个实例,全部对该对象的引用都要共享该实例。该对象自从第一次被建立之后,直到容器退出才会被销毁。就像上面说的,容器中有一个缓存区(MAP)保管这个单例。设计模式
prototype:IOC容器接收到对该对象的请求时,就会新建一个对象实例给对方。返回给对方之后,IOC容器就不在持有该对象的引用,也就是IOC只负责建立该对象实例,置于销毁,就无论了。缓存
request:XmlWebApplicationContext会为每一个HTTP请求建立一个对象,当请求结束,该对象也就被销毁。安全
session:会为每一个session建立一个对象,存活时间为session
Spring常见建立对象的注解?
@Component@Controller@ Service@ Repository <context:compenent-scan base-package="">
xml:<bean>无参构造器、静态工厂(get方法)。
对象(属性)注入的方式
xml:set方法(<property name value>)、构造器(<constructor-arg name value>)
注解:Autowired、Resource
Spring中用到的设计模式
答:简单工厂、工厂方法、单例模式、适配器、包装器、代理、观察者、策略、模板方法
Spring的优势?
答:1.下降了组件之间的耦合性 ,实现了软件各层之间的解耦
2.可使用容易提供的众多服务,如事务管理,消息服务等
3.容器提供单例模式支持
4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
5.容器提供了众多的辅助类,能加快应用的开发
6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
7.spring属于低侵入式设计,代码的污染极低
8.独立于各类应用服务器
9.spring的DI机制下降了业务对象替换的复杂性
10.Spring的高度开放性,并不强制应用彻底依赖于Spring,开发者能够自由选择spring 的部分或所有
Spring 的自动装配
https://www.cnblogs.com/xiaolovewei/p/9424804.html
byName/byType/constructor
咱们在xml中注入对象,使用<property>属于手动装配,自动装配不须要写这个。如byName,类中对象的属性名与bean的名字同样(id)则直接注入。
Autowired和Resource
https://www.cnblogs.com/xiaolovewei/p/9424856.html
Autowired默认使用byType,单例没问题,Spring的注解。若是想使用byName,则和Qualifier("")一块儿使用。
Resource(name="")默认byName。J2EE的注解
Spring保证安全性
首先,Controller、Dao、service都是单例的,就有可能出现多线程的安全问题----有类成员变量,这样多线程访问就会使用到共享变量了。
避免:不要使用类成员变量,这样就不会有共享变量了。或者使用ThreadLocal
使用多例,scope="property"。这样每一个线程都有本身的对象,就不会出现问题。
SpringMVC理解
spring MVC 其实就是 spring 本身作了一套很合适的 controller层 框架。结合性更好。 这个东西的核心就是 Dispatcher(能够理解成一个servlet),根据配置映射的JSP文件路径进行跳转。controller层也可使用annotation(注解)的方式来描述。MVC的中的C。
SpringMVC流程(原理)
1 用户发送请求至前端控制器DispatcherServlet;
2 前端控制器调用处理器映射器HandlerMapping,处理器映射器根据URL找到具体的处理器(Handler,也就是Controller),并返回给前端控制器。
3 前端控制器经过处理器适配器HandlerAdapter调用处理器。
4 执行处理器(Controller),执行完后返回给前端控制器一个ModelAndView
5 前端控制器调用视图解析器ViewResolver解析视图,并返回View给前端控制器。
6 前端控制器渲染并显示视图。
SpringMVC优势
1. 能够任意使用各类视图技术,而不只仅局限于JSP
2. 支持各类请求资源的映射策略
3 .它应是易于扩展的
SpringMVC对请求的拦截方式
<servlet-mapping> 中的<url-pattern>/<url-pattern>。/表明拦截全部请求,包括静态资源。 .action拦截对应action结尾的路径,不会拦截静态资源。
对于/,解决静态资源不被拦截的方法:<mvc:resource location="/WEB-INF/js/" mapping="/js/**"> 全部对mapping的访问,都转到location位置。
<mvc:annotation-driven>
springmvc须要配置HandlerMapping、HandlerAdapter、ViewResolver。而<mvc:annotation-driven>会自动配置RequestMappingHandlerMapping和RequestMaappingHandlerAdapter。
MyBatis
MyBatis是一个优秀的持久层框架,它对jdbc的操做数据库的过程进行封装,使开发者只须要关注 SQL 自己,而不须要花费精力去处理例如注册驱动、建立connection、建立statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis经过xml或注解的方式将要执行的各类statement(statement、preparedStatemnt、CallableStatement)配置起来,并经过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
Mybatis解决jdbc编程的问题
一、 数据库连接建立、释放频繁形成系统资源浪费从而影响系统性能,若是使用数据库连接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据连接池,使用链接池管理数据库连接。
二、 Sql语句写在代码中形成代码不易维护,实际应用sql变化的可能较大,sql变更须要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
三、 向sql语句传参数麻烦,由于sql语句的where条件不必定,可能多也可能少,占位符须要和参数一一对应。
解决:Mybatis自动将java对象映射至sql语句,经过statement中的parameterType定义输入参数的类型。
四、 对结果集解析麻烦,sql变化致使解析代码变化,且解析前须要遍历,若是能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象,经过statement中的resultType定义输出结果的类型。
Mapper接口开发的一些规范
1.mapper.xml中的namespace和mapper接口类路径相同;
2.mapper.xml中的SQL对应的id与mapper接口的方法名相同;
3.mapper.xml中的每一个sql的parameterType和接口的输入参数类型相同;
4.mapper.xml中的每一个sql的resultType要与接口的返回参数类型相同
#{name}获取parameterType中的属性的值,若输入对象,name就是对应的字段,输入hashmap,name就是key。
resultType总结:
resultType中对象的字段名和查询出来的结果的字段名相同。
返回单个pojo对象要保证sql查询出来的结果集为单条,内部使用sqlsession.selectOne方法调用,mapper接口使用pojo对象做为方法返回值。
返回pojo列表表示查询出来的结果集可能为多条,内部使用sqlsession.selectList方法,mapper接口使用List<pojo>对象做为方法返回值。
resultMap
若是sql查询字段名和对象的属性名不一致,能够经过resultMap将字段名和属性名做一个对应关系 ,resultMap实质上还须要将查询结果映射到pojo对象中。

resultMap处理关联查询返回的结果
一对一:类中除了基本的属性,还包含其余对象,orders中含有User,使用association标签
<resultMap type="cn.itcast.mybatis.po.Orders" id="userordermap">
<!-- 这里的id,是mybatis在进行一对一查询时将user字段映射为user对象时要使用,必须写 -->
<id property="id" column="id"/>
<result property="user_id" column="user_id"/>
<result property="number" column="number"/>
<association property="user" javaType="cn.itcast.mybatis.po.User">
<!-- 这里的id为user的id,若是写上表示给user的id属性赋值 -->
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
一对多:类中除了基本的属性外,还包含对象的集合,orders中含有List<Orderdetail>。使用collection标签
<resultMap type="cn.itcast.mybatis.po.Orders" id="userorderdetailmap">
<id property="id"column="id"/>
<result property="user_id" column="user_id"/>
<result property="number" column="number"/>
<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
<id property="id" column="orderdetail_id"/>
<result property="items_id" column="items_id"/>
<result property="items_num" column="items_num"/>
</collection>
</resultMap>
多对多:User中包含List<Orders>,Orders中包含List<Orderdetail>。collection中嵌套collection。
MyBatis延迟加载
查询关联信息时(须要关联对象,要查关联表),首次查询只查询主要信息(单表查询),关联信息等用户获取时再查询(须要查询关联表),大大缓解了数据库压力。association和collection都具有延迟加载的功能。
这个跟 本身在作项目时同样,先查询单表,若是还须要其余表关联信息,再查询其余表。
sqlmapconfig.xml中
<settings>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--关闭积极加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--查询订单和建立订单的用户,使用延迟加载-->
<resultMap id="OrderAndUserLazyLoad" type="Orders">
<id column="id" property="id"/>
<result column="user_id" property="userId" />
<result column="number" property="number" />
<result column="createtime" property="createtime" />
<result column="note" property="note" />
<!--
select:要延迟加载的statement的id colunm:关联两张表的那个列的列名 -->
<association property="user" javaType="User" select="findUser" column="user_id">
<--select中就是延迟加载再去执行的sql-->
</association>
</resultMap>
<select id="findOrdersByLazyLoad" resultMap="OrderAndUserLazyLoad"> SELECT * FROM orders </select>
<select id="findUser" parameterType="int" resultType="User"> SELECT * FROM User WHERE id = #{value} </select>
从上面看,其实就是单表查询两次。
Mybatis缓存
Mybatis一级缓存的做用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将再也不从数据库查询,从而提升查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。当遇到增删改时会清空缓存。Mybatis默认开启一级缓存。
Mybatis二级缓存是多个SqlSession共享的,其做用域是mapper的同一个namespace,不一样的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将再也不从数据库查询,从而提升查询效率。当遇到增删改时会清空缓存。Mybatis默认没有开启二级缓存须要在setting全局参数中配置开启二级缓存。
#{}和${}的区别
#{}是预编译处理,${}是字符串替换。 Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值; Mybatis在处理${}时,就是把${}替换成变量的值。 使用#{}能够有效的防止SQL注入,提升系统安全性。
当实体类中的属性名和表中的字段名不同 ,怎么办 ?
1。查询语句中,给字段名取别名。
2.。resultMap
模糊查询like语句该怎么写?
1.在Java代码中写。string wildcardname = “%smi%”; list<name> names = mapper.selectlike(wildcardname);
2.Java代码中传入变量,SQL语句中拼接通配符,会引发SQL注入。select * from foo where bar like "%"${value}"%"
mapper如何传递多个参数
1.包装成pojo对象。
2.map
Mybatis的Xml映射文件中,不一样的Xml映射文件,id是否能够重复?
不一样的Xml映射文件,若是配置了namespace,那么id能够重复;若是没有配置namespace,那么id不能重复;毕竟namespace不是必须的,只是最佳实践而已。
一般一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工做原理是什么?Dao接口里的方法,参数不一样时,方法能重载吗?
Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串做为key值,可惟必定位一个MappedStatement,举例:com.mybatis3.mappers.StudentDao.findStudentById,能够惟一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。
Dao接口里的方法,是不能重载的,由于是全限名+方法名的保存和寻找策略。
Dao接口的工做原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所表明的sql,而后将sql执行结果返回。