一、 Struts1.x 4
1、 struts1优缺点,为什么要使用struts1 4
2、 Struts1核心组件 4
3、 Strust1请求处理流程 工作原理 4
4、 Struts1线程安全问题 4
5、 Struts1 它解决了什么问题? 4
6、 Struts1的框架的结构是什么? 4
7、 struts 1如何实现mvc 5
8、 DispatchAction与动态form 5
9、 为什么要使用动态form 5
二、 Hibernate面试题 5
10、 list,iterate区别 5
11、 Hibernate 核心接口session介绍 5
12、 Session接口常见方法 6
13、 Hibernate操作的对象有三种状态 7
14、 Hibernate的检索策略 7
15、 Query 中常见方法 8
16、 Hibernate参数绑定有几种方式 8
17、 在Hibernate中什么是命名查询 8
18、 Hibernate优化 8
19、 什么是懒加载 懒加载用什么技术实现,如何解决session关闭导致的懒加载问题 解决的方案有缺点吗、 9
20、 hibernate核心类 9
21、 hibernate抓取策略 9
22、 hibernate 的原理 9
23、 Hibernate 的session.save()与session.saveOrUpdate()的区别? 9
24、 Hibernate 中sedssion.get()与session.load()的区别? 9
25、 介绍下hibernate 9
26、 Hibernate 中的HQL 和criteria 的区别? 10
27、 介绍hibernate 延持加载属性 10
28、 列举你接触过的框架,说明特点和原理 10
29、 Hibernate 中离线查询与在线查询的区别 10
30、 Ibatis 框架和Hibernate 框架各有什么特点? 10
31、 为什么要用ORM? 和JDBC 有何不一样? 10
32、 简述Hibernate 和JDBC 的优缺点? 10
33、 如何书写一个one-to-many 配置文件 10
34、 写Hibernate 的一对多和多对一双向关联的orm 配置? 10
35、 hibernate 的inverse 属性的作用? 11
36、 Hibernate 对象有几种状态?如何转换 11
37、 Hibernate 中有几种关系映射 11
38、 介绍一下Hibernate 的一级缓存与二级缓存。 11
39、 Hibernate 中的Cascade 属性有什么作用? 11
40、 Hibernate.update()和merge()区别? 11
41、 Hibernate update和flush区别? 11
42、 Hibernate session的load()和get()的区别? 11
43、 Hibernate List和Iterator方式的比较 12
44、 hibernate的inverse属性的作用? 12
45、 hibernate的cascade属性的作用? 12
46、 各种关联关系下的lazy懒加载区别? 12
47、 类(Class)的延迟加载: 13
48、 Hibernate工作原理 13
三、 Struts2.x 14
49、 MVC是什么 一种设计模式,M:model模型;V:View视图;C:Control控制器 14
50、 简述 Struts2 的工作流程: 14
51、 Struts2 拦截器 和 过滤器 的区别 14
52、 为什么要使用 Struts2 & Struts2 的优点: 14
53、 Struts2 如何访问 HttpServletRequest、HttpSession、ServletContext 三个域对象 ? 14
54、 Struts2 中的默认包 struts-default 有什么作用? 15
55、 说出 struts2 中至少 5 个的默认拦截器 15
56、 谈谈 ValueStack 15
57、 ActionContext、ServletContext、pageContext的区别 ? 15
58、 Struts2 有哪几种结果类型 ? 15
59、 拦截器的生命周期与工作过程 ? 15
60、 如何在 Struts2 中使用 Ajax 功能 ? 15
61、 用自己的话简要阐述struts2的执行流程 15
62、 Struts工作原理 16
63、 Struts2.0 有几种标签库 16
64、 struts2 必备包有哪些? 16
65、 Hiberbate 优化方法有那些? 16
66、 应用服务器与Web Server 的区别 16
67、 如何设置Hibernate 二级缓存 16
68、 ApplicationContext 和BeanFactory 有什么区别? 16
69、 Spring MVC 与Struts2 MVC 的不同之处 17
70、 Spring 使用了哪些设计模式,这样用有什么好处? 17
71、 Hibernate 有哪几种查询数据的方法? 17
72、 3 个框架在项目在项目当中的用,BaseDao 是用来做什么的。 17
73、 ThreadLocal 在项目中的实际意义? 17
74、 Spring 对多种ORM 框架提供了很好的支持,结合事务管理描述spring 从哪些方面提供了对Hibernate 的支持。 17
75、 Hibernate 的session.save()与session.saveOrUpdate()的区别? 17
76、 Hibernate 中sedssion.get()与session.load()的区别? 18
77、 annotation 的使用方法和用途主要分为几类? 18
78、 Struts2 是怎么实现MVC 的? 18
79、 介绍下hibernate【上海数字政通】 18
80、 在Struts2 中,配置文件中通配符是怎么表示和使用的?使用通配符后有什么好处 18
81、 Hibernate 中的HQL 和criteria 的区别? 18
82、 介绍hibernate 延持加载属性 18
83、 列举你接触过的框架,说明特点和原理 19
84、 解释一下IOC,以及spring 的举例 19
85、 解释一下mvc 以及熟悉的mvc 框架 19
86、 Spring 工作原理 19
87、 Hibernate 中离线查询与在线查询的区别 19
88、 Struts2 实现拦截器的原理? 19
89、 Struts2 的实现原理 19
90、 简述spring 的事务传播行为和隔离级别 19
91、 Ibatis 框架和Hibernate 框架各有什么特点? 20
92、 为什么要用ORM? 和JDBC 有何不一样? 20
93、 谈谈你对Spring AOP 思想的理解。 20
94、 谈谈你对Spring 的理解。 20
95、 说说struts1 与struts2 的区别。 20
96、 简述Hibernate 和JDBC 的优缺点? 如何书写一个one to many 配置文件 21
97、 写Hibernate 的一对多和多对一双向关联的orm 配置? 21
98、 hibernate 的inverse 属性的作用? 21
99、 Spring 的依赖注入是什么意思? 给一个Bean 的message 属性, 字符串类型, 注入值为"Hello" 的XML 配置文件该怎么写? 21
100、 JDO 是什么? 22
101、 Spring 与EJB 的区别? 22
102、 SSH 框架的优缺点。 22
103、 Spring 有哪几种注入方式? 22
104、 Spring MVC 工作机制及为什么要用? 23
105、 spring 中常用的几种advice 23
106、 Spring 中bean 的配置scope 表示什么含义?可以有哪几种取值。 23
107、 Hibernate 对象有几种状态?如何转换 23
108、 spring 中OpenSessionInViewFilter 作用什么的,解决了什么问题 23
109、 hibernate 有哪五个核心接口。 23
110、 Hibernate 中有几种关系映射 23
111、 介绍一下Hibernate 的一级缓存与二级缓存。 23
112、 如何在WEB 里面配置SPRING 23
113、 Hibernate 中的Cascade 属性有什么作用? 24
114、 Struts1 优缺点 24
115、 整合spring 与struts1 的方法,那种最好,为什么? 24
116、 Struts1.2 的工作原理 24
117、 谈谈Struts1 中的ActionServlet。 24
118、 Struts1.X 中ActionServlet、ActionForm 、Action、ActionMapping 各起什么作用? 25
119、 Struts 1 的Action 类与Struts 2 的Action 类区别? 25
120、 谈谈你对Struts1 的理解。 25
121、 Struts1 中的action 是安全线程么?为什么 25
122、 在Struts1 中actionform 属于哪一层 25
123、 struts 控制器组件的主要包括? 25
124、 常见的缓存技术举例【大唐动力面试题】 25
125、 以Spring 为基础的J2EE 项目中,一般如何分层?每个层的作用是什么?事务控制放在哪一层? 25
126、 EBJ 是基于哪些技术实现的和JavaBean 的区别? 25
127、 Webservice 有什么好处? 26
128、 什么是事物处理,J2EE 提供哪两种事物处理方式 26
129、 WEB SERVICE 的理解【大唐动力面试题】 26
130、 J2EE 系统访问速度慢.从哪些方面可以优化 26
131、 说说你所知道的应用服务器? 26
四、 Spring 27
132、 对Spring理解与作用 27
133、 在spring中有几种事务管理,分别是什么? 27
134、 JDK动态代理学习 27
135、 Spring与Struts集成 把业务对象、Action纳入spring的ioc容器, 27
136、 怎么理解OpenSessionInviewFilter? 27
137、 讲讲spring中的事务,如何支持事务的,事务的7大传播属性,spring mvc 作为控制器层需要注意什么 27
138、 什么是aop 说说AOP的一些概念概念和术语 aop好处 项目中怎么用的 27
五、 SpringMVC 28
139、 spring 如何实现mvc 请求处理流程 28
140、 spring mvc如何执行静态文件如js文件 css文件 图片文件 28
141、 springmvc与struts2比较 28
142、 spring mvc 注解 28
143、 说说spring dao 29
六、 MyBatis 29
144、 .ibatis/mybatis框架的优缺点? 29
145、 ibatis核心类的作用;MyBatis核心类的作用? 29
146、 mybatis/ibatis跟hibernate的比较; 29
147、 ibatis的工作流程或运行原理? 29
148、 Ibatis中#与$的区别? 29
七、 WebServices 30
149、 怎么调用webservice 30
150、 wsdl soap 30
151、 你如何开发webservice 30
152、 项目用了webservice干什么 30
153、 安全问题: 30
154、 ejb 31
八、 EJB 31
九、 DAO 31
155、 dao是什么及其优点 31
156、 jdbc 31
157、 说说spring dao 31
158、 orm框架 什么是orm orm比较 与jdbc比较 31
159、 ibatis与mybatis比较 # $ %干什么的 32
160、 hibernate load与get list() 和 iterate() saveOrUpdate与merge 32
161、 什么是懒加载 懒加载用代理技术实现 如何解决session关闭导致的懒加载问题 解决的方案有缺点吗 32
162、 缓存 32
163、 mybatis,hibernate如何开发一对多的案例 过程以及如何配置 33
164、 hibernate 实体的3种状态 33
165、 hibernate 的原理步骤 核心类 33
166、 hibernate 的经验 (如 大数据处理 性能优化 有什么经验 最佳实践) 33
167、 hibenrate 查询方式 离线查询 33
168、 hibernate抓取策略 指的是如何查询关联数据 (有关联实体与关联集合) 34
169、 hibernate注解 34
170、 你了解ejb或者jpa吗,随便谈一下 34
好处:1、良好的架构和设计
2、可重用,模块化,扩展性好
3、Open source 开放源代码
4、它提供了丰富的标签库,使页面能更加的灵活的使用。
缺点:1、依赖于servlet API 不方便测试
2、单例模式,线程不安全
3、视图表现层技术都支持jsp
4、类型转换是单向的
5、没有针对具体方法的校验。
6、强制继承action或者dispatchAction
7、它太过于依赖web容器,当配置文件改动一次就要重新启动。
8、它的配置文件太过复杂。
9、ActionForm无法进行测试
ActionServlet 核心控制器
Action 业务类
ActionForm 0显示数据 1封装页面数据 2回显数据 3校验
ActionMapping 帮助ActionServlet控制器将请求映射到业务类操作(类似于查询action)
ActionForward 导航器,进行jsp页面转发
ActionError与Actionmessage 用来存储和回收错误
Struts标签库可以减轻开发显示层次的工作
1、读取配置
2、发送请求
3、填充form
4、校验form input
5、派发请求 到Action的业务方法 比如execute方法
6、处理业务
7、返回响应
8、处理返回响应
工作原理:在Struts中,用户的请求一般以*.do作为服务名,所有的*.do请求均被指向ActionServlet
ActionServlet根据Struts-config.xml中的配置信息,将用户请求封装成一个指定名称的FromBean
并将此FromBean传至指定名称的ActionBean,由ActionBean完成相应的业务操作。
1、因为struts1是单例的,所以存在线程安全问题,所以我们采用在方法上标上线程同步或者使用同步代码块就可以解决了。
2、Action交给spring创建
3、注意不要用实例变量或类变量共享只是针对某个请求的数据,注意资料操作的同步性
它解决了jsp页面代码混乱和多个Servlet的问题
Jsp + servlet + tiles
用户发送请求 到达ActionServlet核心控制器,然后在通过ActionMapping帮助ActionServlet将控制器请求映射到业务类
在此之间 通过ActionForm将数据进行类型转换,数据封装,和校验。
然后执行业务类的的execute方法 然后将ActionForm转换成我们自己定义的form
在通过调用m层的方法将数据持久化到数据库 再返回C层通过ActionForward进行页面转发返回到V层
DispatchAction:分发方法,不需要实现execute方法否则失效 在配置文件中配置parameter 里面放入如:xxx; 在调用
可在?号传值xxx=方法名即可
动态form:
可以在配置文件里配置动态的form 他里面的属性字段和定义的bean一样
当前台数据传送过来的时候可以将ActionForm直接转换成动态的form就可以了 但是一个项目中form不可以太多
如果配置太多的话会导致项目过于臃肿
1 不能通过new创建动态form 实例 减少actionform的个数
2 修改了某个属性不需要编译源代码,方便后期维护
缺点:
1 会导致配置文件臃肿
可以不用通过编程的方式而只要通过struts-config.xml文件中进行配置,以后在struts运行时,会自动根
据struts-config.xml中配置的DynaActionform来生成一个ActionForm实例
很显然随着应用程序的变大,数百个ActionForm 这样不仅编程起来麻烦,以后维护起来也麻烦,比如:
某个属性变化了,则需要修改源代码,然后重新编译,但是如果使用DynaActionform则只需要修改
struts-config.xml配置文件就行了。这样提高了应用程序的开发效率与应用程序的可维护性
但大量的使用它也会造成配置文件的臃肿
• 使用list()方法获取查询结果,每次发出一条查询语句,获取全部数据
• 使用iterate()方法获取查询结果,先发出一条SQL 语句用来查询满足条件数据的id,然后依次按这些id 查询记录,也就是要执行N+1 条SQL 语句(N 为符合条件的记录数)
• list()方法将不会在缓存中读取数据,它总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存
• iterate()方法则是获取了符合条件的数据的id 后,首先根据id 在缓存中寻找符合条件的数据,若缓存中无符合条件的数据,再到数据库中查询
1、作用:提供基本的保存,删除,更新,和加载Java对象
2、什么是清理缓存:
Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程别称为清理缓存(flush)
3、SessionFactory是线程安全的(可以多个对象共用同一个对象)。而Session不是线程安全的。
为了解决Session线程不安全我们采用ThreadLocal方案。
ThreadLocal 模式的解决方案:
ThreadLocal并不是一个线程的本地实现,也就是说它不是一个Thread,而是Thread local variable(线程局部变量)。它的作用就是为每一个使用这个变量的线程提供一个变量的副本,并且每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
ThreadLocal模式实例代码:
public void getSession() {
Configuration cfg = new Configuration().configure();
SessionFactory sf = cfg.buildSessionFactory();
session = sf.openSession();
}
//创建ThreadLocal对象
private static final ThreadLocal threadLodacl = new ThreadLocal();
public void getSession() {
Configuration cfg = new Configuration().configure();
SessionFactory sf = cfg.buildSessionFactory();
//session = sf.openSession();
//解决session线程非安全的方式
this.session = (Session) threadLodacl.get();
if(session == null){
this.session = sf.openSession();
threadLodacl.set(this.session);
}
}
4、获取session的两种方式介绍
1、 getCurrentSession创建的Session会绑定到当前线程,而openSession不会
2、 getCurrentSession创建的Session会在事务回滚或者事务提交后自动关闭,而openSession创建的必须手动关闭(调用Session的cloe()方法)
3、 getCurrentSession使用方法
1、 当使用本地事务时(jdbc事务)
需要在hibernate.cfg.xml文件的
<property name="hibernate.current_session_context_class">threadproperty>
2、 当使用的是全局使唔时(jta事务)
<property name="hibernate.current_session_context_class">jtaproperty>
注意:如果使用了getCurrentSession方法又没有在配置中配置以上方法时程序编译无误,但是运行汇报如下错误。
Exception in thread "main" org.hibernate.HibernateException: No CurrentSessionContext configured!
序号 |
Session 方法及说明 |
1 |
Transaction beginTransaction()开始工作单位,并返回关联事务对象。 |
2 |
void cancelQuery()取消当前的查询执行。 |
3 |
void clear()完全清除该会话。 |
4 |
Connection close()通过释放和清理 JDBC 连接以结束该会话。 |
5 |
Criteria createCriteria(Class persistentClass)为给定的实体类或实体类的超类创建一个新的 Criteria 实例。 |
6 |
Criteria createCriteria(String entityName)为给定的实体名称创建一个新的 Criteria 实例。 |
7 |
Serializable getIdentifier(Object object)返回与给定实体相关联的会话的标识符值。 |
8 |
Query createFilter(Object collection, String queryString)为给定的集合和过滤字符创建查询的新实例。 |
9 |
Query createQuery(String queryString)为给定的 HQL 查询字符创建查询的新实例。 |
10 |
SQLQuery createSQLQuery(String queryString)为给定的 SQL 查询字符串创建 SQLQuery 的新实例。 |
11 |
void delete(Object object)从数据存储中删除持久化实例。 |
12 |
void delete(String entityName, Object object)从数据存储中删除持久化实例。 |
13 |
Session get(String entityName, Serializable id)返回给定命名的且带有给定标识符或 null 的持久化实例(若无该种持久化实例)。 |
14 |
SessionFactory getSessionFactory()获取创建该会话的 session 工厂。 |
15 |
void refresh(Object object)从基本数据库中重新读取给定实例的状态。 |
16 |
Transaction getTransaction()获取与该 session 关联的事务实例。 |
17 |
boolean isConnected()检查当前 session 是否连接。 |
18 |
boolean isDirty()该 session 中是否包含必须与数据库同步的变化? |
19 |
boolean isOpen()检查该 session 是否仍处于开启状态。 |
20 |
Serializable save(Object object)先分配一个生成的标识,以保持给定的瞬时状态实例。 |
21 |
void saveOrUpdate(Object object)保存(对象)或更新(对象)给定的实例。 |
22 |
void update(Object object)更新带有标识符且是给定的处于脱管状态的实例的持久化实例。 |
23 |
void update(String entityName, Object object)更新带有标识符且是给定的处于脱管状态的实例的持久化实例。 |
1、瞬时状态(Transient)/临时。2.、持久化状态(persistent)。3、托管状态(detached)/游离状态
1、当一个对象通过new 新创建的时候就是瞬时状态
瞬时状态下对象的主键没有值,也没有纳入session的管理,数据库表中也没有对应的记录,当我们调用save等相关的其他方法是则进入了持久化状态,
2、持久化状态下对象纳入了session管理中,对象标示符有值。Hibernate保证在同一个session实例的缓存中数据库中的一条记录只对应唯一的一个持久化对象。session在清理缓存时会根据持久化对象的属性变化会同步更新数据库。当session关闭后持久化状态就会变成托管状态。当持久化对象调用delete方法就由持久化变成了移除状态
3、托管状态下的特点:对象不处于session的管理中。但他曾经与某个持久化上下文发生过关联(session),对象标示符有值,数据库可能存在与之相对的记录。Hibernate不能够保证托管状态下的数据和数据库中的数据同步更新。
4、临时和游离状态下的对象特点:等待垃圾回收,
检索策略 |
运行机制 |
立即检索 |
立即加载与当前对象关联的对象,需要执行多条select语句 |
延迟检索 |
不立即加载与当前对象关联的对象,在第一次访问关联对象时才加载其信息 |
迫切左外连接检索 |
通过左外连接加载与当前对象的关联对象。为立即检索策略,但执行的select语句少,只执行1条select连接查询语句 |
属性 |
类级别 |
一对多关联级别 |
多对一关联级别 |
lazy |
1. 2. |
1. 2. |
1. 2. |
fetch |
没有此属性 |
1. 2. |
1. 2. |
1、检索方法
a) 通过Session类的get和load方法加载指定的OID的对象
b) 通过HQL,QBC等检索方法记载满足条件的对象
2、检索的作用域
a) 类级别:作用于当前对象。对当前对象时立即检索,还是延迟检索。默认延迟检索只对load有效
b) 关联级别:对关联对象是立即检索,延迟检索还是迫切左外连接检索。默认延迟检索。对所有检索方法有效
3、fetch的作用和取值
a) select 加载关联对象时通过select语句实现。默认值
b) subselect 加载关联对象时通过带子查询语句实现。
c) join 执行立即检索,采用迫切左外连接检索所有关联对象,lazy属性将被忽略。
总结:① select 和 subselect 适用于立即检索和延迟检索,join 仅使用立即检索。
② select 和 subselect 决定加载关联对象时查询语句形式,join决定加载关联对象的时机。
1、 占位符“?”
2、 命名查询
3、 封装参数(投影查询)
命名查询是在映射文件中定义字符串形式的查询语句
<query name="findPrimaryKey">
from Emp e where e.job = :job
]]>
query>
<sql-query name="findPrimaryKey">
select * from emp where job = ‘研发部’
]]>
sql-query>
1、避免or操作
where 子句包含or 操作,执行时不使用索引
可以使用in条件来替换
2、避免使用not
where 子句包含not 关键字,执行时该字段的索引失效
使用比较运算符替换not
3、避免like的特殊形式
查询时,尽可能少使用like
4、避免having子句
尽可能在where 子句中指定条件
5、避免使用distinct
在不要求或允许冗余时,应避免使用distinct
懒加载就是延迟加载,采用代理技术实现,采用openSessionInViewFilter,openSessionInViewFilter其实上就是一个过滤器页面打开时开启session,页面访问结束时关闭session
当访问用户过多,而且网速过慢的时候,会挤爆系统
事务扩大了 加锁导致资源等待时间过长
session范围变大 如果加载页面的时间过长 如网速比较慢 session内存时间过长 导致系统性能下载
数据库连接不能及时释放
congfigeration负责管理配置信息
sessionfactory负责创建出session
session负责调用持久化方法
Transaction 负责事务管理
query为查询接口
Hibernate的 抓取策略有四种
1、 join 连接抓取 它是通过select语句使用外连接来加载实体或者集合 懒加载会失效--同等于mybatis中的嵌套结果
2、 select 查询抓取 它是通过发送一条select语句抓取当前对象关联的实体或者集合 一条查自己 一条抓关联数据
3、 subselect 子查询抓取 发送一条select语句查询出关联的实体或者集合,然后通过子查询in完成
4、 batch-size 批量抓取
1. 读取并解析配置文件
2. 读取并解析映射信息,创建SessionFactory
3. 打开Sesssion
4. 创建事务Transation
5. 持久化操作
6. 提交事务
7. 关闭Session
8. 关闭SesstionFactory
1.save()方法,调用save 方法时,首先会在session 缓存中查找保存对象如果实体对象已经处于Persient 状态,直接返回;否则并将保存至数据库,对象变为持久状态。
2.saveOrUpdate()方法:和save 方法一样首先在session 缓存中查找,判断对象是否为为保存状态,如果对象处于Persient,不执行操作,处于Transient 执行save 操作,处于Detached 调用saveOrUpdate 将对象与session 重新关联(简单的说就是该方法会先看该对象是否已经存在,如果已经存在就更新,否则新增保存),如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。
Session.load/get 方法均可以根据指定的实体类和id 从数据库读取记录,并返回与之对
应的实体对象。其区别在于:
1) 如果未能发现符合条件的记录, get 方法返回null , 而load 方法会抛出一个
ObjectNotFoundException。
2) load 支持延迟加载,get 不支持
3) load 方法可返回实体的代理类实例,而get 方法永远直接返回实体类。
4) load 方法可以充分利用内部缓存和二级缓存中的现有数据,get 方法则仅仅在内部缓存
中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL 完成数据读取。
Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架。将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,Hibernate 不仅负责从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL 和JDBC 上的开发时间。
1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;
2.HQL(Hibernate Query Language)查询提供了更加丰富的和灵活的查询特性,在涵盖
Criteria 查询的所有功能的前提下,提供了类似标准SQL 语句的查询方式,同时也
提供了更加面向对象的封装。
Hibernate 通过lazy 来指定加载策略,一般值为true 或false,。设为flase 表示立即加载,true 表过延迟加载。
Hibernate 特点:
1. 基于JDBC 的主流持久化框架,是一个优秀的ORM 实现,对JDBC 访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. hibernate 使用Java 反射机制,而不是字节码增强程序来实现透明性。
3. hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
Spring 特点:
Spring 框架的主要优势之一低侵入式的架构思想,实现了IOC 容器。另外一个AOP 的编程也在很多应用场合下地位较重。提供了对各种不同类型框架的支持,如:Web 容器、持入层、事务层、其它J2EE 组件等。
Criteria 和DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在线的,所以它是由Hibernate Session 进行创建的;而DetachedCriteria 是离线的,创建时无需Session,DetachedCriteria 提供了2 个静态方法forClass(Class) 或forEntityName(Name)进行DetachedCriteria 实例的创建。
orm 是一种思想,就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 对象,我们可以用jdbc 来实现这种思想,orm 的思想本质就是建立是JDBC 上,对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节,提高了开发效率,现在用的较多的ORM 工具很多,一般我们公司采用的ORM 框架主要有hibernate 和MyBatis。当然也听说一些其他orm 工具,如toplink,ojb 等。
1、封装了jdbc,简化了很多重复性代码。
2、简化了DAO 层编码工作,使开发更对象化了。
3、移植性好,支持各种数据库,如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码。
4、支持透明持久化,因为hibernate 操作的是纯粹的(pojo)java 类,没有实现任何接口,没有侵入性。
1、 配置一对多
2、 多对一
在Hibernate 中,术语inverse 是反转的意思,在关联关系中,inverse="false"为主控方,由主控方负责维护对象的关联关系,如果设为主控方对象,主控对象更新,则负责更新另一方对象更新。
共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。
主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多
缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。Hibernate 的Session 就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连,所以Session 最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session 是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大。Hibernate 的二级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存,也叫进程级的缓存,使用第3 方插件实现的,也值缓存实体,生命周期和sessionFactory 一致,可以进行管理。
二级缓存具体实现:
首先配置第3 放插件,我们用的是EHCache,在hibernate.cfg.xml 文件中加入
在映射中也要显示的调用,
命周期也结束了。在程序中必须手动启用查询缓存:query.setCacheable(true);
cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:
all : 所有情况下均进行关联操作。
save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。
none:所有情况下均不进行关联操作。这是默认值。
delete :(级联删除) 级联删除所关联的对象。
all-delete-orphan:自动删除不再和父对象关联的子对象。并且,在出现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值。
前面说过update,基本merge和update一样。但如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象覆盖session已有的持久实例
(1)当我们使用update的时候,执行完成后,会抛出异常
(2)但当我们使用merge的时候,把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中,执行完成后原来是持久状态还是持久态,而我们提供的A还是自由态。
Hibernate update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象,而flush是操作的在持久状态的对象。
默认情况下,一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值,等待Hibernate flush就自动更新或保存到数据库了。
(1) 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合。get()一个对象,把对象的属性进行改变,把资源关闭。
(2)transaction commit的时候(包含了flush) 。
1:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。 对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null(网上有很多误解以为get就马上去数据库查找根本不先查session那是不正确的,不想信你就去做下试验便知)。
2、“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。
3、再注重说明get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。
总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
(1)、List方式是1次性把所有的数据全部取到内存中,构造一个超大的结果集,主要的时间开销是这一步,这一步的时间开销要远远超过JDBC和 Iterator方式下构造结果集的时间开销,并且内存开销也很惊人;而对结果集的遍历操作,速度则是非常的惊人(经过测试,30万记录的内 存遍历不到100ms,由于这一步不受JDBC影响,因此结果可信)。因此,List方式适合于对结果集进行反复多次操作的情况,例如分页显示,往后往前 遍历,跳到第一行,跳到最后一行等等。
(2)、Iterator方式只取记录id到内存中,并没有把所有数据取到内存中,因此构造结果集的时间开销很小,比JDBC和List方式都要少,并且内 存开销也小很多。而对结果集的遍历的操作的时候,Iterator仍然要访问数据库,所有主要的时间开销都花在这里。因此,Iterator方式适合于只 对结果集进行1次遍历操作的情况,并且Iterator方式特别适合于从超大结果集中取少量数据,这种情况Iterator性能非常好
在Hibernate中,术语inverse是反转的意思,在关联关系中,inverse=”false”为主控方,由主控方负责维护对象的关联关系。
inverse 决定是否把对对象中集合的改动反映到数据库中,所以inverse只对集合起作用,也就是只对one-to-many或many-to-many有效(因 为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用,注意一般只在双向关联时才有需要设置inverse)。
(1)、一对多:
通常会在的one一方放弃对多的关系的维护,这样效率会高起来(如老师记住每位学生是件困难的事情,效率是很低的,所以干脆就不记了,这关系由学生来维护,学生记住一位老师是很容易)
所以应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可以不设置inverse属性,因为默认值是false),这说明关联关系由多的一方来维护。
如果要一方维护关系,就会使在插入或是删除”一”方时去update”多”方的每一个与这个”一”的对象有关系的对象。
而如果让”多”方面维护关系时就不会有update操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。
显然这样做的话,会减少很多操作,提高了效率。
注:单向one-to-many关联关系中,不可以设置inverse=”true”,因为被控方的映射文件中没有主控方的信息。
(2)、多对多: 属性在独立表中。inverse属性的默认值为false。在多对多关联关系中,关系的两端 inverse不能都设为false,即默认的情况是不对的,如果都设为false,在做插入操作时会导致在关系表中插入两次关系。也不能都设为 true,如果都设为true,任何操作都不会触发对关系表的操作。因此在任意一方设置inverse=true,另一方inverse=false。
cascade属性的作用是描述关联对象进行操作时的级联特性。因此,只有涉及到关系的元素才有cascade属性。
具 有cascade属性的标记包括
注意:
级联操作:指当主控方执行某项操作时,是否要对被关联方也执行相同的操作。
1、 one-to-one懒加载
一对一的懒加载并不常用,因为懒加载的目的是为了减少与数据库的交互,从而提高执行效率,而在一对一关系中,主表中的每一条数据只对应从表的一条数据库,就算都查询也不会增加多少交互的成本,而且主表不能有contrained=true,所以主表是不能懒加载的。但是从表可以有。实现此种懒加载必须在从对象这边同时满足三个条件:
a)lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
b)Constrained = true ;
c)fetch=select。
注:当fetch设置为join时,懒加载就会失效。因为fetch的作用是抓取方式,他有两个值分别为select和join,默认值为select。即在设为join时,他会直接将从表信息以join方式查询到而不是再次使用select查询,这样导致了懒加载的失效。
2、 one-to-many懒加载
与one-to-one关联不同,对one-to-many而言,主表的每一条属性都会对应从表的多条数据,这个时候懒加载就显得非常有效了。比如一个部门里面有多个员工,如果没有懒加载,每查询这个部门的时候都会查询出多个员工,这会大大增加与数据库交互的成本。所以Hbernate默认的是加入懒加载的。这就是查询集合属性的时候返回的是一个PersistentIndexed*类型对象的原因。该对象其实就是一个代理对象。当然,可以在映射文件中通过将lazy属性设为假来禁用。
Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:
一:设置lazy=”false”;
二:设置fetch=”join”.
实现此种懒加载必须在从对象这边同时满足两个条件:
1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
2、fetch=select。
3、 many-to-one懒加载
此关联关系的懒加载和one-to-one的懒加载一样都是可要可不要的,因为对执行效率的提高都不是非常明显。虽然多对一与一对一关系方式相同,但是在Hibernate中多对一时,默认是进行懒加载的。另外有一点需要注意的是懒加载并不会区分集合属性里面是否有值,即使是没有值,他依然会使用懒加载。实现此种懒加载必须在从对象这边同时满足两个条件
1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
2、fetch=select
4、 many-to-many懒加载
此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的。
实现此种懒加载必须在从对象这边同时满足两个条件:
1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
2、fetch=select
能够懒加载的对象都是被改过的代理对象,当相应的对象没有关闭时,访问这些懒加载对象的属性(getId和getClass除外)Hibernate会初始化这些代理,或用hibernate.initalize(proxy)来初始化代理对象;当关闭session后在访问懒加载的对象就会出现异常。
◆设置
◆ 如果lazy的属性值为true,那么在使用load方法加载数据时,只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。
注意:在class标签上配置的lazy属性不会影响到关联对象!
① 请求发送给 StrutsPrepareAndExecuteFilter
② StrutsPrepareAndExecuteFilter 判定该请求是否是一个 Struts2 请求
③ 若该请求是一个 Struts2 请求,则 StrutsPrepareAndExecuteFilter 把请求的处理交给 ActionProxy
④ ActionProxy 创建一个 ActionInvocation 的实例,并进行初始化
⑤ ActionInvocation 实例在调用 Action 的过程前后,涉及到相关拦截器(Intercepter)的调用。
⑥ Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。调用结果的 execute 方法,渲染结果。
⑦ 执行各个拦截器 invocation.invoke() 之后的代码
⑧ 把结果发送到客户端
① 过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器。
② Struts2 拦截器只能对 Action 请求起作用,而过滤器则可以对几乎所有请求起作用。
③ 拦截器可以访问 Action 上下文(ActionContext)、值栈里的对象(ValueStack),而过滤器不能.
④ 在 Action 的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
① 基于 MVC 架构,框架结构清晰。
② 使用 OGNL: OGNL 可以快捷的访问值栈中的数据、调用值栈中对象的方法
③ 拦截器: Struts2 的拦截器是一个 Action 级别的 AOP, Struts2 中的许多特性都是通过拦截器来实现的, 例如异常处理,文件上传,验证等。拦截器是可配置与重用的
③ 多种表现层技术. 如:JSP、FreeMarker、Velocity 等
① 与 Servlet API 解耦的访问方式
> 通过 ActionContext 访问域对象对应的 Map 对象
> 通过实现 Aware 接口使 Struts2 注入对应的 Map 对象
② 与 Servlet API 耦合的访问方式
> 通过 ServletActionContext 直接获取 Servlet API 对象
> 通过实现 ServletXxxAware 接口的方式使 Struts2 注入对应的对象
①. struts-default 包是 struts2 内置的,它定义了 struts2 内部的众多拦截器和 Result 类型,而 Struts2 很多核心的功能都是通过这些内置的拦截器实现,如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了truts-default包才能使用struts2为我们提供的这些功能。
②.struts-default 包是在 struts-default.xml 中定义,struts-default.xml 也是 Struts2 默认配置文件。Struts2 每次都会自动加载 struts-default.xml文件。
③. 通常每个包都应该继承 struts-default 包。
exception;fileUpload;i18n;modelDriven;params;prepare;token;tokenSession;validation 等
①. ValueStack 贯穿整个 Action 的生命周期,保存在 request 域中,所以 ValueStack 和 request 的生命周期一样. 当 Struts2 接受一个请求时,会迅速创建 ActionContext,ValueStack,Action. 然后把 Action 存放进 ValueStack,所以 Action 的实例变量可以被 OGNL 访问。请求来的时候,Action、ValueStack 的生命开始;请求结束,Action、ValueStack的生命结束
②. 值栈是多实例的,因为Action 是多例的(和 Servlet 不一样,Servelt 是单例的),而每个 Action 都有一个对应的值栈,Action 对象默认保存在栈顶;
③. ValueStack 本质上就是一个 ArrayList(查看源代码得到);
④. 使用 OGNL 访问值栈的内容时,不需要#号,而访问 request、session、application、attr 时,需要加#号;
⑤. Struts2 重写了 request 的 getAttribute 方法,所以可以使用 EL 直接访问值栈中的内容
① ActionContext Struts2 的 API:是当前的 Action 的上下文环境
② ServletContext 和 PageContext 是 Servlet 的 API
dispatcher、chain、redirect
每个拦截器都是需要实现 Interceptor 接口
> init():在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化;
> intercept(ActionInvocation invocation):每拦截一个动作请求,该方法就会被调用一次;
> destroy:该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次;
① . JSON plugin
② . DOJO plugin
③ . DWR plugin
④ . 使用 Stream 结果类型.
Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用。 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,所以说Struts 2是WebWork的升级版本。基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置,该请求被FilterDispatcher接收。3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。6、返回HTTP响应到客户端浏览器。
一个请求在Struts2框架中的处理大概分为以下几个步骤
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2、 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
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的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置,该请求被FilterDispatcher接收。3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。6、返回HTTP响应到客户端浏览器。
【参考答案】UI 标签、控制标签、数据标签、杂项标签
【参考答案】
commons-fileupload-1.2.1.jar
freemarker-2.3.13.jar
ognl-2.6.11.jar
struts2-core-2.1.6.jar
xwork-2.1.2.jar
【参考答案】
1) 尽量使用many-to-one,避免使用one-to-many
2) 灵活使用单向one-to-many
3) 不用一对一,使用多对一代替一对一
4) 配置对象缓存,不使用集合缓存
5) 一对多使用Bag 多对一使用Set
6) 继承使用显示多态HQL:from object polymorphism="exlicit" 避免查处所有对象
7) 消除大表,使用二级缓存
1、首先要打开二级缓存,在hibernate.cfg.xml 中添加如下配置:
2、Hibernate 的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个缓存工具。如下配置指定Hibernate 使用EhCache 缓存工具。
3、 Hibernate 在默认情况下并不会对所有实体对象进行缓存,所以,我们需要指定缓存哪些对象,在实体对象的映射文件中(相应的
BeanFactory 实际上是实例化,配置和管理众多bean 的容器。这些bean 通常会彼此合作,因而它们之间会产生依赖,而这种依赖只是体现在Bean 与Bean 之间的依赖这些依赖关系可以通过配置来反映,而ApplicationContext beans 包是BeanFactory 的子类,提供了以编程的方式管理和操控bean 的基本功能,而context 包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory 的功能,简单说他增强了面向Web 容器的功能。ApplictionContext 完全采用声明式方式来使用容器,甚至不用去手工创建它,Web应用的启动进程中用它启动ApplicationContext 。当然用编程的方式创建一个ApplicationContext 对象可以有以下几种方式或实现:
1、ClassPathXmlApplicationContext:从类路径中的XML 文件载入上下文定义信息,把上下文定义文件当作类路径资源。
2、FileSystemXmlApplicationContext:从文件系统中的XML 文件载入上下文定义信息。
3、XmlWebApplicationContext:从Web 系统中的XMl 文件载入上下文信息。
【参考答案】
1、请求处理机制:spring mvc 是基于方法的设计,而sturts 是基于类,每次发一次请求都会实例一个action,每个action 都会被注入属性,而spring 基于方法,粒度更细。
2、参数传递:struts 是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。
3、设计思想上:struts 更加符合oop 的编程思想, spring 就比较谨慎,在servlet 上扩展。
4、intercepter 的实现机制:struts 有以自己的interceptor 机制,spring mvc 用的是独立的AOP 方式。这样导致struts 的配置文件量还是比spring mvc 大,虽然struts 的配置能继承,所以我觉得论使用上来讲,spring mvc 使用更加简洁,开发效率Spring MVC 确实比struts2高。
【参考答案】
最典型的像:工厂模式,Spring 的IOC 容器就是一个大的Bean 实例的工厂,负责Bean的周期管理。单例模式,这个和Spring 的IOC 一起的,既然是IOC 是一个大工厂,那个Bean对象为减少内存开销就需要提供单例特征。适配器模式,在Spring 的AOP 编程中随处可见Adapter 模式的应用。代理模式,为其它对象提供一种代理访问的机制。观察者模式,当对象发生变化时,其它对象需要得到相应更新,Spring 中应用也较为普遍。
【参考答案】
hibernate 查询有三种方式:HQL 查询、结构化SQL 查询、QBC 查询
【参考答案】
DAO 组件主要提供数据库访问操作,针对不同数据源表持久化操作进行了封装,这样可以提供其它层的访问接口,使得组件之间解耦。而BaseDAO 是这些所有这些不同的持久化的DAO 的公共API 进行了封装,进一步抽象提取,使其它各组件DAO 从BaseDAO 中派生,增强系统的重用性、维护性、扩展性。
【参考答案】
ThreadLocal 和其它同步机制相比从另一个角度来解决多线程的并发访问,它为每一个线程维护一个和该线程绑定的变量的副本,从而隔离了多个线程的数据,每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。还提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的整个变量封装进ThreadLocal
ThreadLocal 可以大量减少参数的传递,可以使代码简洁,但一个线程会绑定多个自己定义的局部对象,ThreadLocal 是抽象在线程上的对象创建工厂,目前的Tomcat5 使用了线程池,一个线程处理一个request,这样ThreadLocal 对象可以抽象的绑定在request 生命周期,不会存在线程危机,而且线程池也平衡了这些ThreadLocal
【参考答案】
1、SessionFactory 管理。使用Spring 整合Hibernate 时我们不需要hibernate.cfg.xml 文件。首先, 在applicationContext.xml 中配置数据源( dataSource ) bean 和session 工厂(sessionFactory)bean。
2、持入层管理。Spring 提供了HibernateTemplate,用于持久层访问,无需打开Session及关闭Session。它只要获得SessionFactory 的引用,将可以只读地打开Session,并在持久化访问结束后关闭Session,对持久层逻辑,通用的操作(如对数据库中数据的增,删,改,查)有HibernateTemplate 完成。
3、对DAO 的支持:通过继承HibernateDaoSupport 实现DAO 基本操作。
4、对事务支持:Spring 的声明式事务和编程式事务,很好的将持久化的操作纳入事务管理。
【参考答案】
1.save()方法,调用save 方法时,首先会在session 缓存中查找保存对象如果实体对象已经处于Persient 状态,直接返回;否则并将保存至数据库,对象变为持久状态。
2.saveOrUpdate()方法:和save 方法一样首先在session 缓存中查找,判断对象是否为为保存状态,如果对象处于Persient,不执行操作,处于Transient 执行save 操作,处于Detached 调用saveOrUpdate 将对象与session 重新关联(简单的说就是该方法会先看该对象是否已经存在,如果已经存在就更新,否则新增保存),如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。
【参考答案】
Session.load/get 方法均可以根据指定的实体类和id 从数据库读取记录,并返回与之对应的实体对象。其区别在于:
1) 如果未能发现符合条件的记录, get 方法返回null , 而load 方法会抛出一个ObjectNotFoundException。
2) load 支持延迟加载,get 不支持
3) load 方法可返回实体的代理类实例,而get 方法永远直接返回实体类。
4) load 方法可以充分利用内部缓存和二级缓存中的现有数据,get 方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL 完成数据读取。
【参考答案】
1、内建Annotation——Java5.0 版在java 语法中经常用到的内建Annotation:
2、开发者自定义Annotation:由开发者自定义Annotation 类型;
3、使用第三方开发的Annotation 类型
【参考答案】
MVC 就是model view controller,三种组件,Struts2 实现Controller 主要由一系列的前端过滤器(Filter)实现Controller。Model 层主要由Struts2 的Action 组件实现。View 层主要是由Struts2 的标签库、Freemarker 等组件实现视图层
【参考答案】
Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架。将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,Hibernate 不仅负责从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL 和JDBC 上的开发时间。
调用相同Action 中的不同方法
其中表达式{1}的值name 属性值中第一个*的值。如果用户请求的URL 为loginAction.action,则调用Jcuckoo.LoginRegistAction 中的login 方法;
如果用户请求的URL 为registerAction.action,则调用Jcuckoo.LoginRegistAction 中的register 方法
示例2:带转视图
当处理结果是input 时,会转到/input.jsp 页面当处理结果是success 时,如果crud_create.action,则会执行Jcuckoo.CrudAction 中的create 方法,并且跳
转到/create.jsp;如果crud_delete.action,则会执行Jcuckoo.CrudAction 中的delete 方法,并且跳转到/delete.jsp;
优点:
使用通配符能规范命名格式,简洁配置文件,加速开发效率,也是Struts 倡导的一种开发模式。
【参考答案】
1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;
2.HQL(Hibernate Query Language)查询提供了更加丰富的和灵活的查询特性,在涵盖Criteria 查询的所有功能的前提下,提供了类似标准SQL 语句的查询方式,同时也提供了更加面向对象的封装。
【参考答案】Hibernate 通过lazy 来指定加载策略,一般值为true 或false,。设为flase 表示立即加载,true 表过延迟加载。
Hibernate 特点:
1. 基于JDBC 的主流持久化框架,是一个优秀的ORM 实现,对JDBC 访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. hibernate 使用Java 反射机制,而不是字节码增强程序来实现透明性。
3. hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
Spring 特点:
Spring 框架的主要优势之一低侵入式的架构思想,实现了IOC 容器。另外一个AOP 的编程也在很多应用场合下地位较重。提供了对各种不同类型框架的支持,如:Web 容器、持入层、事务层、其它J2EE 组件等。
IOC 称为控制反转,也叫依赖注入,ioc 是Spring 的核心组件,它通过配置文件,将需要创建的对象以池的方式管理,将实例注入到需要的对象中区,是对象依赖于注入而不依赖于实现,解决了各个组件的耦合度,使得项目在后期的维护和扩展上非常方便。如在ssh框架整合中,我们将datasource 对象注入给sessionFactory,再将sessionFactory 注入给dao 组件,再将dao 组件注入给struts 的Action 组件,在将action 对象注入给struts的拦截器。
MVC 是Model-View-Controller 的简写。Model 代表的是应用的业务逻辑(通过JavaBean,EJB 组件实现), View 是应用的表示层(由JSP、HTML、各种Taglib 等组成),Controller 是提供应用程序的中心控制处理。通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现,这些组件可以进行交互和重用,另外有利于维护。Struts1、Struts2、Spring MVC、WebWork 等这些都是属于基于MVC 模式实现的框架
内部最核心的就是IOC 了,动态注入,让一个对象的创建不用new 了,可以自动的生产,这其实就是利用java 里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring 的配置文件来动态的创建对象,和调用对象里的方法的还有一个核心就是AOP 这个就是面向切面编程,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的
Spring 目的:
就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring 根据这些配置内部通过反射去动态的组装对象)要记住:Spring 是一个容器,凡是在容器里的对象才会有Spring 所提供的这些服务和功能
Criteria 和DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在线的,所以它是由Hibernate Session 进行创建的;而DetachedCriteria 是离线的,创建时无需Session,DetachedCriteria 提供了2 个静态方法forClass(Class) 或forEntityName(Name)进行DetachedCriteria 实例的创建。
拦截器是AOP 中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用。而Struts2 的Interceptor,其拦截的对象是Action 代码,可以定义在Action 代码之前或者之后执行拦截器的代码。
1. 整个结构就如同一个堆栈,除了Action 以外,堆栈中的其他元素是Interceptor
2. Action 位于堆栈的底部。由于堆栈"先进后出"的特性,而这些都是围绕着Action 的,当我们请求Action 时,必须首先把位于Action 上端的Interceptor 拿出来执行。
1、客户端初始化一个指向Servlet 容器(例如Tomcat)的请求
2 、这个请求经过一系列的过滤器( Filter )( 这些过滤器中有一个叫做ActionContextCleanUp 的可选过滤器,这个过滤器对于Struts2 和其他框架的集成很有帮助,例如:SiteMesh Plugin);
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 的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
spring 的事务传播行为:
Spring 在TransactionDefinition 接口中规定了7 种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED 类似的操作。
Spring 的隔离级别
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。
orm 是一种思想,就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 对象,我们可以用jdbc 来实现这种思想,orm 的思想本质就是建立是JDBC 上,对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节,提高了开发效率,现在用的较多的ORM 工具很多,一般我们公司采用的ORM 框架主要有hibernate 和MyBatis。当然也听说一些其他orm 工具,如toplink,ojb 等。
【参考答案】
AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-OrientedPrograming,面向对象编程)的补充和完善。OOP 引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力。也就是说,OOP 允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能,日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。而AOP 技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP 代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。使用“横切”技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。实现AOP 的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
1.Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory ( 实际上是一个接口), 在程序中通常BeanFactory 的子类
ApplicationContext。Spring 相当于一个大的工厂类,在其配置文件中通过
2. Spring 提供了对IOC 良好支持,IOC 是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。IOC 也称为DI(Depency Injection)。
3. Spring 提供了对AOP 技术的良好封装, AOP 称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP 功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK 中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice 对象进行提供,显然要创建出代理对象,至少需要目标类和Advice 类。
1) Servlet 依赖性
由于Action 在被调用时,HttpServletRequest 和HttpServletResponse 被传递到execute()方法中,Struts1中的Action 对Servlet 的API 是有依赖性的.但如果在Struts2中,Action 就不会对容器有依赖了,因为Action 是由简单的POJO 组成的.在Struts2中,servlet 上下文以简单的Map 的形式表现出来,这使得Action 可以得到独立的测试.如果需要,Struts2也可以访问原始的请求与响应。不过,其他的框架元素减少或排除直接访问HttpServetRequest 或HttpServletResponse 的必要。
2) Action 类
使用抽象类而不是接口设计是Struts1设计上的问题,这已经在Struts2中得到了解决.Struts1中的Action 类需要继承框架中依赖的抽象基础类.但在Struts2中,Action 类可能会也可能不会实现接口来启用可选的或者自定义的服务.在Struts2中,Action 是不会依赖于容器的,因为它是由简单的POJO 组成的.Struts2提供了一个基础的ActionSupport 类来实现一些常用的接口。尽管这样,Action 接口仍然不是必须要继承的,任何含有execute 方法的POJO 对象都可以当作Action 对象来用。
3) 验证
Struts1与Struts2都支持通过validate 方法的手动验证.Struts1使用ActionForm 中的validate 方法或者通过扩展Commons Validator 来进行校验.然而,Struts2支持通过Validate 方法与Xwork 校验框架的手动验证. Xwork 框架支持验证链到子属性----使用为属性类文件和校验上下文定义的验证.
4) 线程模型
在Struts1中,Action 资源一定是线程安全或者同步的.所以Action 是singletons 并且线程安全的,一定只有一个Action 类的实例处理该Action 的所有请求,singleton 策略限制了Struts1的Action 所能完成的,并且需要更加谨慎的开发.但是在Struts2中,Action 对象对每一个请求都生成实例,所以在Struts2中不存在线程安全的问题。
5) 易测性
测试Struts1的程序会有些复杂.测试Struts1 Action 的主要它依赖容器。但是在Struts2中,Action 可以经由创建Action 的实例,设置属性和调用方法来得到测试。Struts2中的测试是很简单的,不依赖于容器。
6) 获取输入
Struts1使用ActionForm 来捕获输入,而且所有的ActionForm 需要继承一个框架依赖的基类.由于JavaBean 不能当作ActionForm 来用,开发人员不得不创建冗繁的类来获取输入.不过Struts2使用Action 属性(例如输入属性不依赖于底层框架)这避免了需要创建第二个输入对象,从此冗繁减少了.此外在Struts2中,Action 的属性可以通过标签在web 页面中得到访问,POJO 表单对象和POJO Action.甚至富对象类型,包括业务或域对象,都可以被当作输入/输出对象来使用。
7) 表达式语言
Struts1与JSTL 整合,所以它使用JSTL 表达式语言.Struts1的表达式语言含有遍历图表的基础对象,但是在集合和索引属性的支持上表现不好.Struts2同样支持JSTL,但是它也支持一种更强大且灵活的表达式语言----“对象图标记语言”(OGNL)
8) 将绑定值到视图中
在视图层,Struts1使用标准的JSP 来绑定对象(在模型层被处理的)到页面上下文来进行访问.然而Struts2使用一种叫做值栈的技术,这使得标签可以访问值而不需将视图与正在呈递的对象类型连接起来.值栈允许重用一些属性名相同但类型不同的视图类型.
9) 类型转换
通常Struts1的ActionForm 属性都是String 型的。Struts1使用Commons-Beanutils进行类型转换,这些针对每一个类的类型转换无法为每一个实例配置。然而Struts2使用OGNL 来进行类型转换.框架包含了针对基础类型,常见对象类型与原始类型的转换器。
10) Action 的生存周期
Struts1支持对每一个模块的请求处理器的分离(生命周期),但是同一模块下的所有Action 必须共享相同的生命周期。Struts2支持通过拦截器栈为每一个Action 创建不同的生命周期.自定义栈可以视需要对不同的Action 使用.
1、封装了jdbc,简化了很多重复性代码。
2、简化了DAO 层编码工作,使开发更对象化了。
3、移植性好,支持各种数据库,如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码。
4、支持透明持久化,因为hibernate 操作的是纯粹的(pojo)java 类,没有实现任何接口,没有侵入性。
在Hibernate 中,术语inverse 是反转的意思,在关联关系中,inverse="false"为主控方,由主控方负责维护对象的关联关系,如果设为主控方对象,主控对象更新,则负责更新另一方对象更新。
依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某一个Java 类,需要另一个Java 类的协助时,在传统的程序设计过程中,通常由当前类(调用者)来创建被调用者的实例,然后使用被调用者的方法。但在Spring 里,创建被调用者的工作不再由调用者来完成,而是由其它类(往往是工厂类)或容器(Spring IOC容器)完成,当前调用者从其它类或容器中来获取被调用者的实例,这种方式称为控制反转;创建被调用者实例的工作通常由Spring 容器来完成,然后注入调用者,因此也称为依赖注入,这是Spring 的一种编程思想的体现。依赖注入在设计模式也体现得非常多,比如说工厂模式和构建模式,这种就是一个依赖
注入的实现
JDO 是Java 对象持久化的新的规范,为java data object 的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO 提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API 的使用)。这些繁琐的例行工作已经转移到JDO 产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC 只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML 以及对象数据库(ODBMS)等等,使得应用可移植性更强。
1) 提供商无关性
EJB 3.0 是一个被设计为对提供商没有依赖性的开放的标准。EJB 3.0 规范由企业JAVA社区的主流开源组织和厂商共同编写和支持的。EJB 3.0 框架使开发者的应用程序实现可以独立于应用服务器。而Spring 一直是一个非标准的技术,尽管你在任何应用服务器都上可以使用Spring 框架,但基于Spring 的应用仍然被限制于Spring 本身和在你的应用中使用到的Spring 提供的各种特别服务。
2) 服务整合
Spring 框架是建立在应用服务器和服务库之上,它的服务整合代码(如数据访问模板和Helper 类)是基于框架的,并暴露给应用开发者。相反,EJB 3.0 框架是紧密整合到应用服务器中的,它的服务整合代码是封装在一个标准的接口下的。
3) 服务聚合的灵活性
由于Spring 中的服务整合代码是作为编程接口暴露给应用开发者的,因此开发人员可以根据需要来聚合多个服务。这个特性使你可以集成一个你自己的“轻量”级应用服务器。通常,EJB 3.0 应用服务器不提供给开发者这种按照你的需要来选择服务的灵活性。大多数情况,你会得到一系列已经预先打包好的特性,其中有些你可能是不需要的。
4) 声明式服务
EJB 3.0 和Spring 都将运行时服务(如事务管理、安全、日志、消息、和信息服务)连接给应用程序。由于这些服务同应用程序的业务逻辑并不是直接相关的,因此,它们不被应用程序本身来管理。相反,这些服务被服务容器(如EJB 3.0 和Spring)以不可见的方式在运行时提供给应用程序。开发人员(或系统管理员)通过配置来告诉容器什么时候,以怎样的方式来应用这些服务。
5) 注射依赖
Spring 和EJB 3.0 都提供了大量的DI 模式支持。但是,它们之间也有着根本的不同。Spring 支持了通常意义上的但是复杂的基于XML 配置文件的注射依赖API;EJB 3.0 支持的注射大多数通用服务对象(如,EJB 和容器对象)和JNDI 对象,它通过简单的JAVA 注解来完成。
1.struts 第一个优点应该是实现了MVC。对Servlet 依赖减少,低侵入式的设计
2.Action 线程安全的设计
3.功能强大的OGNL 表达式使用。
4.支持多种复合视图,表现层的使用也多样化,像JSP\freeMarker\Velocity。
5.拦截器的应用,实现了AOP 的思想,方便重用与扩展
6.自动类型转换功能。
7.相对低粗度的数据验证功能
Struts 缺点:
Struts2 中Action 中取得从jsp 中传过来的参数时,如果页面过于复杂,会造成对象臃肿。
Spring 优点:
1、非常优秀的轻量级,低侵入式的框架。
2、IOC 的容器周期式的管理,降低组件的偶合。
3、对其它容器有非常好的支持,像对持久层的Hibernate、Ibaits、TOP Link等。
Spring 缺点:
1.Web 层的MVC 框架单过于单薄,对页面框架的支持,跟其它框架还有很大的差距。
2.不是一站式解决方案。
3.使用了反射来管理其容器中的bean,在程序中增大了内存和运行计算的时间。
4.部分组件功能还有待完善
Hibernate 的优点:
1、非常好的ORM 的框架,在MVC 的切分和JDBC 的封装上做的很好。
缺点:
1、对复杂查询,多变的查询,完成起来有难度。
2、自动化程序高,改写灵活性不够。
2、缓存不是太高效,所以有些企业单独会选择缓存框架或者弃用Hibernate 的原因之一。
3 种方法。构造属入、属性注入、接口注入
1) 客户端所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2) DispatcherServlet 查询一个或多个HandlerMapping,找到处理请求的Controller.
3) DispatcherServlet 请请求提交到目标Controller
4) Controller 进行业务逻辑处理后,会返回一个ModelAndView
5) Dispathcher 查询一个或多个ViewResolver 视图解析器,找到ModelAndView 对象指定的视图对象
6) 视图对象负责渲染返回给客户端。
BeforeAdvice (前织入)、AfterAdvice (后织入)、ArroundAdvice (前后织入)ThrowAdvice (异常织入)
【参考答案】
scope 表示Bean 的生命周期或者叫Bean 的作用域。scope 的值有两个:
1、singleton,为单例属性,即Spring IoC 容器只会创建该bean 的唯一一个实例,这也是默认的。
2、prototype 为原型属性,即每一次请求都会产生一个新的bean 实例。
共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。
解决Hibernate 的Session 的关闭与开启问题。
SSH 整合问题:Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个Hibernate Session 范围之内进行。如果Service 层返回一个启用了延迟加载功能的领域对象给Web 层,当Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常。而Spring为我们提供的OpenSessionInViewFilter 过滤器为我们很好的解决了这个问题。OpenSessionInViewFilter 的主要功能是用来把一个Hibernate Session 和一次完整的请求过程对应的线程相绑定,允许在事务提交之后延迟加载显示所需要的对象。实现"Open Session in View"的模式
Configuration 接口,SessionFactory 接口,Session 接口,Transaction 接口,Query 和Criteria接口
主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多。
缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。Hibernate 的Session 就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连,所以Session 最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session 是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大。Hibernate 的二级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存,也叫进程级的缓存,使用第3 方插件实现的,也值缓存实体,生命周期和sessionFactory 一致,可以进行管理。
二级缓存具体实现:
首先配置第3 放插件,我们用的是EHCache,在hibernate.cfg.xml 文件中加入
在映射中也要显示的调用,
主要配置Spring Web 监听器
cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:
all : 所有情况下均进行关联操作。
save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。
none:所有情况下均不进行关联操作。这是默认值。
delete :(级联删除) 级联删除所关联的对象。
all-delete-orphan:自动删除不再和父对象关联的子对象。并且,在出现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值。
优点:
1) 实现MVC 模式,结构清晰,使开发者只关注业务逻辑的实现.
2) 有丰富的tag 可以用,Struts 的标记库(Taglib),如能灵活动用,则能大大提高开发效率
3) 页面导航
4) 使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
5) 提供Exception 处理机制。
6) 数据库链接池管理。
7) 支持I18N (国际化)
缺点
1) 转到展示层时,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每
2) Struts 的Action 必需是thread-safe 方式,它仅仅允许一个实例去处理所有的请求。所以action 用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
3) 测试不方便. Struts 的每个Action 都同Web 层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现
4) 类型的转换. Struts 的FormBean 把所有的数据都作为String 类型,它可以使用工具Commons-Beanutils 进行类型转化。但它的转化都是在Class 级别,而且转化的类型是不可配置的。
5) 对Servlet 的依赖性过强. Struts 处理Action 时必需要依赖ServletRequest 和ServletResponse,所有它摆脱不了Servlet 容器。
6) 前端表达式语言方面集成了JSTL,所以它主要使用JSTL 的表达式语言来获取数据。可是JSTL 的表达式语言在Collection 和索引属性方面处理显得很弱。
7) 对Action 执行的控制困难. Struts 创建一个Action,如果想控制它的执行顺序将会非常困难。
8) 对Action 执行前和后的处理. Struts 处理Action 的时候是基于class 的hierarchies,很难在action 处理前和后进行操作。
9) 对事件支持不够. 在struts 中, 实际是一个表单Form 对应一个Action 类(或DispatchAction),换一句话说:在Struts 中实际是一个表单只能对应一个事件。
1.第一种方法:
Struts 的Action 继承Spring 的ActionSupport 类,并在Action 中获取Spring 的ApplicationContext。这是最简单的一种整合方式,但有三个缺点:第一,Struts 与Spring紧密耦合,不能改换到其他IoC 容器;第二,难以使用Spring AOP 特性;第三,对于需要使用DispatchAction 的Struts 应用无能为力。
2.第二种方法:
在Struts 的配置文件中,以Spring 的DelegatingRequestProcessor 类代替Struts的RequestProcessor 类, 并在Spring 的配置文件中定义与Struts 配置文件中
3.第三种方法:
通过Spring 的DelegatingActionProxy 类代理Struts 的动作,即在Struts 配置文件中,定义
【参考答案】
1.ActionServlet 核心控制器会拦截所有*.do 的请求
2.从struts-config.xml 中找到用户请求的Action
3.通过struts-config.xml 中的配置再去找这个Action 对应的ActionForm,并实例化
4.把用户填写的数据自动填充到ActionForm 中(调用ActionForm 中的setXX()方法填充)
5.同时把ActionForm 放入到指定的范围中(request,session)
6.然后把请求转发给Action
7.Action 获取ActionForm 中的值然后调用业务逻辑层实现功能
8.在通过ActionMapping 查找Actionforward 实现转发;
【参考答案】
中心控制器,负责所以请求处理,并根据配置文件,将请求转到指定Action 执行,并根据Action 的ActionForward 返回,转到指定视图。
【参考答案】
a. Actionservlet 为控制器,接受用户请求并派发给相应的Action 组件处理;
b. ActionForm 主要用于封装请求中的数据和简单验证
c. Action 组件具体对用户的请求进行处理
d. ActionMapping 封装当前用户请求Action 相关的配置信息
【参考答案】
Struts 1 要求Action 类要扩展自一个抽象基类。Struts 1 的一个共有的问题是面向抽象类编程而不是面向接口编程。Struts 2 的Action 类实现了一个Action 接口,连同其他接口一起实现可选择和自定义的服务。
Struts 1 Action 类是单例类,因只有一个示例控制所有的请求。
Struts 2 Action 对象每一个请求都实例化对象,所以没有程安全的问题。
【参考答案】
1. struts 是一个按MVC 模式设计的Web 层框架,其实它就是一个大大的servlet,这个Servlet 名为ActionServlet,或是ActionServlet 的子类。我们可以在web.xml 文件中将符合某种特征的所有请求交给这个Servlet 处理,这个Servlet 再参照一个配置文件(通常为/WEB-INF/struts-config.xml)将各个请求分别分配给不同的action 去处理。
2. ActionServlet 把请求交给action 去处理之前,会将请求参数封装成一个formbean对象(就是一个java 类,这个类中的每个属性对应一个请求参数)
3.要说明的是, ActionServlet 把formbean 对象传递给action 的execute 方法之前,可能会调用formbean 的validate方法进行校验,只有校验通过后才将这个formbean 对象传递给action 的execute 方法,否则,它将返回一个错误页面,这个错误页面由input 属性指定,(看配置文件)作者为什么将这里命名为input 属性,而不是error 属性,我们后面结合实际的运行效果进行分析。4.action 执行完后要返回显示的结果视图,这个结果视图是用一个ActionForward 对象来表示的,actionforward 对象通过struts-config.xml 配置文件中的配置关联到某个jsp页面,因为程序中使用的是在struts-config.xml 配置文件为jsp 页面设置的逻辑名,这样可以实现action 程序代码与返回的jsp 页面名称的解耦
【参考答案】
Servlet 是在多线程环境下的。即可能有多个请求发给一个servelt 实例,每个请求是一个线程。struts 下的action 也类似,同样在多线程环境下。为多线程环境编写代码。我们的controller servlet 指挥创建你的Action 类的一个实例,用此实例来服务所有的请求。因此,你必须编写线程安全的Action 类。遵循与写线程安全的servlet 同样的方针。
【参考答案】
属于视图层组件,负责封装页面表单数据。
【参考答案】
ActionServlet 组件:充当struts 框架的中央控制器。
RequestProcessor 组件,充当每个子应用模块的请求处理器
Action 组件,负责处理一项具体的业务。
【参考答案】
操作系统磁盘缓存->减少磁盘机械操作数据库缓存->减少文件系统I/O应用程序缓存->减少对数据库的查询Web 服务器缓存->减少应用服务器请求客户端浏览器缓存->少对网站的访问
一般分为持久层(DAO 层)、业务层(Service 层)、控制层、视图层;事务一般放在业务层,以一个业务作为一个事务分割的最小单位。
EJB 包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT 等技术实现EJB 是一个关于用JAVA 语言开发的可部署的服务器端组件的组件体系结构。它是一个技术协议,能使组件运行于任何应用服务器,专门用来解决商务问题JAVABEANS 是JAVA 类,是由属性、事件和方法组成的JAVA 组件,它们可以用来组成JAVA 应用程序Java Bean 是可复用的组件,对Java Bean 并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean 是被容器所创建(如Tomcat)的,所以Java Bean 应具有一个无参的构造器,另外,通常Java Bean 还要实现Serializable 接口用于实现Bean 的持久性。Java Bean 实际上相当于微软COM 模型中的本地进程内COM 组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java 的远程方法调用(RMI)技术的,所以EJB 可以被远程访问(跨进程、跨计算机)。但EJB 必须被布署在诸如Webspere、WebLogic 这样的容器中,EJB 客户从不直接访问真正的EJB 组件,而是通过其容器访问。EJB 容器是EJB 组件的代理,EJB 组件由容器所创建和管理,客户通过容器来访问真正的EJB 组件。
跨平台的可互操作性跨防火墙的通信应用程序集成软件和数据重用。
事务(Transaction)是数据库管理系统提供的基本功能之一,可以把完成用户一个特定工作的一组操作看作是一个不可拆分的工作单元,所以事务也就是作业或任务。
JDBC:支持单一数据库连接事务JTA:支持分布式事务
Web Service 主要是为了使原来各孤立的站点之间的信息能够相互通信、共享而提出的一种接口。Web Service 所使用的是Internet 上统一、开放的标准,如HTTP、XML、SOAP(简单对象访问协议)、WSDL 等,所以Web Service 可以在任何支持这些标准的环境(Windows,Linux)中使用。注:SOAP 协议(Simple Object Access Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML 的通讯协议。在此协议下,软件组件或应用程序能够通过标准的HTTP 协议进行通讯。它的设计目标就是简单性和扩展性,这有助于大量异构程序和平台之间的互操作性,从而使存在的应用程序能够被广泛的用户访问。
J2EE 性能的优化包括很多方面的,要达到一个性能优良的系统,除了关注代码之外,还应该根据系统实际的运行情况,从服务器软硬件环境、集群技术、系统构架设计、系统部署环境、数据结构、算法设计等方面综合考虑来优化。一般程序级别的优化首先考虑做数据缓存,数据库方面全做表的切割、数据分区、索引等这些方面来加快对数据的访问。
BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i Application Server,jBoss
Spring是一个开源的控制反转和面向切面的容器框架。
Spring包含依赖注入容器、AOP实现、DAO/ORM支持、Web集成等。
解耦合、提供各种服务(事务管理、消息服务)、单例模式支持、AOP技术可以很容易的实现权限控制、监控等、很多辅助类加快应用开发、对各大主流的应用框架提供了集成支持。
代码管理的事务处理、容器管理的事务处理;
并不直接管理事务、将事务管理委托给事务管理器;
声明式事务
传播行为、隔离级别
动态生成代理、可以和任何实现接口的目标对象融合
save完一个对象后,由于有这个过滤器,spring会把这个连接放到线程池里面,而不是马上关闭。当需要延迟加载的时候,spring会从线程池里面取出那个session完成加载的动作,当确定这个session确实不再需要的时候,spring才会close掉这个session
有编程型(事务量比较少)与声明型事务(aop)
1 不同平台下的有不同事务管理器
2 加功能的代码写在通知类中,spring已经提供了环绕通知,事务拦截器TransactionInteceptor
3 专门提供了一个类TransactionProxyFactoryBean生成事务代理类,该类内部持有事务拦截器TransactionInteceptor,只需注入
事务管理器与目标类即可
事务的7大传播属性 required(有就使用没有就建立一个) required_new(有没有都创建一个) support(支持) not_suppot(不支持) never(不支持,有事务管理器还报错) 嵌套
spring mvc的配置文件与ContextLoaderListener加载的包含service层 dao层实例的配置文件最好分开
aop aspect oriedted program 面向切面(方面)编程,在不改变源代码的基础上给目标类加上一些非业务性功能,如事务,日志,权限,需要给目标类生成代理类,生成代理类的技术有面向接口的jdk动态代理以及面向具体类的cglib技术(jdk通过接口实现,cglib通过继承来实现),加功能的代码写在通知类中,有五种 通知类,前置通知
后置通知,环绕通知,异常通知,最终通知,给代理类注入目标类和通知类,客户操纵的是代理类,想更精确的切入,使用切入点,例如
如果想把功能切入到哪些包下的哪些类的哪些方法需要aspectJ切入点表达式. exucution( * com.lxit..*.add(..) ) //修饰符? 返回值 类全名.方法名(..) 异常?
连接点是某个方法的调用或者异常的抛出,连接点的集合就是切入点
aop好处 源代码的无关性,低侵入式设计
项目中怎么用
1 事务 2 日志 3 权限
1 事务
1 配置事务管理器,不同的平台有不同的事务管理器,如DataSourceTransactionManager,HibernateTransactionManager,JPATransactionManager
2 使用
3 在需要事务的类或方法上使用@Transactionnal
日志
struts2的拦截器就是一个环绕通知 我们可以把消息通知写在invoke前后,怎么就是aop了 aop 是没有修改源代码的情况下加功能 加功能的代码写在通知类中
view发送请求---- 核心控制器DispathcerServlet--- hangldermapping(映射器)(类型转换,数据封转,数据检验,异常处理等)
-----------业务控制器-调用m层----
modelAndview(String)-----视图解析器(内部资源视图解析器)-- -视图层使用标签国际化展示数据
1 映射器 hangldermapping 定位action,使用@requestmapping
2 类型转换
1 实现convert接口
2 定义类型转化器服务工厂类FormattingConversionServiceFactoryBean ,注入我们的类型转换器
3 使用
3 数据封转 参数封转 使用对象或者是model
4 数据检验 jsr303校验
1 引入jsr303的校验实现者,如hibernate,
2 在参数对象上标上@valid注解,校验错误放在紧跟对象后的bindResult,
之后根据bindResult是否有校验错误进行相应的跳转
3 在校验的实体类中编写jsr303的注解校验 如notnull length eamli
5 值绑定到页面 model
6 视图解析器---内部资源视图解析器,xml视图解析器等,采用链式解析
7 国际化
1 定义id为messageSource的bean,注入国际化资源文件基础名
2 定义LocaleChangeInteceptor拦截器,拦截local参数,使用mvc:interceptors引入拦截器
3 语言环境放到哪里,如session作用域
1
1 在数据封装方面 ,spring3mvc方法级别 struts2 类级别 spring3mvc开发效率高于 struts2
2 spring3mvc 注解版基本上是零配置
3 springmvc与spring是一家人,兼容性好
4 struts2 存在安全漏洞
可以通过ongl表达式 格式化硬盘
使用重定向定位到钓鱼网站
1 @Controller 标注为spring容器的中的bean 做为c
2 作用域注解 有五大作用域: 原型 单例 request session 全局session
3 @RequestMapping 访问路径,可以用在类或者方法上 访问路径类/方法
4 @responsebody 返回字符串,一般用于返回json格式
5 @ModelAttribute 放入request作用域
6 @SessionAttributes 值能用在类上
7 @requestParam 主要用于数据封装时,页面的参数名与方法参数不一致时
8 @pathVarible 主要用于获取路径变量的值
1 对jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,
使用daoSupport方便获取模板
2 给模板类注入数据源,之后使用模板类的api进行数据操作
优点: 易于上手和掌握
sql写在xml里,便于统一管理和优化
解除sql与程序代码的耦合
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql
缺点: 可读性低,调试非常困难,非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接
ibatis:
SqlMapClientBuilder: 加载配置文件,返回一个会话
SqlMapClient: 具体的会话
SqlSession: 对数据的增删查改
SqlMapSession: 进行数据库操作
SqlSessionManager: 创建SqlSesstion的对象
SqlMapTransactionManager: 定义事务管理功能
Mybatis:
SqlSessionFactory 每个MyBatis应用的核心
Hibernate是全自动化的,只要配置映射文件,可以为我们动态的生成sql
ibatis是半自动化的,需要我们手动的编写sql,ibatis简单易学
Hibernate比较复杂,ibatis可以细粒度的优化,而Hibernate是根据映射文件进行优化
1.在sqlMapConfig的配置文件中进行数据库连接的配置。
2.在sqlMapConfig的xml配置文件中引用sqlMap的xml配置文件。
3.在sqlMap的xml配置文件中进行SQL文件的配置。(文件名称随意,一般是javaBean的类名加xml。)
4.通过SqlMapClient生成具体的操作,用来操作sqlMap配置文件中SQL文件的IBATIS对象。
5.SqlMapClient对象提供函数,函数的参数对应替换sqlMap配置文件的id,parameter等属性,完成SQL文件的执行
(1)#号它会将传进来的数据都当成一个一个字符串,会给数据加一对双引号,而$号它会将传进来的数据直接显示生成到sql中
(2)#号能够防止sql的注入,而$号无法防止sql的注入
(3)$方式一把用于传入数据库对象,比如表名
1 wsdl文件地址,根据该文件通过myeclipse webservice视图进行访问进而拿到soap协议
2 使用HttpUrlConnection进行网路连接,使用conection中的输出流发送soap协议,返回值也是一个soap协议,用conection中的输入流接,进行解析(dom sax stax)
1 wsdl web service description language 网络服务描述语言
wsdl 作用
1 提供了, 服务的访问地址,服务的绑定协议
2 wsdl生成客户端访问代码
3 wsdl 用过myeclipe工具获取soap协议
wsdl 7大元素
1 servides:服务的集合
2 port:单个服务访问点
3 porttype:相当于接口
4 operation: 操作 相当接口中的方法
5 message :方法中的参数以及返回值
6 type:数据类型
7 binding:协议
2 soap
简单对象访问协议 本质上就是xml格式 xml是国际工业标准的数据交换格式,所以会跨平台跨语言,其格式如下
信封
信封头 (加密的时候用到)
信封body
方法
参数
有一个场景,你的项目中有一个类中的某方法,公司有5个项目都要调用,最好的方式暴露成webservice
用的cxf技术,与spring结合较好,使用jdk中的jax-ws语法,那么如何把spring容器中的bean暴露成webservice
1 cxf技术 它使用 jax-ws的语法
2 接口类 使用@WebService注解 实现类 使用@WebService注解指定接口
3 配置CXFServlet,使得服务器启动时发布webservice
4 在spring配置文件中 导入cxf支持spring的3个文件
5 配置jaxws命名空间endpoint 发布spring中的bean,主要指定实现类,即#bean的id,以及地址
1 公共模块 数据交换 数据中心 五表权限
2 流程审批
3 便民服务 天气预报 手机号码归属地查询
webservice安全 以及大数据量
大数据量 在cxf框架中
1 快速信息集 @FastInfoset 2 对返回的数据进行压缩 @GZIP
2 数据缓存,它需要编写代码来实现
实际使用中,多线程下载文件的方式,webservice把数据打包到压缩文件,比较本地的文件名与时间,决定是否从远程服务端下载文件
1 使用拦截器技术,配置用户名以及密码,本质上是对soap-header信封头进行加密
服务端: 发布spring中的bean成webservice,配置inInterceptors 配置拦截器WSS4JInInterceptor,注入服务端密码验证类,该类实现了CallbackHandler
客户端:配置outInterceptors,配置out拦截器WSS4JOutInterceptor,注入客户端验证类
密码验证类实现 CallbackHandler
2 带证ca认证 配置 tomcat https http+Security
soa Service-Oriented Architecture 面向服务架构 WebService是soa一种实现。
1 ejb是sun公司java的一种规范,webservice是跨语言的
2 webservice 是通过http协议发送soap协议,ejb是jndi访问,底层协议rmi-iiop
3 可以把ejb暴露成webservice
1 dao data access object 数据访问对象 持久化层,主要用来进行数据操作的,经常成为dao模式
2 优点
1 数据访问独立到了一层,分层 ,易于分工,可重用
2 修改具体的dao层实现类,不会影响到其他层,实现松耦合
3 dao的结构 四大组件
1 doa接口
2 dao实现类
3 pojo(plain old java objecct)类
4 dao定位( 如何获取实例 spring)
4 常用的dao技术
jdbc spring的dao 以及orm(ibatis mybatis hibernate)
1 步骤手写
1 加载驱动 Class.forName("oralce.jdbc.driver.OracleDriver");
2 获取数据库连接 Connection connection=Drivermanager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","aaa","aaa");
3 创建statement Statement statement= connection.createStatement();
4 执行sql statement.executeQuery(sql);
5 处理ResutlSet结果集---手动转成javabean
6 关闭 ResutlSet statement Connection
2 3个statement
1 Statement 一边编译边执行
2 PrepareStatement 预编译,效率高,安全,阻止sql攻击,支持占位符
3 CallableStatement 调用存储过程
PrepareStatement继承Statement,CallableStatement 继承PrepareStatement
1 对jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,
使用daoSupport方便获取模板
2 给模板类注入数据源,之后使用模板类的api进行数据操作
1 orm object relaction mapping 对象关系映射,解决面向对象与关系数据库不匹配的技术,对jdbc进行了封装,
使得我们可以使用面向对象的思维操纵数据库。使用缓存与懒加载技术提高效率
2 常见的orm框架有ibatis mybatis hibernate
mybatis与hibernate
1 mybatis 半自动需要手动编写sql, 灵活控制sql,方便sql优化,代码量增加,不易移植, 也叫sql映射、不方便移植
2 hibernate 全自动,自动生成sql, 方便移植,也叫对象映射、方便移植
3 hibernate 与jdbc
1 hibernate封装了jdbc,使得我们可以使用面向对象的思维操纵数据库
2 hibernate 全自动,自动生成sql, 方便移植,也叫对象映射、方便移植
3 jdbc效率最好
1 iBATIS3.0以后到goole公司了,更名为mybatis
2 mybatis增加了接口绑定
3 传值方式由##---#{} $:解析数据库的关键字 %:模糊查询
4 mybatis核心类SqlSessionfactory SqlSeession ibatis sqlMapclient
5 使用ognl表达式,体现在动态sql上
6 配置的改变,如别名的配置,mybatis移动到了总配置文件中
1 load与get
load 支持懒加载,没找到数据时报异常,get不支持懒加载,没找到数据时返回null
2 list() 和 iterate()
list:查询缓存不存在时,一条sql去数据库把所有数据加载,填充一级缓存,二级缓存
iterate:去数据线加载id,根据id去缓存查询,如果缓存没有,以id为条件到数据库查询数据,会造成n+1次查询
由于list或填充缓存,而iterate会使用缓存,因此第一次使用list,之后使用iterate可提高效率
3 saveOrUpdate与merge
1 merge不会使对象变成持久化状态
2 缓存中存在相同id的实体,saveOrUpdate会报错,merge会合并
1 懒加载 真正需要数据的时候才向数据库发送sql,比如调用load方法,不会发出sql,而在加载对象属性时才发出了sql,实现了数据的延迟加载,get则不然
2 使用openSessionInView模式解决,实则是一个过滤器,保持session一直在view一直打开
1 session范围扩大,从dao扩展到了其他的层,session所暂用的资源不能得到及时的释放,效率下降
2 事务扩大了
1 使用
1 hibernate缓存
一级缓存 内置的 调用session api如(save saveopupdate load等)会hibernate会把实体放入一级缓存 session级别缓存
二级缓存 可配置的 sessionFactory级别缓存,为所有session共享
1 打开二级缓存开关
2 指定哪种缓存 如 EHCache
3 指定哪些实体要放入二级缓存
查询缓存 :命中率较低 比较少用
2 ibatis 在映射文件配置Cachemodel
3 mybatis 在映射文件配置Cache,实体类实现序列化
2 优点与缺点
1 减少应用程序对数据库的访问次数,提高效率
2 数据量大时导致内存溢出
3 容忍无效的数据(缓存里的数据有可能是过期的),经常修改的数据不适合放入缓存中
3 缓存中配置一些什么东西
2、 多对一
在Hibernate 中,术语inverse 是反转的意思,在关联关系中,inverse="false"为主控方,由主控方负责维护对象的关联关系,如果设为主控方对象,主控对象更新,则负责更新另一方对象更新。
共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。
主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多
缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。Hibernate 的Session 就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连,所以Session 最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session 是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大。Hibernate 的二级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存,也叫进程级的缓存,使用第3 方插件实现的,也值缓存实体,生命周期和sessionFactory 一致,可以进行管理。
二级缓存具体实现:
首先配置第3 放插件,我们用的是EHCache,在hibernate.cfg.xml 文件中加入
在映射中也要显示的调用,
命周期也结束了。在程序中必须手动启用查询缓存:query.setCacheable(true);
cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:
all : 所有情况下均进行关联操作。
save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。
none:所有情况下均不进行关联操作。这是默认值。
delete :(级联删除) 级联删除所关联的对象。
all-delete-orphan:自动删除不再和父对象关联的子对象。并且,在出现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值。
前面说过update,基本merge和update一样。但如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象覆盖session已有的持久实例
(1)当我们使用update的时候,执行完成后,会抛出异常
(2)但当我们使用merge的时候,把处理自由态的po对象A的属性copy到session当中处于持久态的po的属性中,执行完成后原来是持久状态还是持久态,而我们提供的A还是自由态。
Hibernate update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象,而flush是操作的在持久状态的对象。
默认情况下,一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值,等待Hibernate flush就自动更新或保存到数据库了。
(1) 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合。get()一个对象,把对象的属性进行改变,把资源关闭。
(2)transaction commit的时候(包含了flush) 。
1:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。 对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null(网上有很多误解以为get就马上去数据库查找根本不先查session那是不正确的,不想信你就去做下试验便知)。
2、“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。
3、再注重说明get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。
总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
(1)、List方式是1次性把所有的数据全部取到内存中,构造一个超大的结果集,主要的时间开销是这一步,这一步的时间开销要远远超过JDBC和 Iterator方式下构造结果集的时间开销,并且内存开销也很惊人;而对结果集的遍历操作,速度则是非常的惊人(经过测试,30万记录的内 存遍历不到100ms,由于这一步不受JDBC影响,因此结果可信)。因此,List方式适合于对结果集进行反复多次操作的情况,例如分页显示,往后往前 遍历,跳到第一行,跳到最后一行等等。
(2)、Iterator方式只取记录id到内存中,并没有把所有数据取到内存中,因此构造结果集的时间开销很小,比JDBC和List方式都要少,并且内 存开销也小很多。而对结果集的遍历的操作的时候,Iterator仍然要访问数据库,所有主要的时间开销都花在这里。因此,Iterator方式适合于只 对结果集进行1次遍历操作的情况,并且Iterator方式特别适合于从超大结果集中取少量数据,这种情况Iterator性能非常好
在Hibernate中,术语inverse是反转的意思,在关联关系中,inverse=”false”为主控方,由主控方负责维护对象的关联关系。
inverse 决定是否把对对象中集合的改动反映到数据库中,所以inverse只对集合起作用,也就是只对one-to-many或many-to-many有效(因 为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用,注意一般只在双向关联时才有需要设置inverse)。
(1)、一对多:
通常会在的one一方放弃对多的关系的维护,这样效率会高起来(如老师记住每位学生是件困难的事情,效率是很低的,所以干脆就不记了,这关系由学生来维护,学生记住一位老师是很容易)
所以应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可以不设置inverse属性,因为默认值是false),这说明关联关系由多的一方来维护。
如果要一方维护关系,就会使在插入或是删除”一”方时去update”多”方的每一个与这个”一”的对象有关系的对象。
而如果让”多”方面维护关系时就不会有update操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。
显然这样做的话,会减少很多操作,提高了效率。
注:单向one-to-many关联关系中,不可以设置inverse=”true”,因为被控方的映射文件中没有主控方的信息。
(2)、多对多: 属性在独立表中。inverse属性的默认值为false。在多对多关联关系中,关系的两端 inverse不能都设为false,即默认的情况是不对的,如果都设为false,在做插入操作时会导致在关系表中插入两次关系。也不能都设为 true,如果都设为true,任何操作都不会触发对关系表的操作。因此在任意一方设置inverse=true,另一方inverse=false。
cascade属性的作用是描述关联对象进行操作时的级联特性。因此,只有涉及到关系的元素才有cascade属性。
具 有cascade属性的标记包括
注意:
级联操作:指当主控方执行某项操作时,是否要对被关联方也执行相同的操作。
1、 one-to-one懒加载
一对一的懒加载并不常用,因为懒加载的目的是为了减少与数据库的交互,从而提高执行效率,而在一对一关系中,主表中的每一条数据只对应从表的一条数据库,就算都查询也不会增加多少交互的成本,而且主表不能有contrained=true,所以主表是不能懒加载的。但是从表可以有。实现此种懒加载必须在从对象这边同时满足三个条件:
a)lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
b)Constrained = true ;
c)fetch=select。
注:当fetch设置为join时,懒加载就会失效。因为fetch的作用是抓取方式,他有两个值分别为select和join,默认值为select。即在设为join时,他会直接将从表信息以join方式查询到而不是再次使用select查询,这样导致了懒加载的失效。
2、 one-to-many懒加载
与one-to-one关联不同,对one-to-many而言,主表的每一条属性都会对应从表的多条数据,这个时候懒加载就显得非常有效了。比如一个部门里面有多个员工,如果没有懒加载,每查询这个部门的时候都会查询出多个员工,这会大大增加与数据库交互的成本。所以Hbernate默认的是加入懒加载的。这就是查询集合属性的时候返回的是一个PersistentIndexed*类型对象的原因。该对象其实就是一个代理对象。当然,可以在映射文件中通过将lazy属性设为假来禁用。
Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:
一:设置lazy=”false”;
二:设置fetch=”join”.
实现此种懒加载必须在从对象这边同时满足两个条件:
1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
2、fetch=select。
3、 many-to-one懒加载
此关联关系的懒加载和one-to-one的懒加载一样都是可要可不要的,因为对执行效率的提高都不是非常明显。虽然多对一与一对一关系方式相同,但是在Hibernate中多对一时,默认是进行懒加载的。另外有一点需要注意的是懒加载并不会区分集合属性里面是否有值,即使是没有值,他依然会使用懒加载。实现此种懒加载必须在从对象这边同时满足两个条件
1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
2、fetch=select
4、 many-to-many懒加载
此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的。
实现此种懒加载必须在从对象这边同时满足两个条件:
1、lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy)
2、fetch=select
能够懒加载的对象都是被改过的代理对象,当相应的对象没有关闭时,访问这些懒加载对象的属性(getId和getClass除外)Hibernate会初始化这些代理,或用hibernate.initalize(proxy)来初始化代理对象;当关闭session后在访问懒加载的对象就会出现异常。
◆设置
◆ 如果lazy的属性值为true,那么在使用load方法加载数据时,只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。
注意:在class标签上配置的lazy属性不会影响到关联对象!
① 请求发送给 StrutsPrepareAndExecuteFilter
② StrutsPrepareAndExecuteFilter 判定该请求是否是一个 Struts2 请求
③ 若该请求是一个 Struts2 请求,则 StrutsPrepareAndExecuteFilter 把请求的处理交给 ActionProxy
④ ActionProxy 创建一个 ActionInvocation 的实例,并进行初始化
⑤ ActionInvocation 实例在调用 Action 的过程前后,涉及到相关拦截器(Intercepter)的调用。
⑥ Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。调用结果的 execute 方法,渲染结果。
⑦ 执行各个拦截器 invocation.invoke() 之后的代码
⑧ 把结果发送到客户端
① 过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器。
② Struts2 拦截器只能对 Action 请求起作用,而过滤器则可以对几乎所有请求起作用。
③ 拦截器可以访问 Action 上下文(ActionContext)、值栈里的对象(ValueStack),而过滤器不能.
④ 在 Action 的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
① 基于 MVC 架构,框架结构清晰。
② 使用 OGNL: OGNL 可以快捷的访问值栈中的数据、调用值栈中对象的方法
③ 拦截器: Struts2 的拦截器是一个 Action 级别的 AOP, Struts2 中的许多特性都是通过拦截器来实现的, 例如异常处理,文件上传,验证等。拦截器是可配置与重用的
③ 多种表现层技术. 如:JSP、FreeMarker、Velocity 等
① 与 Servlet API 解耦的访问方式
> 通过 ActionContext 访问域对象对应的 Map 对象
> 通过实现 Aware 接口使 Struts2 注入对应的 Map 对象
② 与 Servlet API 耦合的访问方式
> 通过 ServletActionContext 直接获取 Servlet API 对象
> 通过实现 ServletXxxAware 接口的方式使 Struts2 注入对应的对象
①. struts-default 包是 struts2 内置的,它定义了 struts2 内部的众多拦截器和 Result 类型,而 Struts2 很多核心的功能都是通过这些内置的拦截器实现,如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了truts-default包才能使用struts2为我们提供的这些功能。
②.struts-default 包是在 struts-default.xml 中定义,struts-default.xml 也是 Struts2 默认配置文件。Struts2 每次都会自动加载 struts-default.xml文件。
③. 通常每个包都应该继承 struts-default 包。
exception;fileUpload;i18n;modelDriven;params;prepare;token;tokenSession;validation 等
①. ValueStack 贯穿整个 Action 的生命周期,保存在 request 域中,所以 ValueStack 和 request 的生命周期一样. 当 Struts2 接受一个请求时,会迅速创建 ActionContext,ValueStack,Action. 然后把 Action 存放进 ValueStack,所以 Action 的实例变量可以被 OGNL 访问。请求来的时候,Action、ValueStack 的生命开始;请求结束,Action、ValueStack的生命结束
②. 值栈是多实例的,因为Action 是多例的(和 Servlet 不一样,Servelt 是单例的),而每个 Action 都有一个对应的值栈,Action 对象默认保存在栈顶;
③. ValueStack 本质上就是一个 ArrayList(查看源代码得到);
④. 使用 OGNL 访问值栈的内容时,不需要#号,而访问 request、session、application、attr 时,需要加#号;
⑤. Struts2 重写了 request 的 getAttribute 方法,所以可以使用 EL 直接访问值栈中的内容
① ActionContext Struts2 的 API:是当前的 Action 的上下文环境
② ServletContext 和 PageContext 是 Servlet 的 API
dispatcher、chain、redirect
每个拦截器都是需要实现 Interceptor 接口
> init():在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化;
> intercept(ActionInvocation invocation):每拦截一个动作请求,该方法就会被调用一次;
> destroy:该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次;
① . JSON plugin
② . DOJO plugin
③ . DWR plugin
④ . 使用 Stream 结果类型.
Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用。 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,所以说Struts 2是WebWork的升级版本。基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置,该请求被FilterDispatcher接收。3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。6、返回HTTP响应到客户端浏览器。
一个请求在Struts2框架中的处理大概分为以下几个步骤
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2、 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
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的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
基本简要流程如下:1、客户端浏览器发出HTTP请求。2、根据web.xml配置,该请求被FilterDispatcher接收。3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。6、返回HTTP响应到客户端浏览器。
【参考答案】UI 标签、控制标签、数据标签、杂项标签
【参考答案】
commons-fileupload-1.2.1.jar
freemarker-2.3.13.jar
ognl-2.6.11.jar
struts2-core-2.1.6.jar
xwork-2.1.2.jar
【参考答案】
1) 尽量使用many-to-one,避免使用one-to-many
2) 灵活使用单向one-to-many
3) 不用一对一,使用多对一代替一对一
4) 配置对象缓存,不使用集合缓存
5) 一对多使用Bag 多对一使用Set
6) 继承使用显示多态HQL:from object polymorphism="exlicit" 避免查处所有对象
7) 消除大表,使用二级缓存
1、首先要打开二级缓存,在hibernate.cfg.xml 中添加如下配置:
2、Hibernate 的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个缓存工具。如下配置指定Hibernate 使用EhCache 缓存工具。
3、 Hibernate 在默认情况下并不会对所有实体对象进行缓存,所以,我们需要指定缓存哪些对象,在实体对象的映射文件中(相应的
BeanFactory 实际上是实例化,配置和管理众多bean 的容器。这些bean 通常会彼此合作,因而它们之间会产生依赖,而这种依赖只是体现在Bean 与Bean 之间的依赖这些依赖关系可以通过配置来反映,而ApplicationContext beans 包是BeanFactory 的子类,提供了以编程的方式管理和操控bean 的基本功能,而context 包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory 的功能,简单说他增强了面向Web 容器的功能。ApplictionContext 完全采用声明式方式来使用容器,甚至不用去手工创建它,Web应用的启动进程中用它启动ApplicationContext 。当然用编程的方式创建一个ApplicationContext 对象可以有以下几种方式或实现:
1、ClassPathXmlApplicationContext:从类路径中的XML 文件载入上下文定义信息,把上下文定义文件当作类路径资源。
2、FileSystemXmlApplicationContext:从文件系统中的XML 文件载入上下文定义信息。
3、XmlWebApplicationContext:从Web 系统中的XMl 文件载入上下文信息。
【参考答案】
1、请求处理机制:spring mvc 是基于方法的设计,而sturts 是基于类,每次发一次请求都会实例一个action,每个action 都会被注入属性,而spring 基于方法,粒度更细。
2、参数传递:struts 是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。
3、设计思想上:struts 更加符合oop 的编程思想, spring 就比较谨慎,在servlet 上扩展。
4、intercepter 的实现机制:struts 有以自己的interceptor 机制,spring mvc 用的是独立的AOP 方式。这样导致struts 的配置文件量还是比spring mvc 大,虽然struts 的配置能继承,所以我觉得论使用上来讲,spring mvc 使用更加简洁,开发效率Spring MVC 确实比struts2高。
【参考答案】
最典型的像:工厂模式,Spring 的IOC 容器就是一个大的Bean 实例的工厂,负责Bean的周期管理。单例模式,这个和Spring 的IOC 一起的,既然是IOC 是一个大工厂,那个Bean对象为减少内存开销就需要提供单例特征。适配器模式,在Spring 的AOP 编程中随处可见Adapter 模式的应用。代理模式,为其它对象提供一种代理访问的机制。观察者模式,当对象发生变化时,其它对象需要得到相应更新,Spring 中应用也较为普遍。
【参考答案】
hibernate 查询有三种方式:HQL 查询、结构化SQL 查询、QBC 查询
【参考答案】
DAO 组件主要提供数据库访问操作,针对不同数据源表持久化操作进行了封装,这样可以提供其它层的访问接口,使得组件之间解耦。而BaseDAO 是这些所有这些不同的持久化的DAO 的公共API 进行了封装,进一步抽象提取,使其它各组件DAO 从BaseDAO 中派生,增强系统的重用性、维护性、扩展性。
【参考答案】
ThreadLocal 和其它同步机制相比从另一个角度来解决多线程的并发访问,它为每一个线程维护一个和该线程绑定的变量的副本,从而隔离了多个线程的数据,每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。还提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的整个变量封装进ThreadLocal
ThreadLocal 可以大量减少参数的传递,可以使代码简洁,但一个线程会绑定多个自己定义的局部对象,ThreadLocal 是抽象在线程上的对象创建工厂,目前的Tomcat5 使用了线程池,一个线程处理一个request,这样ThreadLocal 对象可以抽象的绑定在request 生命周期,不会存在线程危机,而且线程池也平衡了这些ThreadLocal
【参考答案】
1、SessionFactory 管理。使用Spring 整合Hibernate 时我们不需要hibernate.cfg.xml 文件。首先, 在applicationContext.xml 中配置数据源( dataSource ) bean 和session 工厂(sessionFactory)bean。
2、持入层管理。Spring 提供了HibernateTemplate,用于持久层访问,无需打开Session及关闭Session。它只要获得SessionFactory 的引用,将可以只读地打开Session,并在持久化访问结束后关闭Session,对持久层逻辑,通用的操作(如对数据库中数据的增,删,改,查)有HibernateTemplate 完成。
3、对DAO 的支持:通过继承HibernateDaoSupport 实现DAO 基本操作。
4、对事务支持:Spring 的声明式事务和编程式事务,很好的将持久化的操作纳入事务管理。
【参考答案】
1.save()方法,调用save 方法时,首先会在session 缓存中查找保存对象如果实体对象已经处于Persient 状态,直接返回;否则并将保存至数据库,对象变为持久状态。
2.saveOrUpdate()方法:和save 方法一样首先在session 缓存中查找,判断对象是否为为保存状态,如果对象处于Persient,不执行操作,处于Transient 执行save 操作,处于Detached 调用saveOrUpdate 将对象与session 重新关联(简单的说就是该方法会先看该对象是否已经存在,如果已经存在就更新,否则新增保存),如果此时saveOrUpdate 的对象与另一个与Session 关联的对象持有相同的持久化标识则抛出相同的标识符异常。
【参考答案】
Session.load/get 方法均可以根据指定的实体类和id 从数据库读取记录,并返回与之对应的实体对象。其区别在于:
1) 如果未能发现符合条件的记录, get 方法返回null , 而load 方法会抛出一个ObjectNotFoundException。
2) load 支持延迟加载,get 不支持
3) load 方法可返回实体的代理类实例,而get 方法永远直接返回实体类。
4) load 方法可以充分利用内部缓存和二级缓存中的现有数据,get 方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL 完成数据读取。
【参考答案】
1、内建Annotation——Java5.0 版在java 语法中经常用到的内建Annotation:
2、开发者自定义Annotation:由开发者自定义Annotation 类型;
3、使用第三方开发的Annotation 类型
【参考答案】
MVC 就是model view controller,三种组件,Struts2 实现Controller 主要由一系列的前端过滤器(Filter)实现Controller。Model 层主要由Struts2 的Action 组件实现。View 层主要是由Struts2 的标签库、Freemarker 等组件实现视图层
【参考答案】
Hibernate 是一个开放源代码Java 语言下的对象关系映射解决方案。它为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架。Hibernate 也是目前Java开发中最为流行的数据库持久层框架。将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,Hibernate 不仅负责从Java 类到数据库表的映射(还包括从Java 数据类型到SQL 数据类型的映射),还提供了面向对象的数据查询检索机制,从而极大地缩短的手动处理SQL 和JDBC 上的开发时间。
调用相同Action 中的不同方法
其中表达式{1}的值name 属性值中第一个*的值。如果用户请求的URL 为loginAction.action,则调用Jcuckoo.LoginRegistAction 中的login 方法;
如果用户请求的URL 为registerAction.action,则调用Jcuckoo.LoginRegistAction 中的register 方法
示例2:带转视图
当处理结果是input 时,会转到/input.jsp 页面当处理结果是success 时,如果crud_create.action,则会执行Jcuckoo.CrudAction 中的create 方法,并且跳
转到/create.jsp;如果crud_delete.action,则会执行Jcuckoo.CrudAction 中的delete 方法,并且跳转到/delete.jsp;
优点:
使用通配符能规范命名格式,简洁配置文件,加速开发效率,也是Struts 倡导的一种开发模式。
【参考答案】
1.QBC(Query by Criteria)查询对查询条件进行了面向对象封装,符合编程人员的思维方式;
2.HQL(Hibernate Query Language)查询提供了更加丰富的和灵活的查询特性,在涵盖Criteria 查询的所有功能的前提下,提供了类似标准SQL 语句的查询方式,同时也提供了更加面向对象的封装。
【参考答案】Hibernate 通过lazy 来指定加载策略,一般值为true 或false,。设为flase 表示立即加载,true 表过延迟加载。
Hibernate 特点:
1. 基于JDBC 的主流持久化框架,是一个优秀的ORM 实现,对JDBC 访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. hibernate 使用Java 反射机制,而不是字节码增强程序来实现透明性。
3. hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
Spring 特点:
Spring 框架的主要优势之一低侵入式的架构思想,实现了IOC 容器。另外一个AOP 的编程也在很多应用场合下地位较重。提供了对各种不同类型框架的支持,如:Web 容器、持入层、事务层、其它J2EE 组件等。
IOC 称为控制反转,也叫依赖注入,ioc 是Spring 的核心组件,它通过配置文件,将需要创建的对象以池的方式管理,将实例注入到需要的对象中区,是对象依赖于注入而不依赖于实现,解决了各个组件的耦合度,使得项目在后期的维护和扩展上非常方便。如在ssh框架整合中,我们将datasource 对象注入给sessionFactory,再将sessionFactory 注入给dao 组件,再将dao 组件注入给struts 的Action 组件,在将action 对象注入给struts的拦截器。
MVC 是Model-View-Controller 的简写。Model 代表的是应用的业务逻辑(通过JavaBean,EJB 组件实现), View 是应用的表示层(由JSP、HTML、各种Taglib 等组成),Controller 是提供应用程序的中心控制处理。通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现,这些组件可以进行交互和重用,另外有利于维护。Struts1、Struts2、Spring MVC、WebWork 等这些都是属于基于MVC 模式实现的框架
内部最核心的就是IOC 了,动态注入,让一个对象的创建不用new 了,可以自动的生产,这其实就是利用java 里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring 的配置文件来动态的创建对象,和调用对象里的方法的还有一个核心就是AOP 这个就是面向切面编程,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的
Spring 目的:
就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring 根据这些配置内部通过反射去动态的组装对象)要记住:Spring 是一个容器,凡是在容器里的对象才会有Spring 所提供的这些服务和功能
Criteria 和DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在线的,所以它是由Hibernate Session 进行创建的;而DetachedCriteria 是离线的,创建时无需Session,DetachedCriteria 提供了2 个静态方法forClass(Class) 或forEntityName(Name)进行DetachedCriteria 实例的创建。
拦截器是AOP 中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用。而Struts2 的Interceptor,其拦截的对象是Action 代码,可以定义在Action 代码之前或者之后执行拦截器的代码。
1. 整个结构就如同一个堆栈,除了Action 以外,堆栈中的其他元素是Interceptor
2. Action 位于堆栈的底部。由于堆栈"先进后出"的特性,而这些都是围绕着Action 的,当我们请求Action 时,必须首先把位于Action 上端的Interceptor 拿出来执行。
1、客户端初始化一个指向Servlet 容器(例如Tomcat)的请求
2 、这个请求经过一系列的过滤器( Filter )( 这些过滤器中有一个叫做ActionContextCleanUp 的可选过滤器,这个过滤器对于Struts2 和其他框架的集成很有帮助,例如:SiteMesh Plugin);
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 的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
spring 的事务传播行为:
Spring 在TransactionDefinition 接口中规定了7 种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED 类似的操作。
Spring 的隔离级别
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。
orm 是一种思想,就是把object 对象转变成数据库中的记录,或者把数据库中的记录转变成object 对象,我们可以用jdbc 来实现这种思想,orm 的思想本质就是建立是JDBC 上,对JDBC 的一种封装,这种封装可以省去了直接使用jdbc 的繁琐细节,提高了开发效率,现在用的较多的ORM 工具很多,一般我们公司采用的ORM 框架主要有hibernate 和MyBatis。当然也听说一些其他orm 工具,如toplink,ojb 等。
【参考答案】
AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-OrientedPrograming,面向对象编程)的补充和完善。OOP 引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力。也就是说,OOP 允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能,日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。而AOP 技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP 代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。使用“横切”技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。实现AOP 的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
1.Spring 实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory ( 实际上是一个接口), 在程序中通常BeanFactory 的子类
ApplicationContext。Spring 相当于一个大的工厂类,在其配置文件中通过
2. Spring 提供了对IOC 良好支持,IOC 是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。IOC 也称为DI(Depency Injection)。
3. Spring 提供了对AOP 技术的良好封装, AOP 称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP 功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK 中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice 对象进行提供,显然要创建出代理对象,至少需要目标类和Advice 类。
1) Servlet 依赖性
由于Action 在被调用时,HttpServletRequest 和HttpServletResponse 被传递到execute()方法中,Struts1中的Action 对Servlet 的API 是有依赖性的.但如果在Struts2中,Action 就不会对容器有依赖了,因为Action 是由简单的POJO 组成的.在Struts2中,servlet 上下文以简单的Map 的形式表现出来,这使得Action 可以得到独立的测试.如果需要,Struts2也可以访问原始的请求与响应。不过,其他的框架元素减少或排除直接访问HttpServetRequest 或HttpServletResponse 的必要。
2) Action 类
使用抽象类而不是接口设计是Struts1设计上的问题,这已经在Struts2中得到了解决.Struts1中的Action 类需要继承框架中依赖的抽象基础类.但在Struts2中,Action 类可能会也可能不会实现接口来启用可选的或者自定义的服务.在Struts2中,Action 是不会依赖于容器的,因为它是由简单的POJO 组成的.Struts2提供了一个基础的ActionSupport 类来实现一些常用的接口。尽管这样,Action 接口仍然不是必须要继承的,任何含有execute 方法的POJO 对象都可以当作Action 对象来用。
3) 验证
Struts1与Struts2都支持通过validate 方法的手动验证.Struts1使用ActionForm 中的validate 方法或者通过扩展Commons Validator 来进行校验.然而,Struts2支持通过Validate 方法与Xwork 校验框架的手动验证. Xwork 框架支持验证链到子属性----使用为属性类文件和校验上下文定义的验证.
4) 线程模型
在Struts1中,Action 资源一定是线程安全或者同步的.所以Action 是singletons 并且线程安全的,一定只有一个Action 类的实例处理该Action 的所有请求,singleton 策略限制了Struts1的Action 所能完成的,并且需要更加谨慎的开发.但是在Struts2中,Action 对象对每一个请求都生成实例,所以在Struts2中不存在线程安全的问题。
5) 易测性
测试Struts1的程序会有些复杂.测试Struts1 Action 的主要它依赖容器。但是在Struts2中,Action 可以经由创建Action 的实例,设置属性和调用方法来得到测试。Struts2中的测试是很简单的,不依赖于容器。
6) 获取输入
Struts1使用ActionForm 来捕获输入,而且所有的ActionForm 需要继承一个框架依赖的基类.由于JavaBean 不能当作ActionForm 来用,开发人员不得不创建冗繁的类来获取输入.不过Struts2使用Action 属性(例如输入属性不依赖于底层框架)这避免了需要创建第二个输入对象,从此冗繁减少了.此外在Struts2中,Action 的属性可以通过标签在web 页面中得到访问,POJO 表单对象和POJO Action.甚至富对象类型,包括业务或域对象,都可以被当作输入/输出对象来使用。
7) 表达式语言
Struts1与JSTL 整合,所以它使用JSTL 表达式语言.Struts1的表达式语言含有遍历图表的基础对象,但是在集合和索引属性的支持上表现不好.Struts2同样支持JSTL,但是它也支持一种更强大且灵活的表达式语言----“对象图标记语言”(OGNL)
8) 将绑定值到视图中
在视图层,Struts1使用标准的JSP 来绑定对象(在模型层被处理的)到页面上下文来进行访问.然而Struts2使用一种叫做值栈的技术,这使得标签可以访问值而不需将视图与正在呈递的对象类型连接起来.值栈允许重用一些属性名相同但类型不同的视图类型.
9) 类型转换
通常Struts1的ActionForm 属性都是String 型的。Struts1使用Commons-Beanutils进行类型转换,这些针对每一个类的类型转换无法为每一个实例配置。然而Struts2使用OGNL 来进行类型转换.框架包含了针对基础类型,常见对象类型与原始类型的转换器。
10) Action 的生存周期
Struts1支持对每一个模块的请求处理器的分离(生命周期),但是同一模块下的所有Action 必须共享相同的生命周期。Struts2支持通过拦截器栈为每一个Action 创建不同的生命周期.自定义栈可以视需要对不同的Action 使用.
1、封装了jdbc,简化了很多重复性代码。
2、简化了DAO 层编码工作,使开发更对象化了。
3、移植性好,支持各种数据库,如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate 代码。
4、支持透明持久化,因为hibernate 操作的是纯粹的(pojo)java 类,没有实现任何接口,没有侵入性。
在Hibernate 中,术语inverse 是反转的意思,在关联关系中,inverse="false"为主控方,由主控方负责维护对象的关联关系,如果设为主控方对象,主控对象更新,则负责更新另一方对象更新。
依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某一个Java 类,需要另一个Java 类的协助时,在传统的程序设计过程中,通常由当前类(调用者)来创建被调用者的实例,然后使用被调用者的方法。但在Spring 里,创建被调用者的工作不再由调用者来完成,而是由其它类(往往是工厂类)或容器(Spring IOC容器)完成,当前调用者从其它类或容器中来获取被调用者的实例,这种方式称为控制反转;创建被调用者实例的工作通常由Spring 容器来完成,然后注入调用者,因此也称为依赖注入,这是Spring 的一种编程思想的体现。依赖注入在设计模式也体现得非常多,比如说工厂模式和构建模式,这种就是一个依赖
注入的实现
JDO 是Java 对象持久化的新的规范,为java data object 的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO 提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API 的使用)。这些繁琐的例行工作已经转移到JDO 产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC 只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML 以及对象数据库(ODBMS)等等,使得应用可移植性更强。
1) 提供商无关性
EJB 3.0 是一个被设计为对提供商没有依赖性的开放的标准。EJB 3.0 规范由企业JAVA社区的主流开源组织和厂商共同编写和支持的。EJB 3.0 框架使开发者的应用程序实现可以独立于应用服务器。而Spring 一直是一个非标准的技术,尽管你在任何应用服务器都上可以使用Spring 框架,但基于Spring 的应用仍然被限制于Spring 本身和在你的应用中使用到的Spring 提供的各种特别服务。
2) 服务整合
Spring 框架是建立在应用服务器和服务库之上,它的服务整合代码(如数据访问模板和Helper 类)是基于框架的,并暴露给应用开发者。相反,EJB 3.0 框架是紧密整合到应用服务器中的,它的服务整合代码是封装在一个标准的接口下的。
3) 服务聚合的灵活性
由于Spring 中的服务整合代码是作为编程接口暴露给应用开发者的,因此开发人员可以根据需要来聚合多个服务。这个特性使你可以集成一个你自己的“轻量”级应用服务器。通常,EJB 3.0 应用服务器不提供给开发者这种按照你的需要来选择服务的灵活性。大多数情况,你会得到一系列已经预先打包好的特性,其中有些你可能是不需要的。
4) 声明式服务
EJB 3.0 和Spring 都将运行时服务(如事务管理、安全、日志、消息、和信息服务)连接给应用程序。由于这些服务同应用程序的业务逻辑并不是直接相关的,因此,它们不被应用程序本身来管理。相反,这些服务被服务容器(如EJB 3.0 和Spring)以不可见的方式在运行时提供给应用程序。开发人员(或系统管理员)通过配置来告诉容器什么时候,以怎样的方式来应用这些服务。
5) 注射依赖
Spring 和EJB 3.0 都提供了大量的DI 模式支持。但是,它们之间也有着根本的不同。Spring 支持了通常意义上的但是复杂的基于XML 配置文件的注射依赖API;EJB 3.0 支持的注射大多数通用服务对象(如,EJB 和容器对象)和JNDI 对象,它通过简单的JAVA 注解来完成。
1.struts 第一个优点应该是实现了MVC。对Servlet 依赖减少,低侵入式的设计
2.Action 线程安全的设计
3.功能强大的OGNL 表达式使用。
4.支持多种复合视图,表现层的使用也多样化,像JSP\freeMarker\Velocity。
5.拦截器的应用,实现了AOP 的思想,方便重用与扩展
6.自动类型转换功能。
7.相对低粗度的数据验证功能
Struts 缺点:
Struts2 中Action 中取得从jsp 中传过来的参数时,如果页面过于复杂,会造成对象臃肿。
Spring 优点:
1、非常优秀的轻量级,低侵入式的框架。
2、IOC 的容器周期式的管理,降低组件的偶合。
3、对其它容器有非常好的支持,像对持久层的Hibernate、Ibaits、TOP Link等。
Spring 缺点:
1.Web 层的MVC 框架单过于单薄,对页面框架的支持,跟其它框架还有很大的差距。
2.不是一站式解决方案。
3.使用了反射来管理其容器中的bean,在程序中增大了内存和运行计算的时间。
4.部分组件功能还有待完善
Hibernate 的优点:
1、非常好的ORM 的框架,在MVC 的切分和JDBC 的封装上做的很好。
缺点:
1、对复杂查询,多变的查询,完成起来有难度。
2、自动化程序高,改写灵活性不够。
2、缓存不是太高效,所以有些企业单独会选择缓存框架或者弃用Hibernate 的原因之一。
3 种方法。构造属入、属性注入、接口注入
1) 客户端所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2) DispatcherServlet 查询一个或多个HandlerMapping,找到处理请求的Controller.
3) DispatcherServlet 请请求提交到目标Controller
4) Controller 进行业务逻辑处理后,会返回一个ModelAndView
5) Dispathcher 查询一个或多个ViewResolver 视图解析器,找到ModelAndView 对象指定的视图对象
6) 视图对象负责渲染返回给客户端。
BeforeAdvice (前织入)、AfterAdvice (后织入)、ArroundAdvice (前后织入)ThrowAdvice (异常织入)
【参考答案】
scope 表示Bean 的生命周期或者叫Bean 的作用域。scope 的值有两个:
1、singleton,为单例属性,即Spring IoC 容器只会创建该bean 的唯一一个实例,这也是默认的。
2、prototype 为原型属性,即每一次请求都会产生一个新的bean 实例。
共3 种状态,分别是:Transient 状态(瞬时)、Persient 状态(持久)、Detached(脱管状态)状态。
解决Hibernate 的Session 的关闭与开启问题。
SSH 整合问题:Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个Hibernate Session 范围之内进行。如果Service 层返回一个启用了延迟加载功能的领域对象给Web 层,当Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常。而Spring为我们提供的OpenSessionInViewFilter 过滤器为我们很好的解决了这个问题。OpenSessionInViewFilter 的主要功能是用来把一个Hibernate Session 和一次完整的请求过程对应的线程相绑定,允许在事务提交之后延迟加载显示所需要的对象。实现"Open Session in View"的模式
Configuration 接口,SessionFactory 接口,Session 接口,Transaction 接口,Query 和Criteria接口
主要有单向一对一、单向一对多、单向多对一、单向多对多、双向一对一、双向一对多、双向多对多。
缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。Hibernate 的Session 就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session 从数据库中查询出一个对象时,Session 也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session 代表一次会话过程,一个Session 与一个数据库连接相关连,所以Session 最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session 是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate 的Session 这一级缓存的缓存作用并不明显,应用价值不大。Hibernate 的二级缓存就是要为Hibernate 配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。一般我们叫它sessionFactory 缓存,也叫进程级的缓存,使用第3 方插件实现的,也值缓存实体,生命周期和sessionFactory 一致,可以进行管理。
二级缓存具体实现:
首先配置第3 放插件,我们用的是EHCache,在hibernate.cfg.xml 文件中加入
在映射中也要显示的调用,
主要配置Spring Web 监听器
cascade 属性的作用是描述关联对象进行操作时的级联特性。可以有以下几种取值:
all : 所有情况下均进行关联操作。
save-update:(级联保存) 表明保存或更新当前对象时会级联保存或更新他所关联的对象。
none:所有情况下均不进行关联操作。这是默认值。
delete :(级联删除) 级联删除所关联的对象。
all-delete-orphan:自动删除不再和父对象关联的子对象。并且,在出现上面两种情况时执行上面两种的功能,可以说是一个全自动的属性值。
优点:
1) 实现MVC 模式,结构清晰,使开发者只关注业务逻辑的实现.
2) 有丰富的tag 可以用,Struts 的标记库(Taglib),如能灵活动用,则能大大提高开发效率
3) 页面导航
4) 使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
5) 提供Exception 处理机制。
6) 数据库链接池管理。
7) 支持I18N (国际化)
缺点
1) 转到展示层时,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每
2) Struts 的Action 必需是thread-safe 方式,它仅仅允许一个实例去处理所有的请求。所以action 用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
3) 测试不方便. Struts 的每个Action 都同Web 层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现
4) 类型的转换. Struts 的FormBean 把所有的数据都作为String 类型,它可以使用工具Commons-Beanutils 进行类型转化。但它的转化都是在Class 级别,而且转化的类型是不可配置的。
5) 对Servlet 的依赖性过强. Struts 处理Action 时必需要依赖ServletRequest 和ServletResponse,所有它摆脱不了Servlet 容器。
6) 前端表达式语言方面集成了JSTL,所以它主要使用JSTL 的表达式语言来获取数据。可是JSTL 的表达式语言在Collection 和索引属性方面处理显得很弱。
7) 对Action 执行的控制困难. Struts 创建一个Action,如果想控制它的执行顺序将会非常困难。
8) 对Action 执行前和后的处理. Struts 处理Action 的时候是基于class 的hierarchies,很难在action 处理前和后进行操作。
9) 对事件支持不够. 在struts 中, 实际是一个表单Form 对应一个Action 类(或DispatchAction),换一句话说:在Struts 中实际是一个表单只能对应一个事件。
1.第一种方法:
Struts 的Action 继承Spring 的ActionSupport 类,并在Action 中获取Spring 的ApplicationContext。这是最简单的一种整合方式,但有三个缺点:第一,Struts 与Spring紧密耦合,不能改换到其他IoC 容器;第二,难以使用Spring AOP 特性;第三,对于需要使用DispatchAction 的Struts 应用无能为力。
2.第二种方法:
在Struts 的配置文件中,以Spring 的DelegatingRequestProcessor 类代替Struts的RequestProcessor 类, 并在Spring 的配置文件中定义与Struts 配置文件中
3.第三种方法:
通过Spring 的DelegatingActionProxy 类代理Struts 的动作,即在Struts 配置文件中,定义
【参考答案】
1.ActionServlet 核心控制器会拦截所有*.do 的请求
2.从struts-config.xml 中找到用户请求的Action
3.通过struts-config.xml 中的配置再去找这个Action 对应的ActionForm,并实例化
4.把用户填写的数据自动填充到ActionForm 中(调用ActionForm 中的setXX()方法填充)
5.同时把ActionForm 放入到指定的范围中(request,session)
6.然后把请求转发给Action
7.Action 获取ActionForm 中的值然后调用业务逻辑层实现功能
8.在通过ActionMapping 查找Actionforward 实现转发;
【参考答案】
中心控制器,负责所以请求处理,并根据配置文件,将请求转到指定Action 执行,并根据Action 的ActionForward 返回,转到指定视图。
【参考答案】
a. Actionservlet 为控制器,接受用户请求并派发给相应的Action 组件处理;
b. ActionForm 主要用于封装请求中的数据和简单验证
c. Action 组件具体对用户的请求进行处理
d. ActionMapping 封装当前用户请求Action 相关的配置信息
【参考答案】
Struts 1 要求Action 类要扩展自一个抽象基类。Struts 1 的一个共有的问题是面向抽象类编程而不是面向接口编程。Struts 2 的Action 类实现了一个Action 接口,连同其他接口一起实现可选择和自定义的服务。
Struts 1 Action 类是单例类,因只有一个示例控制所有的请求。
Struts 2 Action 对象每一个请求都实例化对象,所以没有程安全的问题。
【参考答案】
1. struts 是一个按MVC 模式设计的Web 层框架,其实它就是一个大大的servlet,这个Servlet 名为ActionServlet,或是ActionServlet 的子类。我们可以在web.xml 文件中将符合某种特征的所有请求交给这个Servlet 处理,这个Servlet 再参照一个配置文件(通常为/WEB-INF/struts-config.xml)将各个请求分别分配给不同的action 去处理。
2. ActionServlet 把请求交给action 去处理之前,会将请求参数封装成一个formbean对象(就是一个java 类,这个类中的每个属性对应一个请求参数)
3.要说明的是, ActionServlet 把formbean 对象传递给action 的execute 方法之前,可能会调用formbean 的validate方法进行校验,只有校验通过后才将这个formbean 对象传递给action 的execute 方法,否则,它将返回一个错误页面,这个错误页面由input 属性指定,(看配置文件)作者为什么将这里命名为input 属性,而不是error 属性,我们后面结合实际的运行效果进行分析。4.action 执行完后要返回显示的结果视图,这个结果视图是用一个ActionForward 对象来表示的,actionforward 对象通过struts-config.xml 配置文件中的配置关联到某个jsp页面,因为程序中使用的是在struts-config.xml 配置文件为jsp 页面设置的逻辑名,这样可以实现action 程序代码与返回的jsp 页面名称的解耦
【参考答案】
Servlet 是在多线程环境下的。即可能有多个请求发给一个servelt 实例,每个请求是一个线程。struts 下的action 也类似,同样在多线程环境下。为多线程环境编写代码。我们的controller servlet 指挥创建你的Action 类的一个实例,用此实例来服务所有的请求。因此,你必须编写线程安全的Action 类。遵循与写线程安全的servlet 同样的方针。
【参考答案】
属于视图层组件,负责封装页面表单数据。
【参考答案】
ActionServlet 组件:充当struts 框架的中央控制器。
RequestProcessor 组件,充当每个子应用模块的请求处理器
Action 组件,负责处理一项具体的业务。
【参考答案】
操作系统磁盘缓存->减少磁盘机械操作数据库缓存->减少文件系统I/O应用程序缓存->减少对数据库的查询Web 服务器缓存->减少应用服务器请求客户端浏览器缓存->少对网站的访问
一般分为持久层(DAO 层)、业务层(Service 层)、控制层、视图层;事务一般放在业务层,以一个业务作为一个事务分割的最小单位。
EJB 包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT 等技术实现EJB 是一个关于用JAVA 语言开发的可部署的服务器端组件的组件体系结构。它是一个技术协议,能使组件运行于任何应用服务器,专门用来解决商务问题JAVABEANS 是JAVA 类,是由属性、事件和方法组成的JAVA 组件,它们可以用来组成JAVA 应用程序Java Bean 是可复用的组件,对Java Bean 并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean 是被容器所创建(如Tomcat)的,所以Java Bean 应具有一个无参的构造器,另外,通常Java Bean 还要实现Serializable 接口用于实现Bean 的持久性。Java Bean 实际上相当于微软COM 模型中的本地进程内COM 组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java 的远程方法调用(RMI)技术的,所以EJB 可以被远程访问(跨进程、跨计算机)。但EJB 必须被布署在诸如Webspere、WebLogic 这样的容器中,EJB 客户从不直接访问真正的EJB 组件,而是通过其容器访问。EJB 容器是EJB 组件的代理,EJB 组件由容器所创建和管理,客户通过容器来访问真正的EJB 组件。
跨平台的可互操作性跨防火墙的通信应用程序集成软件和数据重用。
事务(Transaction)是数据库管理系统提供的基本功能之一,可以把完成用户一个特定工作的一组操作看作是一个不可拆分的工作单元,所以事务也就是作业或任务。
JDBC:支持单一数据库连接事务JTA:支持分布式事务
Web Service 主要是为了使原来各孤立的站点之间的信息能够相互通信、共享而提出的一种接口。Web Service 所使用的是Internet 上统一、开放的标准,如HTTP、XML、SOAP(简单对象访问协议)、WSDL 等,所以Web Service 可以在任何支持这些标准的环境(Windows,Linux)中使用。注:SOAP 协议(Simple Object Access Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML 的通讯协议。在此协议下,软件组件或应用程序能够通过标准的HTTP 协议进行通讯。它的设计目标就是简单性和扩展性,这有助于大量异构程序和平台之间的互操作性,从而使存在的应用程序能够被广泛的用户访问。
J2EE 性能的优化包括很多方面的,要达到一个性能优良的系统,除了关注代码之外,还应该根据系统实际的运行情况,从服务器软硬件环境、集群技术、系统构架设计、系统部署环境、数据结构、算法设计等方面综合考虑来优化。一般程序级别的优化首先考虑做数据缓存,数据库方面全做表的切割、数据分区、索引等这些方面来加快对数据的访问。
BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i Application Server,jBoss
Spring是一个开源的控制反转和面向切面的容器框架。
Spring包含依赖注入容器、AOP实现、DAO/ORM支持、Web集成等。
解耦合、提供各种服务(事务管理、消息服务)、单例模式支持、AOP技术可以很容易的实现权限控制、监控等、很多辅助类加快应用开发、对各大主流的应用框架提供了集成支持。
代码管理的事务处理、容器管理的事务处理;
并不直接管理事务、将事务管理委托给事务管理器;
声明式事务
传播行为、隔离级别
动态生成代理、可以和任何实现接口的目标对象融合
save完一个对象后,由于有这个过滤器,spring会把这个连接放到线程池里面,而不是马上关闭。当需要延迟加载的时候,spring会从线程池里面取出那个session完成加载的动作,当确定这个session确实不再需要的时候,spring才会close掉这个session
有编程型(事务量比较少)与声明型事务(aop)
1 不同平台下的有不同事务管理器
2 加功能的代码写在通知类中,spring已经提供了环绕通知,事务拦截器TransactionInteceptor
3 专门提供了一个类TransactionProxyFactoryBean生成事务代理类,该类内部持有事务拦截器TransactionInteceptor,只需注入
事务管理器与目标类即可
事务的7大传播属性 required(有就使用没有就建立一个) required_new(有没有都创建一个) support(支持) not_suppot(不支持) never(不支持,有事务管理器还报错) 嵌套
spring mvc的配置文件与ContextLoaderListener加载的包含service层 dao层实例的配置文件最好分开
aop aspect oriedted program 面向切面(方面)编程,在不改变源代码的基础上给目标类加上一些非业务性功能,如事务,日志,权限,需要给目标类生成代理类,生成代理类的技术有面向接口的jdk动态代理以及面向具体类的cglib技术(jdk通过接口实现,cglib通过继承来实现),加功能的代码写在通知类中,有五种 通知类,前置通知
后置通知,环绕通知,异常通知,最终通知,给代理类注入目标类和通知类,客户操纵的是代理类,想更精确的切入,使用切入点,例如
如果想把功能切入到哪些包下的哪些类的哪些方法需要aspectJ切入点表达式. exucution( * com.lxit..*.add(..) ) //修饰符? 返回值 类全名.方法名(..) 异常?
连接点是某个方法的调用或者异常的抛出,连接点的集合就是切入点
aop好处 源代码的无关性,低侵入式设计
项目中怎么用
1 事务 2 日志 3 权限
1 事务
1 配置事务管理器,不同的平台有不同的事务管理器,如DataSourceTransactionManager,HibernateTransactionManager,JPATransactionManager
2 使用
3 在需要事务的类或方法上使用@Transactionnal
日志
struts2的拦截器就是一个环绕通知 我们可以把消息通知写在invoke前后,怎么就是aop了 aop 是没有修改源代码的情况下加功能 加功能的代码写在通知类中
view发送请求---- 核心控制器DispathcerServlet--- hangldermapping(映射器)(类型转换,数据封转,数据检验,异常处理等)
-----------业务控制器-调用m层----
modelAndview(String)-----视图解析器(内部资源视图解析器)-- -视图层使用标签国际化展示数据
1 映射器 hangldermapping 定位action,使用@requestmapping
2 类型转换
1 实现convert接口
2 定义类型转化器服务工厂类FormattingConversionServiceFactoryBean ,注入我们的类型转换器
3 使用
3 数据封转 参数封转 使用对象或者是model
4 数据检验 jsr303校验
1 引入jsr303的校验实现者,如hibernate,
2 在参数对象上标上@valid注解,校验错误放在紧跟对象后的bindResult,
之后根据bindResult是否有校验错误进行相应的跳转
3 在校验的实体类中编写jsr303的注解校验 如notnull length eamli
5 值绑定到页面 model
6 视图解析器---内部资源视图解析器,xml视图解析器等,采用链式解析
7 国际化
1 定义id为messageSource的bean,注入国际化资源文件基础名
2 定义LocaleChangeInteceptor拦截器,拦截local参数,使用mvc:interceptors引入拦截器
3 语言环境放到哪里,如session作用域
1
1 在数据封装方面 ,spring3mvc方法级别 struts2 类级别 spring3mvc开发效率高于 struts2
2 spring3mvc 注解版基本上是零配置
3 springmvc与spring是一家人,兼容性好
4 struts2 存在安全漏洞
可以通过ongl表达式 格式化硬盘
使用重定向定位到钓鱼网站
1 @Controller 标注为spring容器的中的bean 做为c
2 作用域注解 有五大作用域: 原型 单例 request session 全局session
3 @RequestMapping 访问路径,可以用在类或者方法上 访问路径类/方法
4 @responsebody 返回字符串,一般用于返回json格式
5 @ModelAttribute 放入request作用域
6 @SessionAttributes 值能用在类上
7 @requestParam 主要用于数据封装时,页面的参数名与方法参数不一致时
8 @pathVarible 主要用于获取路径变量的值
1 对jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,
使用daoSupport方便获取模板
2 给模板类注入数据源,之后使用模板类的api进行数据操作
优点: 易于上手和掌握
sql写在xml里,便于统一管理和优化
解除sql与程序代码的耦合
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql
缺点: 可读性低,调试非常困难,非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接
ibatis:
SqlMapClientBuilder: 加载配置文件,返回一个会话
SqlMapClient: 具体的会话
SqlSession: 对数据的增删查改
SqlMapSession: 进行数据库操作
SqlSessionManager: 创建SqlSesstion的对象
SqlMapTransactionManager: 定义事务管理功能
Mybatis:
SqlSessionFactory 每个MyBatis应用的核心
Hibernate是全自动化的,只要配置映射文件,可以为我们动态的生成sql
ibatis是半自动化的,需要我们手动的编写sql,ibatis简单易学
Hibernate比较复杂,ibatis可以细粒度的优化,而Hibernate是根据映射文件进行优化
1.在sqlMapConfig的配置文件中进行数据库连接的配置。
2.在sqlMapConfig的xml配置文件中引用sqlMap的xml配置文件。
3.在sqlMap的xml配置文件中进行SQL文件的配置。(文件名称随意,一般是javaBean的类名加xml。)
4.通过SqlMapClient生成具体的操作,用来操作sqlMap配置文件中SQL文件的IBATIS对象。
5.SqlMapClient对象提供函数,函数的参数对应替换sqlMap配置文件的id,parameter等属性,完成SQL文件的执行
(1)#号它会将传进来的数据都当成一个一个字符串,会给数据加一对双引号,而$号它会将传进来的数据直接显示生成到sql中
(2)#号能够防止sql的注入,而$号无法防止sql的注入
(3)$方式一把用于传入数据库对象,比如表名
1 wsdl文件地址,根据该文件通过myeclipse webservice视图进行访问进而拿到soap协议
2 使用HttpUrlConnection进行网路连接,使用conection中的输出流发送soap协议,返回值也是一个soap协议,用conection中的输入流接,进行解析(dom sax stax)
1 wsdl web service description language 网络服务描述语言
wsdl 作用
1 提供了, 服务的访问地址,服务的绑定协议
2 wsdl生成客户端访问代码
3 wsdl 用过myeclipe工具获取soap协议
wsdl 7大元素
1 servides:服务的集合
2 port:单个服务访问点
3 porttype:相当于接口
4 operation: 操作 相当接口中的方法
5 message :方法中的参数以及返回值
6 type:数据类型
7 binding:协议
2 soap
简单对象访问协议 本质上就是xml格式 xml是国际工业标准的数据交换格式,所以会跨平台跨语言,其格式如下
信封
信封头 (加密的时候用到)
信封body
方法
参数
有一个场景,你的项目中有一个类中的某方法,公司有5个项目都要调用,最好的方式暴露成webservice
用的cxf技术,与spring结合较好,使用jdk中的jax-ws语法,那么如何把spring容器中的bean暴露成webservice
1 cxf技术 它使用 jax-ws的语法
2 接口类 使用@WebService注解 实现类 使用@WebService注解指定接口
3 配置CXFServlet,使得服务器启动时发布webservice
4 在spring配置文件中 导入cxf支持spring的3个文件
5 配置jaxws命名空间endpoint 发布spring中的bean,主要指定实现类,即#bean的id,以及地址
1 公共模块 数据交换 数据中心 五表权限
2 流程审批
3 便民服务 天气预报 手机号码归属地查询
webservice安全 以及大数据量
大数据量 在cxf框架中
1 快速信息集 @FastInfoset 2 对返回的数据进行压缩 @GZIP
2 数据缓存,它需要编写代码来实现
实际使用中,多线程下载文件的方式,webservice把数据打包到压缩文件,比较本地的文件名与时间,决定是否从远程服务端下载文件
1 使用拦截器技术,配置用户名以及密码,本质上是对soap-header信封头进行加密
服务端: 发布spring中的bean成webservice,配置inInterceptors 配置拦截器WSS4JInInterceptor,注入服务端密码验证类,该类实现了CallbackHandler
客户端:配置outInterceptors,配置out拦截器WSS4JOutInterceptor,注入客户端验证类
密码验证类实现 CallbackHandler
2 带证ca认证 配置 tomcat https http+Security
soa Service-Oriented Architecture 面向服务架构 WebService是soa一种实现。
1 ejb是sun公司java的一种规范,webservice是跨语言的
2 webservice 是通过http协议发送soap协议,ejb是jndi访问,底层协议rmi-iiop
3 可以把ejb暴露成webservice
1 dao data access object 数据访问对象 持久化层,主要用来进行数据操作的,经常成为dao模式
2 优点
1 数据访问独立到了一层,分层 ,易于分工,可重用
2 修改具体的dao层实现类,不会影响到其他层,实现松耦合
3 dao的结构 四大组件
1 doa接口
2 dao实现类
3 pojo(plain old java objecct)类
4 dao定位( 如何获取实例 spring)
4 常用的dao技术
jdbc spring的dao 以及orm(ibatis mybatis hibernate)
1 步骤手写
1 加载驱动 Class.forName("oralce.jdbc.driver.OracleDriver");
2 获取数据库连接 Connection connection=Drivermanager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","aaa","aaa");
3 创建statement Statement statement= connection.createStatement();
4 执行sql statement.executeQuery(sql);
5 处理ResutlSet结果集---手动转成javabean
6 关闭 ResutlSet statement Connection
2 3个statement
1 Statement 一边编译边执行
2 PrepareStatement 预编译,效率高,安全,阻止sql攻击,支持占位符
3 CallableStatement 调用存储过程
PrepareStatement继承Statement,CallableStatement 继承PrepareStatement
1 对jdbc进行了封装,提供了两大模板技术封装了jdbc步骤,数据源的实现,行映射器进行记录与对象的转换工作,
使用daoSupport方便获取模板
2 给模板类注入数据源,之后使用模板类的api进行数据操作
1 orm object relaction mapping 对象关系映射,解决面向对象与关系数据库不匹配的技术,对jdbc进行了封装,
使得我们可以使用面向对象的思维操纵数据库。使用缓存与懒加载技术提高效率
2 常见的orm框架有ibatis mybatis hibernate
mybatis与hibernate
1 mybatis 半自动需要手动编写sql, 灵活控制sql,方便sql优化,代码量增加,不易移植, 也叫sql映射、不方便移植
2 hibernate 全自动,自动生成sql, 方便移植,也叫对象映射、方便移植
3 hibernate 与jdbc
1 hibernate封装了jdbc,使得我们可以使用面向对象的思维操纵数据库
2 hibernate 全自动,自动生成sql, 方便移植,也叫对象映射、方便移植
3 jdbc效率最好
1 iBATIS3.0以后到goole公司了,更名为mybatis
2 mybatis增加了接口绑定
3 传值方式由##---#{} $:解析数据库的关键字 %:模糊查询
4 mybatis核心类SqlSessionfactory SqlSeession ibatis sqlMapclient
5 使用ognl表达式,体现在动态sql上
6 配置的改变,如别名的配置,mybatis移动到了总配置文件中
1 load与get
load 支持懒加载,没找到数据时报异常,get不支持懒加载,没找到数据时返回null
2 list() 和 iterate()
list:查询缓存不存在时,一条sql去数据库把所有数据加载,填充一级缓存,二级缓存
iterate:去数据线加载id,根据id去缓存查询,如果缓存没有,以id为条件到数据库查询数据,会造成n+1次查询
由于list或填充缓存,而iterate会使用缓存,因此第一次使用list,之后使用iterate可提高效率
3 saveOrUpdate与merge
1 merge不会使对象变成持久化状态
2 缓存中存在相同id的实体,saveOrUpdate会报错,merge会合并
1 懒加载 真正需要数据的时候才向数据库发送sql,比如调用load方法,不会发出sql,而在加载对象属性时才发出了sql,实现了数据的延迟加载,get则不然
2 使用openSessionInView模式解决,实则是一个过滤器,保持session一直在view一直打开
1 session范围扩大,从dao扩展到了其他的层,session所暂用的资源不能得到及时的释放,效率下降
2 事务扩大了
1 使用
1 hibernate缓存
一级缓存 内置的 调用session api如(save saveopupdate load等)会hibernate会把实体放入一级缓存 session级别缓存
二级缓存 可配置的 sessionFactory级别缓存,为所有session共享
1 打开二级缓存开关
2 指定哪种缓存 如 EHCache
3 指定哪些实体要放入二级缓存
查询缓存 :命中率较低 比较少用
2 ibatis 在映射文件配置Cachemodel
3 mybatis 在映射文件配置Cache,实体类实现序列化
2 优点与缺点
1 减少应用程序对数据库的访问次数,提高效率
2 数据量大时导致内存溢出
3 容忍无效的数据(缓存里的数据有可能是过期的),经常修改的数据不适合放入缓存中
3 缓存中配置一些什么东西