DaoSupport、HibernateDaoSupport、HibernateTemplate学习

时间:2019-02-16
本文章向大家介绍DaoSupport、HibernateDaoSupport、HibernateTemplate学习,主要包括DaoSupport、HibernateDaoSupport、HibernateTemplate学习使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

InitializingBean接口

package org.springframework.beans.factory;
/**
 * 接口由bean实现,一旦BeanFactory设置了bean的所有属性,bean就需要进行响应:例如,执行自定义初始化,或者仅仅检查是否设置了所有强制属性。
 *
 * <p>An alternative to implementing InitializingBean is specifying a custom
 * init-method, for example in an XML bean definition.
 * For a list of all bean lifecycle methods, see the BeanFactory javadocs.
 */
public interface InitializingBean {
	/**
	 * bean工厂在设置了提供的所有bean属性之后调用
	 * 此方法允许bean实例仅在设置了所有bean属性时执行初始化,并在错误配置时抛出异常。
	 */
	void afterPropertiesSet() throws Exception;
}

DaoSupport

package org.springframework.dao.support;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;

/**
 * DAO的通用基类,定义用于DAO初始化的模板方法。
 * 通过Spring的特定DAO支持类进行扩展,例如JdbcDaoSupport, JdoDaoSupport, etc.
 */
public abstract class DaoSupport implements InitializingBean {

	/** 可用于子类的日志记录器*/
	protected final Log logger = LogFactory.getLog(getClass());

	@Override
	public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {
		//让抽象子类检查它们的配置
		checkDaoConfig();
		// 具体实现自己初始化。
		try {
			initDao();
		}
		catch (Exception ex) {
			throw new BeanInitializationException("Initialization of DAO failed", ex);
		}
	}

	/**
	 * 抽象子类必须覆盖它来检查它们的配置
	 * 如果具体的子类不应该覆盖这个模板方法本身,那么实现者应该被标记为{@code final}。
	 * 非法的配置抛出异常IllegalArgumentException
	 */
	protected abstract void checkDaoConfig() throws IllegalArgumentException;
	
	/**
	 * 具体的子类可以为定制的初始化行为覆盖这个。
	 * 在填充此实例的bean属性后调用。
	 * @throws Exception if DAO initialization fails
	 * (will be rethrown as a BeanInitializationException)
	 * @see org.springframework.beans.factory.BeanInitializationException
	 */
	protected void initDao() throws Exception {
	}

}


HibernateDaoSupport

package org.springframework.orm.hibernate5.support;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.support.DaoSupport;
import org.springframework.orm.hibernate5.HibernateTemplate;

public abstract class HibernateDaoSupport extends DaoSupport {

	private HibernateTemplate hibernateTemplate;
	/**
	 * 设置此DAO使用的Hibernate SessionFactory。
	 * 将自动为给定的SessionFactory创建HibernateTemplate
	 */
	public final void setSessionFactory(SessionFactory sessionFactory) {
		if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
			this.hibernateTemplate = createHibernateTemplate(sessionFactory);
		}
	}
	/**
	 * 为给定的SessionFactory创建一个HibernateTemplate。
	 * 只有在用SessionFactory引用填充DAO时才调用!
	 * 可以在子类中重写,以提供具有不同配置的HibernateTemplate实例,或自定义的HibernateTemplate子类。
	 */
	protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
		return new HibernateTemplate(sessionFactory);
	}

	/**
	 * 获得DAO中使用的SessionFactory工厂
	 */
	public final SessionFactory getSessionFactory() {
		return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);
	}

	/**
	 * 显式设置此DAO的HibernateTemplate,作为指定SessionFactory的替代方法。
	 * @see #setSessionFactory
	 */
	public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	/**
	 * 返回此DAO的HibernateTemplate,预先用SessionFactory或显式设置初始化
	 * 返回的HibernateTemplate是一个共享实例
	 */
	public final HibernateTemplate getHibernateTemplate() {
	  return this.hibernateTemplate;
	} 
	
	@Override
	protected final void checkDaoConfig() {
		if (this.hibernateTemplate == null) {
			throw new IllegalArgumentException("'sessionFactory' or 'hibernateTemplate' is required");
		}
	}

	/**
	 * 方便地获取当前Hibernate session。
	 * 返回Hibernate session,如果session没有被创建则抛出 DataAccessResourceFailureException异常
	 */
	protected final Session currentSession() throws DataAccessResourceFailureException {
		return getSessionFactory().getCurrentSession();
	}
}


重点对象
HibernateTemplate
实现HibernateOperations接口

使用HibernateTemplate,不需要直接控制事务,不需直接去获取、打开Session、开始一个事务、处理异常、提交一个事务和最后关闭一个Session。HibernateTemplate 对Hibernate操作进行封装,简单的调用HibernateTemplate 对象,传入HQL和参数,就获得查询接口,至于事务的开启,关闭,都交给HibernateTemplate对象来处理,我们只专注于业务。把这些全部委托给了 HibernateTemplate,然后使用声明式的配置来实现这样的功能。

