Session-Hibernate

HttpSession与Hibernate中Session的区别
一、javax.servlet.http.HttpSession是一个抽象接口
它的产生:J2EE的Web程序在运行的时候,会给每一个新的访问者建立一个HttpSession,这个Session是用户身份的唯一表示。注意,是容器(Tomcat,Resin)自动创建的。
用途:存放这个用户的一些经常被用到的信息,例如:用户名,权限。例如在购物车程序里,存放用户买的商品。
销毁:一定时间(跟容器有关)内,用户无任何动作,session自动销毁。
得到的方法:
HttpSession session = request.getSession();
常用方法setAttribute
session.setAttribute(key,value);
这样在另一个jsp或者Servlet里,可以用
session.getAttribute(key);得到value
类似一个Map

二、org.hibernate.Session
它是hibernate操作数据库的一个句柄对象。它跟上面那个Session唯一的相似处就是名字有点像,其他没任何一样的地方。
一般的Hibernate程序中,Session由用户手动获取,手动关闭。
正规项目中,在业务层获取Session
Session session = HibernateSessionFactory.openSession();
然后把此session传给dao层,将数据持久化或其他的操作。
一次业务逻辑可能调用多个dao方法,例如银行转帐,是一个先减后增的过程,所以会调用2个dao里的方法(甲帐户减,乙帐户增)。因此,可以利用业务层产生的同一个Session来做这件事
a1和a2代表帐户实体。
a1是甲的,a2是乙的。
a1.setAcount(a1.getAcount()-1000);
a2.setAcount(a2.getAcount()+1000);
dao.update(a1,session);
dao.update(a2,session);
Transaction tx = session.beginTransaction();
tx.commit();
最后在业务层,将session关闭
session.close();
或者调用HibernateSessionFactory.closeSession(session);

最好能加上异常捕捉,之类,如产生异常,即时回滚。保证操作不出意外。
try{
...
tx.commit();
}catch(Exception e){
tx.rollback();
}finally{
HibernateSessionFactory.closeSession(session);
}
默认session的时间为20分钟,如果想在这之前清除的话可以使用Session.Abandorn方法


hibernate中 session.save(实体类)方法的原理
我们知道hibernate中的session类中的save()方法可以将某一个实体类的对象存入数据库中,那么我想知道,session是如何判断传入的对象的真实的类型,并将其插入数据库中的?
例如:我有一个user对象,现在我想通过session中的save方法存储这个user对象,那么我需要这样写session.save(user);那么,我想问一下,session接收user对象后,它是如何知道user所属的类型,并解析user中的属性,然后将其插入到数据库中的?请注意,重点是session是如何判断user的本来类型的,解决这个问题就可以了

session中保存了user对象根据执行ID生成策略,为临时对象生成唯一OID
(1)把user对象加入到缓存中,使它变为持久化对象。
(2)选用映射文件指定的标识符生成器为持久化对象分配惟一的OID。比如user.hbm.xml文件中<id>元素的<generator>子元素指定标识符生成器:
<id name="id" column="ID">
<generator class="increment"/>
</id>
(3)计划执行一个insert语句,把user对象当前的属性值组装到insert语句中:
insert into CUSTOMERS(ID, NAME, ......) values(1, 'Tom', ......);
值得注意的是,save()方法并不立即执行SQL insert语句。只有当Session清理缓存时,才会执行SQL insert语句。如果在save()方法之后,又修改了持久化对象的属性,这会使得Session在清理缓存时,额外执行SQL update语句。以下两段代码尽管都能完成相同的功能,但是左边代码仅执行一条SQL insert语句,而右边代码执行一条SQL insert和一条SQL update语句。第一种代码减少了操作数据库的次数,具有更好的运行性能。
UserBean user = new UserBean();
// 先设置Customer对象的属性,再保存它
user .setName("Tom");
user .save(user );
transaction.commit();
UserBean user= new UserBean();
session.save(user );
// 先保存Customer对象,再修改它的属性
user .setName("Tom");
transaction.commit();


Session的save()方法用来将一个临时对象转变为持久化对象,也就是将一个新的实体保存到数据库中。
通过save()将持久化对象保存到数据库需要经过以下步骤:
1,系统根据指定的ID生成策略,为临时对象生成一个唯一的OID;
2,将临时对象加载到缓存中,使之变成持久化对象;
3,提交事务时,清理缓存,利用持久化对象包含的信息生成insert语句,将持久化对象保存到数据库。

执行save()方法时并不会将对象存入数据库,在提交事务时,对象才被真正的保存到数据库中。
save()方法是将对象保存到Session的缓存中,提交事务时,Hibernate会生成相应的insert语句,将对象保存到数据库

user.setUserName("old");
session.save(user);
user.setUserName("new");
tx.commit();
执行以上操作,最终user.getUserName();得到的值将会是“new”,而不会是“old”,因为Hibernate在提交事务的时候把对user对象的所有操作都提交了

user.setId("1");
System.out.println("手动赋值为:"+user.getId());
session.save(user);
System.out.println("存入数据库的值为:"+user.getId());
最终存入数据库的ID是Hibernate自动生成的自增ID,而不是我们手动给的值

原文地址:https://www.cnblogs.com/wanhua-wu/p/6514499.html