最近在用ssh框架写网站,对hibernate框架一直都是一知半解的。只能通过手动一步步的测试,先把目前测试出来的东西做一个小总结吧。
查询:
1.用sql语句查询,返回Model对象
//注意 这里的语句是原生的sql语句,表名和字段名都是数据库中的字段
@Override
public List<SubTaskAudio> getSubTaskAudiosByGroup(int groupid) {
// TODO Auto-generated method stub
Session session=getSessionFactory().getCurrentSession();
String hqlString="select s.* from SUB_TASK_AUDIO s where s.AUDIO_GROUP=?";
SQLQuery query=session.createSQLQuery(hqlString);//
query.setParameter(0, groupid);
//设置返回的数据映射的对象,返回hibernate model对象
query.addEntity(SubTaskAudio.class);
List<SubTaskAudio> list=query.list();
return list;
}
2.用hql语句查询
//注意查询语句是model中对应的表名和字段的名称
@Override
public SubTaskAudio getSubTaskAudioByIndexID(int indexid) {
// TODO Auto-generated method stub\
Session session=getSessionFactory().getCurrentSession();
String hqlString="from SubTaskAudio s where s.indexid=?";
Query query=session.createQuery(hqlString);
query.setParameter(0, indexid);
List<SubTaskAudio> list=query.list();
if(list.size()>0){
return list.get(0);
}else{
return null;
}
}
3.用sql查询,并返回map
@Override
public String getSubTaskNum(String tasktype, int taskState, String dataType) {
// TODO Auto-generated method stub
Session session = getSessionFactory().getCurrentSession();
String sql = "select t.ID from SUB_TASK t,SUB_CONFIGURATION c where t.TYPE=c.INDEXID and c.VALUE=? and t.state=?"
+ " and t.INDEXID in ( select t1.INDEXID from SUB_TASK t1,SUB_CONFIGURATION c1 where t1.DATA_TYPE=c1.INDEXID and c1.VALUE=? )";
Query query = session.createSQLQuery(sql);
query.setParameter(0, tasktype);
query.setParameter(1, taskState);
query.setParameter(2, dataType);
//这只返回的类型为map,可以为model,map,object
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List list = query.list();
if(list.size()>0){
Map<String,String> entry=(Map)list.get(0);
String taskIdString=entry.get("ID");
return taskIdString;
}
return null;
}
更新&&添加记录
1.用hql进行更新:
:
/**
* 更新audio的状态信息
*/
@Override
public void updateAutioState(SubTaskAudio audio) {
// TODO Auto-generated method stub
Session session=getSessionFactory().getCurrentSession();
Query query2=session.createQuery("update SubTaskAudio a set a.state=?"
+" where a.indexid=?");
query2.setParameter(0, audio.getState());
query2.setParameter(1, audio.getIndexid());
//执行更新
int result=query2.executeUpdate();
}
2.用model对象进行更新或者添加
public void insertExportFileItem(MainExportFile exportFile) {
// TODO Auto-generated method stub
Session session=getHibernateTemplate().getSessionFactory().getCurrentSession();
session.saveOrUpdate(exportFile);
}
事务
1.hibernate 的事务操作
事务一般都定义在service层
1.在application的文件之中添加
<!-- 声明式事务配置 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 申明事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 对get开头的函数 进行事务操作-->
<tx:method name="get*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED"></tx:method>
<tx:method name="delete*" propagation="REQUIRED"></tx:method>
<tx:method name="edit*" propagation="REQUIRED"></tx:method>
<tx:method name="handle*" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 申明式事务管理:定义切面 -->
<!-- 第一个* 代表返回所有的类型,第二个*代表所有的类,第三个*代表所有的函数,..代表所有的参数-->
<aop:config>
<aop:pointcut id="services"
expression="execution(* com.studio.services.*.*(..))" />
<!-- 对切面的函数进行操作-->
<aop:advisor pointcut-ref="services" advice-ref="txAdvice" />
</aop:config>
2.事务的总结:
在service之中抛出RuntimeException(集成自它的exception,或者是在aop中配置的exception),之中则会交给spring框架来负责完成事务的回滚。在完成事务的回滚之后,spring框架继续讲这个异常抛出给action层,返回给用户自己处理。
3.缓存
(1)一级缓存是session级别的,二级缓存是sessionFactory级别的,在同一个session中反复查询某一个对象,第一次从数据库查询,以后从缓存中取。
(2)清除一级缓存用session.evict(),清除二级缓存用sessionFactory.evict().
(3)当一个session在循环读取某一个值,等待另一个session改变数据库的状态的时候,这个时候的查询部能用缓存,因为另一个session更新数据库的状态并不能同步到这个session上面,方法有两个。
1)需要用session.evict()清除缓存,不知道为什么用query.setCachmode().禁止使用缓存无效。注意在evict()之前看一下session的哪些变量时需要保存的,直接调用session.flush()会覆盖掉更改的数据。
2)新开一个session进行查询,新开session就不会用到原来session的一级缓存了。方法有两个,第一用sessionFactory.openSession()不要用sessionFactory.getCurrentSession().或者用getHibernateTemplate()来进行查询,getHibernateTemplate进行查询的时候,默认是会新开一个session的。亲测可以。但是有许多疑问没有解决。stackoverflow上面有人提出这个问题和一些想法了。点击打开链接
4.hibernate延迟加载。以及.hbm.xml文件的属性和编辑的方法讲解点击打开链接
笔记 重点:
- 联实体是多个实体时(包括一对多、多对多):此时关联实体将以集合的形式存在,Hibernate 将使用 PersistentSet、PersistentList、PersistentMap、PersistentSortedMap、PersistentSortedSet 等集合来管理延迟加载的实体。这就是前面所介绍的情形。
- 关联实体是单个实体时(包括一对一、多对一):当 Hibernate 加载某个实体时,延迟的关联实体将是一个动态生成代理对象。
当关联实体是单个实体时,也就是使用 <many-to-one.../> 或 <one-to-one.../> 映射关联实体的情形,这两个元素也可通过 lazy 属性来指定延迟加载。
集合这设置set的lazy属性。
延迟加载配合OpenSessionInViewFilter一起使用。OpenSessionInViewFilter