/**
 * 简化Hibernate数据访问代码的Helper类。
 * HibernateTemplate 提供了非常多的常用方法来完成基本的操作,比如增加、删除、修改及查询等操作,Spring 2.0 增加对命名 SQL 查询的支持,也增加对分页的支持。
 * 大部分情况下,使用Hibernate 的常规用法,就可完成大多数DAO对象的CRUD操作。
 */

/**
*getHibernateTemplate().execute(new HibernateCallback()) 
*可以完全使用Hibernate灵活的方式来访问数据库,解决Spring封装Hibernate后灵活性不足、api固定的缺陷。
*不用关心事务。session的创建和销毁,一切都在程序内部完成。
*doInHibernate方法内可以访问Session,该Session对象是绑定在该线程的Session实例。
*该方法内的持久层操作,与不使用Spring时的持久层操作完全相同。这保证了对于复杂的持久层访问,依然可以使用Hibernate的访问方式。
*/
getHibernateTemplate().execute(new HibernateCallback<T>() {
	@Override
	public T doInHibernate(Session session) throws HibernateException {
	return null;
	}
})
public void setMaxResults(int maxResults) 设置分页的大小。

加载单个对象的方便方法:

public <T> T get(Class<T> entityClass, Serializable id)  根据主键加载特定持久化类的实例。
public <T> T get(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
public Object get(String entityName, Serializable id)
public Object get(final String entityName, final Serializable id, final LockMode lockMode)

public <T> T load(Class<T> entityClass, Serializable id)  根据主键加载特定持久化类的实例。
public <T> T load(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
public Object load(String entityName, Serializable id) 
public Object load(final String entityName, final Serializable id, final LockMode lockMode)

public <T> List<T> loadAll(final Class<T> entityClass) 
public void load(final Object entity, final Serializable id) 

public void refresh(final Object entity)
public void refresh(final Object entity, final LockMode lockMode)

public boolean contains(final Object entity) 
public void evict(final Object entity) 
public void initialize(Object proxy) 
public Filter enableFilter(String filterName) 

存储单个对象的方便方法:

public Serializable save(final Object entity) 保存新的实例。
public Serializable save(final String entityName, final Object entity)

public void lock(final Object entity, final LockMode lockMode)
public void lock(final String entityName, final Object entity, final LockMode lockMode)

public void update(Object entity) 更新实例的状态,要求entity 是持久状态。
public void update(final Object entity, final LockMode lockMode) 
public void update(String entityName, Object entity) 
public void update(final String entityName, final Object entity, final LockMode lockMode)

public void saveOrUpdate(final Object entity)  根据实例状态,选择保存或者更新。
public void saveOrUpdate(final String entityName, final Object entity) 

public void replicate(final Object entity, final ReplicationMode replicationMode)
public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode)

public void persist(final Object entity) 
public void persist(final String entityName, final Object entity) 

public <T> T merge(final T entity)
public <T> T merge(final String entityName, final T entity) 

public void delete(Object entity)    删除指定持久化实例 
public void delete(final Object entity, final LockMode lockMode)
public void delete(String entityName, Object entity)
public void delete(final String entityName, final Object entity, final LockMode lockMode)
public void deleteAll(final Collection<?> entities) 删除集合内全部持久化类实例  

public void flush()
public void clear()

HQL字符串的便利查找器方法:

public List<?> find(String queryString)  
根据HQL查询字符串来返回实例集合
示例:
hibernateTemplate.find("from User");   //返回所有User对象 
---

public List<?> find(final String queryString, final Object... values)  
示例:
hibernateTemplate.find("from User u where u.name=?", "test");  
或模糊查询:hibernateTemplate.find("from User u where u.name like ?", "%test%");  
返回name属性值为test的对象(模糊查询,返回name属性值包含test的对象)
---

public List<?> findByNamedParam(String queryString, String paramName, Object value)
示例:String queryString = "select count(*) from User u where u.name=:myName" ;  
   String paramName= "myName";
   String value= "abc";  
   list=hibernateTemplate.findByNamedParam(queryString, paramName, value);
   System.out.println(list.get(0 ));        
返回:name为abc的User对象的条数
---

public List<?> findByNamedParam(final String queryString, final String[] paramNames, final Object[] values)
示例:String queryString = "select count(*) from User u where u.name=:myName and u.password=:myPassword";
   String[] paramName= new String[]{"myName", "myPassword"};
   String[] value= new String[]{"abc", "123"};  
   hibernateTemplate.findByNamedParam(queryString, paramName, value); 
返回:用户名为abc密码为123的User对象
---

public List<?> findByValueBean(final String queryString, final Object valueBean)
示例:  
1、定义一个ValueBean,属性名必须和HQL语句中的:后面的变量名同名,此处必须至少有两个属性,分别为myName和 myPassword,使用setter方法设置属性值
ValueBean valueBean= new ValueBean();
valueBean.setMyName("test");
valueBean.setMyPasswrod("123");        
2、  
String queryString= "from User u where u.name=:myName and u.password=:myPassword";  
hibernateTemplate.findByValueBean(queryString , valueBean); 

命名查询的便利查找器方法:

public List<?> findByNamedQueryAndNamedParam(String queryName, String paramName, Object value)
示例:  
1、首先需要在User.hbm.xml中定义命名查询
<hibernate-mapping>
	<class>......</class>  
	<query name="queryByName "><!--此查询被调用的名字-->
		<![CDATA[  
			from User u where u.name =:myName
		]]>
	</query>
</hibernate-mapping>           
2、如下使用查询:  
hibernateTemplate.findByNamedQuery("queryByName" , "myName", "test");
---

public List<?> findByNamedQuery(final String queryName, final Object... values)   
单参示例:  
1、首先需要在User.hbm.xml中定义命名查询               
<hibernate-mapping>                    
	<class>......</class>  
	<query name="queryByName "> <!--此查询被调用的名字-->
		<![CDATA[  
			from User u where u.name = ? 
		]]>
	</query>
</hibernate-mapping>
2、如下使用查询:  
hibernateTemplate.findByNamedQuery("queryByName ", "test");

多参示例:  
1、首先需要在User.hbm.xml中定义命名查询
<hibernate-mapping>
	<class>......</class>  
	<query name="queryByNameAndPassword ">    <!--此查询被调用的名字--> 
		<![CDATA[  
			from User u where u.name =? and u.password =?  
		]]>
	</query>
</hibernate-mapping>          
 2、如下使用查询:  
String[] values= new String[]{"test", "123"};  
hibernateTemplate.findByNamedQuery("queryByNameAndPassword" , values);  
---

public List<?> findByNamedQuery(String queryName) 
示例:  
1、首先需要在User.hbm.xml中定义命名查询               
<hibernate-mapping>                    
	<class>......</class>  
	<query name="queryAllUser ">   <!--此查询被调用的名字-->  
		<![CDATA[  
		from User
		]]>
	</query>
</hibernate-mapping>           
2、如下使用查询:  
hibernateTemplate.findByNamedQuery("queryAllUser"); 
---

public List<?> findByNamedQueryAndNamedParam(final String queryName, final String[] paramNames, final Object[] values)
示例:
1、首先需要在User.hbm.xml中定义命名查询
<hibernate-mapping>
	<class>......</class>  
	<query name="queryByNameAndPassword ">   <!--此查询被调用的名字-->  
		![CDATA[  
			from User u where u.name =:myName and u.password=:myPassword
		]]>
	</query>
</hibernate-mapping>           
2、如下使用查询:  
String[] names= new String[]{"myName", "myPassword"};
String[] values= new String[]{"test", "123"};  
hibernateTemplate.findByNamedQuery("queryByNameAndPassword " , names, values);
---

public List<?> findByNamedQueryAndValueBean(final String queryName, final Object valueBean)
示例:  
1、首先需要在User.hbm.xml中定义命名查询
<hibernate-mapping>
	<class>......</class>  
	<query name="queryByNameAndPassword ">   <!--此查询被调用的名字-->  
		<![CDATA[  
			from User u where u.name =:myName and u.password=:myPassword   
		]]>
	</query>
</hibernate-mapping>
2、定义一个ValueBean,属性名必须和User.hbm.xml命名查询语句中的:后面的变量名同名,此处必须至少有两个属性,分别为 myName和myPassword,使用setter方法设置属性值后  
ValueBean valueBean= new ValueBean();
valueBean.setMyName("test");
valueBean.setMyPasswrod("123");       
3、  
hibernateTemplate.findByNamedQueryAndValueBean("queryByNameAndPassword ", valueBean); 
---

DetachedCriteria便利查找器方法

public List<?> findByCriteria(DetachedCriteria criteria) 
public List<?> findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults)
---

public <T> List<T> findByExample(T exampleEntity) 
示例:
	User u=new  User();      
	u.setPassword("123" );
	u.setName("bb" );                            
	list=hibernateTemplate.findByExample(u);    
返回:用户名为bb密码为123的对象
---

public <T> List<T> findByExample(String entityName, T exampleEntity) 
---

public <T> List<T> findByExample(T exampleEntity, int firstResult, int maxResults) 
示例:
	User u=new  User();      
	u.setPassword("123" );
	u.setName("bb" );    
	list=hibernateTemplate.findByExample(u,start,max);      
返回:满足用户名为bb密码为123,自start起共max个User对象(对象从0开始计数)
---

public <T> List<T> findByExample(final String entityName, final T exampleEntity, final int firstResult, final int maxResults)

用于迭代和批量更新/删除的便利查询方法:

public Iterator<?> iterate(final String queryString, final Object... values)
public void closeIterator(Iterator<?> it)
public int bulkUpdate(final String queryString, final Object... values)