Spring源代码分析(16)---HibernateTemplate(ORM的回眸一笑);

81 篇文章 0 订阅
36 篇文章 0 订阅
我们在此之前已经分析过了JdbcTemplate的源代码,现在我们来分析一下HibernateTemplate,HIbernateTemplate中间包含了一个SessionFactory,就好比JdbcTemplate中引用一个DataSource一样,Hibernate会利用这个SessionFactory获取Session会话连接,
然后把数据库的curd功能委托给该Session进行;



其下是HibernateTemplate的属性字段:
  1.     //是否允许创建
  2.     private boolean allowCreate = true;
  3.         //是否总是使用新的会话;
  4.     private boolean alwaysUseNewSession = false;
  5.         //是否暴露原生Session
  6.     private boolean exposeNativeSession = false;
  7.         //是否检查写操作
  8.     private boolean checkWriteOperations = true;
  9.        //是否缓存查询
  10.     private boolean cacheQueries = false;
  11.        //缓存
  12.     private String queryCacheRegion;
  13.         //连接数
  14.     private int fetchSize = 0;
  15.         //最大连接
  16.     private int maxResults = 0;
在利用Hibernate进行查询的时候,都是利用一个Session的回调类进行处理的,
  1. public Object execute(HibernateCallback action) throws DataAccessException {
  2.         return execute(action, isExposeNativeSession());
  3.     }
  1. public interface HibernateCallback {
  2.     Object doInHibernate(Session session) throws HibernateException, SQLException;
  3. }

该接口只有一个方法,该方法提供一个Session参数,用户可以利用这个参数进行数据库访问,并且能够返回自己所感兴趣的值;
  1. previousFlushMode = applyFlushMode(session, existingTransaction);
  2.             Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
  3.             Object result = action.doInHibernate(sessionToExpose);
  4.             flushIfNecessary(session, existingTransaction);
  5.             return result;
根据用户制定的exposeNativeSession参数决定是否暴露原生的Session,这个代理的Session会拦截到close,不会作出反映;
  1.     protected Session createSessionProxy(Session session) {
  2.         return (Session) Proxy.newProxyInstance(
  3.                 getClass().getClassLoader(),
  4.                 new Class[] {Session.class},
  5.                 new CloseSuppressingInvocationHandler(session));
  6.     }

CloseSuppressingInvocationHandler是一个生成代理类的invocationHandler接口实现类;


利用HibernateTemplate进行删除的时候,也是利用的上述回调接口:

  1. public int delete(final String queryString, final Object[] values, final Type[] types)
  2.             throws DataAccessException {

  3.         if (values != null && types != null && values.length != types.length) {
  4.             throw new IllegalArgumentException("Length of values array must match length of types array");
  5.         }
  6.         Integer deleteCount = (Integer) execute(new HibernateCallback() {
  7.             public Object doInHibernate(Session session) throws HibernateException {
  8.                
  9.                 checkWriteOperationAllowed(session);
  10.                 if (values != null) {
  11.                     return new Integer(session.delete(queryString, values, types));
  12.                 }
  13.                 else {
  14.                     return new Integer(session.delete(queryString));
  15.                 }
  16.             }
  17.         }, true);
  18.         return deleteCount.intValue();
  19.     }
在删除之前,会进行删除的权限判断:

  1.     protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException {
  2.         if (isCheckWriteOperations() && getFlushMode() != FLUSH_EAGER &&
  3.                 FlushMode.NEVER.equals(session.getFlushMode())) {
  4.             throw new InvalidDataAccessApiUsageException(
  5.                     "Write operations are not allowed in read-only mode (FlushMode.NEVER): "+
  6.                     "Turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition.");
  7.         }
  8.     }
如果 CheckWriteOperations为真,并且刷新机制不是”急切“模式会话刷新机制为Never的话,就会禁止删除;


命名查询功能:

  1. public List findByNamedQuery(final String queryName, final Object[] values, final Type[] types)
  2.             throws DataAccessException {
  3.         if (values != null && types != null && values.length != types.length) {
  4.             throw new IllegalArgumentException("Length of values array must match length of types array");
  5.         }
  6.         return (List) execute(new HibernateCallback() {
  7.             public Object doInHibernate(Session session) throws HibernateException {
  8.                 Query queryObject = session.getNamedQuery(queryName);
  9.                 prepareQuery(queryObject);
  10.                 if (values != null) {
  11.                     for (int i = 0; i < values.length; i++) {
  12.                         if (types != null && types[i] != null) {
  13.                             queryObject.setParameter(i, values[i], types[i]);
  14.                         }
  15.                         else {
  16.                             queryObject.setParameter(i, values[i]);
  17.                         }
  18.                     }
  19.                 }
  20.                 return queryObject.list();
  21.             }
  22.         }, true);
  23.     }
在hbm.xml文件中定义:
<query name="queryName">
<![cdata[
 from visits as vi where vi.id=:id
 ]]>
</query>

  1.     public List findByNamedQueryAndNamedParam(
  2.         final String queryName, final String[] paramNames, final Object[] values, final Type[] types)
  3.         throws DataAccessException {
  4.         if (paramNames != null && values != null && paramNames.length != values.length) {
  5.             throw new IllegalArgumentException("Length of paramNames array must match length of values array");
  6.         }
  7.         if (values != null && types != null && paramNames.length != types.length) {
  8.             throw new IllegalArgumentException("Length of paramNames array must match length of types array");
  9.         }
  10.         return (List) execute(new HibernateCallback() {
  11.             public Object doInHibernate(Session session) throws HibernateException {
  12.                 Query queryObject = session.getNamedQuery(queryName);
  13.                 prepareQuery(queryObject);
  14.                 if (values != null) {
  15.                     for (int i = 0; i < values.length; i++) {
  16.                         applyNamedParameterToQuery(queryObject, paramNames[i], values[i], (types != null ? types[i] : null));
  17.                     }
  18.                 }
  19.                 return queryObject.list();
  20.             }
  21.         }, true);
  22.     }

执行getHibernateTemplate().findByNamedQueryAndNamedParameters("namedQuery",new String[]{"id"},new Object[]{2});

即可;

然后使用:

coreyDao.getHibernateTemplate().findByNamedQuery("quertName",1);

并且支持命名参数:
<query name="queryName">
<![cdata[
 from visits as vi where vi.id=?
 ]]>
</query>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值