菜鸟自学HibernateTemplate方法---------get方法学习

关于HibernateTemplate方法的一些总结
前言:
写这篇文章的目的主要是熟悉HibernateTemplate的方法的使用,刚刚学习ssh,在持久层中使用hibernate,spring对基础的hibernate方法进行了包装,虽然可以绕过spring使用纯正的hibernate方法实现CRUD,可是hibernateTemplate的方法同样也需要认真学习。

[size=small]Summary[/size]
//方法一
public Object get(Class entityClass, Serializable id) throws DataAccessException {
return get(entityClass, id, null);
}
public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)
throws DataAccessException {

return executeWithNativeSession(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.get(entityClass, id, lockMode);
}
else {
return session.get(entityClass, id);
}
}
});
}



Method Analysis
方法一:hibernateTemplate的get方法用于查询返回指定的对象,需要指定所要查询的实体类(entityClass),实体对象在数据库中对应的主键编号(id),重载方法支持一个参数org.hibernate.LockMode
由于不大了解LockMode这个类所以下面插入一下对这个类的分析
 首先我先看了下它的源代码
一段描述类的注释


/**
* Instances represent a lock mode for a row of a relational
* database table. It is not intended that users spend much
* time worrying about locking since Hibernate usually
* obtains exactly the right lock level automatically.
* Some "advanced" users may wish to explicitly specify lock
* levels.
*
* @see Session#lock(Object,LockMode)
* @author Gavin King
*/
实例代表关系型数据库表中一条记录的锁定方式,Hibernate的加锁模式---包括
1. LockMode.NONE:无锁机制
2. LockMode.WRITE:Hibernate在Insert和Update记录的时候会自动获取
3. LockMode.READ:Hibernate在读取记录的时候会自动获取
4. LockMode.UPGRADE:利用数据库的for update子句加锁
5. LockMode.UPGRADE_NOWAIT:Oracle的特定实现,利用Oracle的for update nowait子句实现加锁

下面是我做的一点测试,关闭opensessioninview过滤器,没有添加transactionManager.
Person person1 = personService.get(3);
person1.setName("person");
personService.save(person1);

//查询编号为3的记录,插入成功数据库中增加了一条数据。
//当我配置了opensessioninview过滤器后,这个操作报出异常如下:
[color=red]javax.servlet.ServletException: org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
Root caus:org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.[/color]
解决方法:就是把删除,修改,添加放在transaction中。可以用spring的aop方便解决
OpenSessionInViewFilter调用流程: request(请求)->open session并开始
transaction->controller->View(Jsp)->结束transaction并close session.
一切看起来很正确,尤其是在本地开发测试的时候没出现问题,但试想下如果流程中的某一步被阻塞的话,那在这期间connection就一直被占
用而不释放。最有可能被阻塞的就是在写Jsp这步,一方面可能是页面内容大,response.write的时间长,另一方面可能是网速慢,服务器与用
户间传输时间久。当大量这样的情况出现时,就有连接池连接不足,造成页面假死现象。
Opensessioninview 设置flushMode为never 无论如何也不要把数据的任何变化反映到数据库中去,所以对数据的insert,delete,update操作都无法执行,所以会出现异常。所以应该使用aop将load,get等方法设置为read-only。
比如下面的配置:
<bean id="baseTransaction" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"           
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="get*">
PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="find*">
PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="userService" parent="baseTransaction">
<property name="target">
<bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
</property>
</bean>


回到我们刚才断点,这里我不配置opensessioninview试验。
LockMode.UPGRADE:利用数据库的for update子句加锁,是最高级别的锁定了,目前我只能理解到,如果我需要查询某条记录并更新状态时,使用此锁定模式,当另外一个线程同样也是此操作的话,是处于锁定状态的。网上有个例子是对此的应用可以参照。
[url]http://wiki.iteye.com/blog/195650[/url]
LockMode.WRITE:跟了下源码发现当设置此模式的话,定义为抛出异常
javax.servlet.ServletException: java.lang.IllegalArgumentException: Invalid lock mode for loading—不适当的锁定模式
好了,带有lockmode的方法我目前只能写到这里,毕竟还是菜鸟,后面将不讨论带有lockmode的方法。
方法2:
 public Object get(String entityName, Serializable id) throws DataAccessException {
return get(entityName, id, null);
}

public Object get(final String entityName, final Serializable id, final LockMode lockMode)
throws DataAccessException {

return executeWithNativeSession(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.get(entityName, id, lockMode);
}
else {
return session.get(entityName, id);
}
}
});
}

HibernateTemplate的get方法还有另外俩个重载,参数分别为String 和 id
下面是个例子
Person person1 = personService.get("domain.person.Person",3);
System.out.println(person1.getName()+"---------"+person1.getPassword());


String参数需要传递的是完整的实体类名。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值