HibernateTemplate与HibernateDaoSupport分析

本文详细介绍了HibernateTemplate在Spring框架中的应用,包括基本方法如get、load、save等,并通过示例代码展示了如何配置DataSource、SessionFactory及HibernateTemplate。此外,还讨论了使用XML配置和注解配置的不同方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HibernateTemplate是Spring当中一个很方便的类,主要用于Hibernate中的DAO类中,对数据库记录进行直接操作,常用方法有(这里偷个懒,不把重载方法都一一列出来了,只有方法名以及简单功能介绍):

get                       从数据库相关表中获取一条记录并封装返回一个对象(Object)

load                     作用与get基本相同,不过只有在对该对象的数据实际调用时,才会去查询数据库

save                    添加记录

saveOrUpdate     判断相应记录是否已存在,据此进行添加或修改记录

update                修改记录

delete                 删除记录

 

HibernateTemplate介绍就到这里,接下来我们考虑其使用。

既然是Spring,我们当然要用到IOC了(不知道IOC?问谷老师去!),注入次序是:

DataSource -> SessionFactory -> HibernateTemplate -> DAO

 

以下是相关代码:

applicationContext.xml

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://localhost:3306/myDB"/>
		<property name="username" value="root"/>
		<property name="password" value="abc"/>
 	</bean>
 	
 	<bean id="sessionFactory" 
               class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		
		<property name="annotatedClasses">
     		<list>
       			<value>dj.pojo.Plant</value>
     		</list>
   		</property>
		
   		<property name="hibernateProperties">
   			<value>
   				hibernate.dialect = org.hibernate.dialect.MySQLDialect
   				hibernate.show_sql = true
   				hibernate.format_sql = true
   				hbm2ddl.auto = create
   			</value>
   		</property>
	</bean>
	
	<bean id="hibernateTemplate" 
                   class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
	<bean id="plantDao" class="dj.dao.PlantDao">
		<property name="hibernateTemplate" ref="hibernateTemplate"/>
	</bean>
 

PlantDao.java

public class PlantDao{
        private HibernateTemplate hibernateTemplate;
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	public void save(Plant plant){
		this.getHibernateTemplate().save(plant);
	}
	
	public static void main(String[] args){
		ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
		PlantDao pd=(PlantDao) ctx.getBean("plantDao");
		Plant plant=new Plant();
		plant.setName("data");
		pd.save(plant);
		
	}
}
 

这里的main方法主要是用于测试,当然更标准的测试需要使用Junit。注意在Spring中applicationContext默认是放在WEB-INF目录中,但为了测试方便我把它放在src里了。

 

因为所有DAO类中都会有HibernateTemplate的bean方法,于是

private HibernateTemplate hibernateTemplate;
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

 这段代码就会大量重复。

 

考虑到复用性,我们将这段代码封装在独立的类中,让所有DAO类继承。不过这个类Spring已经有了,那就是HibernateDaoSupport(除此之外,HibernateDaoSupport也有SessionFactory的bean方法),于是PlantDao.java可以简化为:

 

PlantDao.java

public class PlantDao extends HibernateDaoSupport{

	public void save(Plant plant){
		this.getHibernateTemplate().save(plant);
	}

	public static void main(String[] args){
		ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
		PlantDao pd=(PlantDao) ctx.getBean("plantDao");
		Plant plant=new Plant();
		plant.setName("data");
		pd.save(plant);
		
	}
} 

 

到目前为止,我们所使用的是XML的注入方式,那么如果用annotation呢?

 

如果实际测试一下,你会发现出现了类似底下的异常:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'plantDao' defined in file [E:\javaWorks\plantAtlas\WebRoot\WEB-INF\classes\dj\dao\PlantDao.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required

 

它找不到SessionFactory或者HibernateTemplate,即SessionFactory或者HibernateTemplate没有注入给DAO类!

 

原因在于HibernateDaoSupport的setter方法前并没有加入@Resource这样的注解,并且它的所有bean方法都是不可改写的(final),这就相当于你的DAO类和HibernateTemplate都被实例化了(DAO实例化需要使用@Component注解)但DAO实例并没有被注入HibernateTemplate,即:

DataSource -> SessionFactory -> HibernateTemplate ,DAO

HibernateTemplate与DAO之间的注入关系断开了

 

解决此问题的方法是:

    重写一个加入了 @RecourceHibernateDaoSupport 的替代类,让 DAO 类继承

 

以下是使用annotation方式注入的相关代码:

 

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<context:annotation-config />
	<context:component-scan base-package="dj.dao"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://localhost:3306/myDB"/>
		<property name="username" value="root"/>
		<property name="password" value="abc"/>
 	</bean>
 	
 	<bean id="sessionFactory" 
               class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		
		<property name="annotatedClasses">
     		<list>
       			<value>dj.pojo.Plant</value>
     		</list>
   		</property>
		
   		<property name="hibernateProperties">
   			<value>
   				hibernate.dialect = org.hibernate.dialect.MySQLDialect
   				hibernate.show_sql = true
   				hibernate.format_sql = true
   				hbm2ddl.auto = create
   			</value>
   		</property>
	</bean>
	
	<bean id="hibernateTemplate" 
                   class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
</beans>
  

 

PlanteDao.java

@Component
public class PlantDao extends SuperDao{
   
    public void save(Plant plant){
        this.getHibernateTemplate().save(plant);
    }
   
    public static void main(String[] args){
        ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        PlantDao pd=(PlantDao) ctx.getBean("plantDao");
        Plant plant=new Plant();
        plant.setName("sae");
        pd.save(plant);
       
    }
}

 

SuperDao.java

public class SuperDao {
	private HibernateTemplate hibernateTemplate;
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	@Resource
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
		System.out.println("hibernateTemplate is null:"+hibernateTemplate==null);
	}
}

 

 

测试,ok!

到此算讲完了,这是我的第一篇关于程序开发的博客,欢迎各位拍砖。

以上!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值