第一:概念
1.一个变量(session)多个线程访问就会出现线程安全问题,因为就要求给每个线程都复制一份该变量(产生副本)。
2.每个线程(session获得的事务)对象里面都有个map集合用于保存当前线程所用到的所有变量,也就是当前线程作为键,当前session作为值
3.项目是多线程的(多个请求),因此要保证每个请求(线程)都对应一个session。因此要把当
前session保存到当前正在执行的线程中(键是线程id,值是session)
4.打印当前线程的时候,里面打印的其实就是一级缓存(session),因为session就是个键值对
5.使用过滤器,目的是延长session的声明周期,即使项目中有延时加载,此时也能正常输出。注意过滤器的使用顺序,放在最上面。
6.增删改都用query。exectuteupdate
7.struts的jar包在myeclipse的安装目录中,选择一个jar找到计算机中去查。用于批量删除。
----------------
代理模式,单例模式(懒汉),等
open session in view :让session能在jsp页面也能用,就是扩大session的范围。思想就是使用过滤器,在请求进入服务器之前执行
注意:过滤器的特点是在发送请求的时候产生,结束响应的时候销毁。其实就是在到服务器端之前先进入过滤器。
-----------------
课后练习小项目:
1.首先,我用的是员工表和部门表之间的主外键关系,但是员工表和项目表也有一对一关系,通过反向生成的方法生成了实体类和映射文件之后要把员工表中有关项目表的属性删掉。此时保证了只是员工表和部门表之间有关联,有多对一关联
2.重写equals方法和hashCode方法是因为我们使用的set集合。
2.System.out.println("1======"+HibernateUtils.getCurrentSession().hashCode);这是获得当前session,是通过hibernateUtils类里面的getCurrentSession()方法获得的,
方法体里面的threadLocal.get()表示用本地线程的map结构中获得session。。threadLocal.set(session)表示在本地线程的map 结构中保存一个session,键是本地线程的id,值是set后面的那个参数。
3.写入过滤器,目的是扩大session的声明周期,为什么写了过滤器就扩大了session 的声明周期了呢?
答:首先servlet技术中的过滤器的实质是在请求到达服务器和响应离开服务器的时候都要经过过滤器,也就是把方法写在过滤器里,并前后加其他功能。
请求先进入过滤器,过滤器在方法调用之前创建了session,后来执行方法(在执行方法的时候方法体里其实不是在创建session,而是在获得当前(过滤器)的session),然后执行完方法,在dao层执行完的,此时session还没关闭,如果此时又重定向执行其他action的话,那么其他action用的也是这个session。
在此练习中,就是添加之后查询,此过程用的是同一个session。因为session的创建和关闭是在web层(过滤器里)完成的,dao层的session只是调用web层中已经创建好的session。
4.在struts.xml中从一个session跳到另一个session的方式有两个,如果跳到的是另一个action,就用type=redirectAction,如果是又跳到本Action了就用type=chain。(此时注意是不是跳到“另一个”)
5.当我们在查询主表的时候顺便也查询了从表,使用fetch=select当然能够查询成功,但是select查询的时候控制台会产生多余的sql语句,因此要把select改成join(让他左外连接查询),但是左外连接查询的特点是把左表的全部数据都输出,右边表的符合条件的输出,
因此会输出好多重复的记录,出现这个问题的原因是在action层的查询方法中的返回值是list类型的,因此此时把list集合放到set集合里(set集合不允许重复元素的出现,使用set的集合要重写hashcode方法和equal方法)
-------------------------------
1.servlet过滤器:是用来过滤客户端的请求的,减轻服务器端的压力
2.servlet监听器:用来监听四大web域的生命周期
3.struts2拦截器:拦截器的作用是struts帮助我们处理一下问题的(例如类型转换、接收参数、在httpsession和session之间的转化等),我们自定义的拦截器的作用就是在进入服务器和出去服务器的时候增加一些增强代码
4.struts2通过actionContext的getsession方法跟踪客户端的请求。
5.open session in view为什么用的是过滤器而不是拦截器?
答:首先理解过滤器和拦截器:
1.过滤器是servlet的知识,表示在请求到达服务器之前先经过过滤器(减轻服务器端压力),在响应结束之后离开过滤器
2.监听器是struts的知识,表示在进入某个action的时候在这个action之前和之后增加增强代码。
在进入请求的时候这两个都一样,都是在action层的方法执行之前就先执行打开session的操作。
但是在action层方法执行之后,监听器是在这个监听器类中关闭session,而过滤器是在此响应结束的时候关闭session。(由于open session in view 想要的效果就是扩大session的声明周期,把他扩大到web层,因此使用过滤器)
6.工厂模式与代理模式
工厂模式就是创建对象:例如hibernate中的sessionfactory工厂
代理模式也有创建对象的功能,但是代理模式创建的是代理对象。
第二:代码
1.struts2主配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="stu" namespace="" extends="struts-default">
<action name="studentAction_*" class="com.web.action.StudentAction" method="{1}">
<result name="list">/list.jsp</result>
<result name="list2" type="chain">studentAction_findStudent</result>
<result name="show">/show.jsp</result>
</action>
</package>
</struts>
2.hibernate主配置文件
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.Oracle9Dialect
</property>
<property name="connection.url">
jdbc:oracle:thin:@localhost:1521:XE
</property>
<property name="connection.username">xq</property>
<property name="connection.password">xq</property>
<property name="connection.driver_class">
oracle.jdbc.OracleDriver
</property>
<property name="myeclipse.connection.profile">wugui</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping resource="com/model/pojo/Student.hbm.xml" />
<mapping resource="com/model/pojo/Score.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.dao层
package com.model.dao.impl;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.model.dao.HibernateUtils;
import com.model.dao.StudentDao;
import com.model.pojo.Student;
public class StudentDaoImpl implements StudentDao{
public List<Student> selStudent() {
// TODO Auto-generated method stub
Session session =HibernateUtils.getCurrentSession();
System.out.println("2========="+session.hashCode());
Criteria c = session.createCriteria(Student.class);
return c.list();
}
public int addStudent(Student stu) {
// TODO Auto-generated method stub
int x=0;
Session session =HibernateUtils.getCurrentSession();
System.out.println("4========="+session.hashCode());
Serializable sr= session.save(stu);
/*while(x<10000)
{
Serializable sr= session.save(stu);
if(x%100==0)
{
session.flush();
}
}*/
return Integer.parseInt(sr.toString());
}
public Student selStudentBySno(int sno) {
// TODO Auto-generated method stub
Session session =HibernateUtils.getCurrentSession();
return (Student)session.get(Student.class, sno);
}
public void delStudent(Integer[] snos) {
// TODO Auto-generated method stub
Session session =HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
String hql="delete from Student where sno in ( :snos )";
Query query =session.createQuery(hql);
query.setParameterList("snos",snos);
int row = query.executeUpdate();
tr.commit();
System.out.println("row="+row);
}
public static void main(String[] args) {
StudentDao dao = new StudentDaoImpl();
dao.delStudent(new Integer[]{120095,120199,222113});
}
}
4.service层
package com.model.biz.impl;
import java.util.List;
import com.model.biz.StudentBiz;
import com.model.dao.StudentDao;
import com.model.dao.impl.StudentDaoImpl;
import com.model.pojo.Student;
public class StudentBizImpl implements StudentBiz {
StudentDao dao = new StudentDaoImpl();
public List<Student> searchStudent() {
// TODO Auto-generated method stub
return dao.selStudent();
}
public int saveStudent(Student stu) {
// TODO Auto-generated method stub
return dao.addStudent(stu);
}
public Student selStudentBySno(int sno) {
// TODO Auto-generated method stub
return dao.selStudentBySno(sno);
}
}
5.action层
package com.web.action;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.model.biz.StudentBiz;
import com.model.biz.impl.StudentBizImpl;
import com.model.pojo.Student;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;
public class StudentAction implements ModelDriven<Student>{
private Student stu = new Student();
StudentBiz biz = new StudentBizImpl();
public Student getModel() {
// TODO Auto-generated method stub
return stu;
}
public String findStudent()
{
Map<String,Object> session=ActionContext.getContext().getSession();
List<Student> stuList=biz.searchStudent();
Set<Student> set = new HashSet<Student>();
set.addAll(stuList);
session.put("stuList", set);
return "list";
}
public String addStudent()
{
biz.saveStudent(stu);
return "list2";
}
public String selStudent()
{
Student stus= biz.selStudentBySno(stu.getSno());
Map<String,Object> session=ActionContext.getContext().getSession();
session.put("stus",stus);
return "show";
}
}
6.open session in view (过滤器)
package com.web.action;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.model.dao.HibernateUtils;
public class OSIVFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req,
ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
Session session = HibernateUtils.getCurrentSession();
System.out.println("1========="+session.hashCode());
Transaction tr = session.beginTransaction();
chain.doFilter(req, resp);
tr.commit();
System.out.println("3========="+session.hashCode());
HibernateUtils.closeCurrentSession();
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
相关推荐
总的来说,"Struts2+Hibernate3 Open Session in View"项目展示了如何结合这两种技术,实现高效且可靠的Web应用数据持久化。理解并正确使用OSIV模式,可以帮助开发者避免常见的数据库交互问题,提高应用的稳定性和...
Open Session in View (OSIV) 模式是一种在基于Hibernate的Web应用程序中处理持久化数据的策略,它允许在视图层(例如JSP页面)中安全地访问延迟加载的对象,而无需担心Session已关闭的问题。以下是关于这个模式及其...
`Open Session In View`的主要作用是在Web请求的开始阶段打开`Hibernate session`,并在请求结束时自动关闭该session。这样做的好处在于,可以确保在整个请求处理过程中session始终处于可用状态,使得在视图(View)层...
3. **Open Session in View (OSIV)**:在视图渲染阶段保持Session打开,以允许最后时刻的懒加载,但需要注意防止Session泄露。 总的来说,Hibernate中Session的管理是保证多线程环境下数据一致性的重要环节。...
3. **Open Session in View(OSIV)模式** OSIV模式旨在解决Web应用中,由于用户请求可能会引发多次数据库操作,而这些操作可能跨多个HTTP请求。在这种模式下,Session在整个HTTP请求周期内保持打开状态,直到请求...
在Spring整合Hibernate的情况下,Session通常通过Transaction Management进行管理,比如使用`Open Session in View`(OSIV)模式或者基于注解的事务管理。 当你尝试在Controller层或者视图层访问懒加载的属性时,...
4. **使用Open Session in View(OSIV)模式**:在Web开发中,为每个HTTP请求开启一个新的会话,可以避免跨请求的一级缓存污染问题,但也要注意防止会话泄漏。 压缩包文件“hibernate_cache_level1”可能包含与一级...
在没有Spring提供的Open Session In View(OSIV)模式下,事务处理和懒加载(lazy loading)可能会遇到挑战。 懒加载是一种优化策略,允许关联对象在需要时才从数据库加载,而不是在初始加载实体时就全部加载。这...
解决方案:理解并合理使用Open Session in View(OSIV)模式,或者在查询时显式调用`Hibernate.initialize()`方法。另外,可以考虑将懒加载改为急加载(Eager Fetching)。 六、HQL查询错误 错误表现:执行HQL语句...
以及开放 session 在视图(Open Session In View,OSIV)模式,确保在Web请求生命周期内保持一个持久化上下文,避免N+1查询问题。 总结来说,本教程涵盖了Hibernate的基础知识,从入门到实体映射,再到复合主键和...
Open Session In View是一种在Spring框架中常用的技术,用于简化Hibernate中的懒加载(lazy loading)机制。通过保持Hibernate Session在整个请求周期内处于打开状态,可以避免在视图层因为Session关闭而导致的`...
为了解决这个问题,Spring提供了一个过滤器 `OpenSessionInViewFilter` 或者 `OpenSessionInViewInterceptor`,通常简称为OSIV(Open Session In View)模式。 OSIV模式的核心思想是在Controller层和View层之间保持...
2. 使用Open Session In View模式,将Session的生命周期扩展到整个HTTP请求,但此方法可能带来事务管理和性能问题。 3. 在需要访问懒加载属性时,确保在Session内进行操作,或者使用`Hibernate.initialize()`手动...
在后续章节中,文章涵盖了Hibernate的核心接口与类、标识符生成策略、对象生命周期管理、OSIV(Open Session In View)模式、泛型DAO模式、集合映射、组件映射、各种关联关系的映射(一对一、一对多、多对多)、...
这种方式被称为ThreadLocal Session和Open Session in View模式,能够简化事务和Session的生命周期管理。 在实际应用中,需要确保正确地开启和结束Session及事务,并将其与数据访问操作结合。HibernateUtil类可以...
5. **DAO层与Hibernate**:DAO层使用Hibernate提供的API进行数据库操作,如Session的open、close、save、update、delete、find等方法。 6. **拦截器配置**:在Struts2中配置拦截器,可以实现如权限验证、日志记录等...
为解决此问题,可以在Controller层或Service层提前加载关联数据,或者使用Hibernate的“开放Session视图”(Open Session in View)模式。 3. **事务管理**:延时加载需要在一个有效的Hibernate Session内进行。在...
7. **使用Open Session in View(OSIV)模式**: 在Web应用中,通过在视图层保持Session开放,可以在请求结束时一次性加载所有关联数据。但这种方法可能导致事务管理复杂,并可能引发并发问题。 8. **使用Querydsl或...
为了避免这种情况,我们可以使用Open Session in View(OSIV)模式或者在查询时显式启用急切加载。 总的来说,选择合适的抓取策略和恰当使用懒加载是优化Hibernate应用性能的重要手段。开发者应根据业务场景灵活...
Open Session in View(OSIV)模式是一种常见的Hibernate优化模式,主要用于提高读取操作的性能。在这种模式下,Session在整个HTTP请求周期内保持打开状态。 ##### OSIV 实现方式 - **Servlet Filter 方式**:最常见...