我们在此之前已经分析过了JdbcTemplate的源代码,现在我们来分析一下HibernateTemplate,HIbernateTemplate中间包含了一个SessionFactory,就好比JdbcTemplate中引用一个DataSource一样,Hibernate会利用这个SessionFactory获取Session会话连接,
然后把数据库的curd功能委托给该Session进行;
其下是HibernateTemplate的属性字段:
在利用Hibernate进行查询的时候,都是利用一个Session的回调类进行处理的,
该接口只有一个方法,该方法提供一个Session参数,用户可以利用这个参数进行数据库访问,并且能够返回自己所感兴趣的值;
根据用户制定的exposeNativeSession参数决定是否暴露原生的Session,这个代理的Session会拦截到close,不会作出反映;
CloseSuppressingInvocationHandler是一个生成代理类的invocationHandler接口实现类;
利用HibernateTemplate进行删除的时候,也是利用的上述回调接口:
在删除之前,会进行删除的权限判断:
如果
CheckWriteOperations为真,并且刷新机制不是”急切“模式会话刷新机制为Never的话,就会禁止删除;
命名查询功能:
在hbm.xml文件中定义:
<query name="queryName">
<![cdata[
from visits as vi where vi.id=:id
]]>
</query>
执行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>
然后把数据库的curd功能委托给该Session进行;
其下是HibernateTemplate的属性字段:
- //是否允许创建
- private boolean allowCreate = true;
- //是否总是使用新的会话;
- private boolean alwaysUseNewSession = false;
- //是否暴露原生Session
- private boolean exposeNativeSession = false;
- //是否检查写操作
- private boolean checkWriteOperations = true;
- //是否缓存查询
- private boolean cacheQueries = false;
- //缓存
- private String queryCacheRegion;
- //连接数
- private int fetchSize = 0;
- //最大连接
- private int maxResults = 0;
- public Object execute(HibernateCallback action) throws DataAccessException {
- return execute(action, isExposeNativeSession());
- }
- public interface HibernateCallback {
- Object doInHibernate(Session session) throws HibernateException, SQLException;
- }
该接口只有一个方法,该方法提供一个Session参数,用户可以利用这个参数进行数据库访问,并且能够返回自己所感兴趣的值;
- previousFlushMode = applyFlushMode(session, existingTransaction);
- Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
- Object result = action.doInHibernate(sessionToExpose);
- flushIfNecessary(session, existingTransaction);
- return result;
- protected Session createSessionProxy(Session session) {
- return (Session) Proxy.newProxyInstance(
- getClass().getClassLoader(),
- new Class[] {Session.class},
- new CloseSuppressingInvocationHandler(session));
- }
CloseSuppressingInvocationHandler是一个生成代理类的invocationHandler接口实现类;
利用HibernateTemplate进行删除的时候,也是利用的上述回调接口:
- public int delete(final String queryString, final Object[] values, final Type[] types)
- throws DataAccessException {
- if (values != null && types != null && values.length != types.length) {
- throw new IllegalArgumentException("Length of values array must match length of types array");
- }
- Integer deleteCount = (Integer) execute(new HibernateCallback() {
- public Object doInHibernate(Session session) throws HibernateException {
-
- checkWriteOperationAllowed(session);
- if (values != null) {
- return new Integer(session.delete(queryString, values, types));
- }
- else {
- return new Integer(session.delete(queryString));
- }
- }
- }, true);
- return deleteCount.intValue();
- }
- protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException {
- if (isCheckWriteOperations() && getFlushMode() != FLUSH_EAGER &&
- FlushMode.NEVER.equals(session.getFlushMode())) {
- throw new InvalidDataAccessApiUsageException(
- "Write operations are not allowed in read-only mode (FlushMode.NEVER): "+
- "Turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition.");
- }
- }
命名查询功能:
- public List findByNamedQuery(final String queryName, final Object[] values, final Type[] types)
- throws DataAccessException {
- if (values != null && types != null && values.length != types.length) {
- throw new IllegalArgumentException("Length of values array must match length of types array");
- }
- return (List) execute(new HibernateCallback() {
- public Object doInHibernate(Session session) throws HibernateException {
- Query queryObject = session.getNamedQuery(queryName);
- prepareQuery(queryObject);
- if (values != null) {
- for (int i = 0; i < values.length; i++) {
- if (types != null && types[i] != null) {
- queryObject.setParameter(i, values[i], types[i]);
- }
- else {
- queryObject.setParameter(i, values[i]);
- }
- }
- }
- return queryObject.list();
- }
- }, true);
- }
<query name="queryName">
<![cdata[
from visits as vi where vi.id=:id
]]>
</query>
- public List findByNamedQueryAndNamedParam(
- final String queryName, final String[] paramNames, final Object[] values, final Type[] types)
- throws DataAccessException {
- if (paramNames != null && values != null && paramNames.length != values.length) {
- throw new IllegalArgumentException("Length of paramNames array must match length of values array");
- }
- if (values != null && types != null && paramNames.length != types.length) {
- throw new IllegalArgumentException("Length of paramNames array must match length of types array");
- }
- return (List) execute(new HibernateCallback() {
- public Object doInHibernate(Session session) throws HibernateException {
- Query queryObject = session.getNamedQuery(queryName);
- prepareQuery(queryObject);
- if (values != null) {
- for (int i = 0; i < values.length; i++) {
- applyNamedParameterToQuery(queryObject, paramNames[i], values[i], (types != null ? types[i] : null));
- }
- }
- return queryObject.list();
- }
- }, true);
- }
执行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>