Dao层通用化,Spring3.0+Hibernate3.3.2通用Dao层整合
Dao层通用化,Spring3.0+Hibernate3.3.2通用Dao层整合
数据Dao层大家也写了很多了,只要是每对应一个表的话就会有对应的一个类进行增删查改(没算中间表),如果按照面向对象的思维来讲,中间表也算一个表也应该有对应的Dao层操作.Dao层操作其实无非就是数据库中的表进行增删改查这几个功能,如果可以把所有增删查改方法统一做成一个通用的增删改查方法多好啊.想起之前写过通用JDBC增删改查功能法,既然JDBC可以那换成框架组合也一定可以,利用JDK5.0的新特性泛型,可以很好的帮助我把目前主流的2大框架Spring和Hibernate很好的整合起来,方便以后我们操作.
框架采用目前比较新的Spring3.0和Hibernate3.3.2GA进行组合,由于Spring3.0的Jar包只是带了自身功能的不像 2.5.6把所有需要的依赖包都带上了,而Spring3.0把所有功能的包都拆分成为每个独立的Jar包不会像Spring2.5.6分成功能整合包 Spring.jar和按功能模块分类的包(功能模块包位置在\dist\modules 下)先把Spring3.0Jar包大概介绍一下:
org.springframework.aop-3.0.0.RELEASE--------------------Spring的面向切面编程,提供AOP(面向切面编程)实现
org.springframework.asm-3.0.0.RELEASE--------------------Spring独立的asm程序,相遇Spring2.5.6的时候需要asmJar 包.3.0开始提供他自己独立的asmJar
org.springframework.aspects-3.0.0.RELEASE----------------Spring提供对AspectJ框架的整合\
org.springframework.beans-3.0.0.RELEASE------------------SpringIoC(依赖注入)的基础实现
org.springframework.context.support-3.0.0.RELEASE--------Spring-context的扩展支持,用于MVC方面
org.springframework.context-3.0.0.RELEASE----------------Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等
org.springframework.core-3.0.0.RELEASE-------------------Spring3.0的核心工具包
org.springframework.expression-3.0.0.RELEASE-------------Spring表达式语言
org.springframework.instrument.tomcat-3.0.0.RELEASE------Spring3.0对Tomcat的连接池的集成
org.springframework.instrument-3.0.0.RELEASE-------------Spring3.0对服务器的代理接口
org.springframework.jdbc-3.0.0.RELEASE-------------------对JDBC的简单封装
org.springframework.jms-3.0.0.RELEASE--------------------为简化JMS API的使用而作的简单封装
org.springframework.orm-3.0.0.RELEASE--------------------整合第三方的ORM框架,如hibernate,ibatis,jdo,以及 spring的JPA实现
org.springframework.oxm-3.0.0.RELEASE--------------------Spring对Object/XMl的映射支持,可以让Java与XML之间来回切换
org.springframework.test-3.0.0.RELEASE--------------------对Junit等测试框架的简单封装
org.springframework.transaction-3.0.0.RELEASE-------------为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理
org.springframework.web.portlet-3.0.0.RELEASE-------------SpringMVC的增强
org.springframework.web.servlet-3.0.0.RELEASE-------------对JEE6.0 Servlet3.0的支持
org.springframework.web.struts-3.0.0.RELEASE--------------整合Struts的时候的支持
org.springframework.web-3.0.0.RELEASE--------------------SpringWeb下的工具包
由于3.0的新加的新特性比较多这里采用的还是基于2.5.6版本的改变进行整合
之前介绍了Spring3.0包是按功能进行一个一个进行分类的,并且把需要的依赖包都去掉了,只留下了实现功能的包,那么对于使用 Spring2.5.6的人来讲有点不习惯,但是这些都是小问题,下面我将会从最基本的Spring+Hibernate的整合慢慢转变成通用的Dao 层, ,从Hibernate官网上下载hibernate-distribution-3.3.2.GA-dist.zip,由于我采用的是JPA注解的形式直接对JavaBean进行表的关系跟定义,所以还需要下载hibernate-entitymanager-3.4.0.GA.zip,hibernate-annotations-3.4.0.GA ,然后到Spring官网网站下载spring-framework-3.0.0.RELEASE-with-docs.zip.
待下载完成后首先创建一个Project,我这里用的是Eclipse 3.5版本,创建的是Dynamic Web Project为了以后方便整合Struts2使用, 把从Hibernate官网中下载的Jar包分别解压到各个自己的目录后,分别在 Hibernate3.3.2Ga中找到Hibernate3.jar,\lib\required\下的所有 jar包,\lib\optional\ehcache下的ehcache-1.2.3.jar(用于Hibernate的2级缓存),在\lib \bytecode\cglib加入cglib-2.2(Hibernate中代理用的,实际和用途不是很清楚),在Hibernate-Annotation-3.4.0ga下加入让Hibernate支持JPA的核心包hibernate-annotations.jar、\lib下的ejb3-persistence.jar、hibernate- commons-annotations.jar,最后在hibernate- entitymanager-3.4.0.GA中加入hibernate-entitymanager.jar分别放在/WebContent/WEB-INF/lib目录下,经测试之后发现Hibernate会报错Caused by:java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder 或者Caused by: java.lang.NoClassDefFoundError:org/apache/log4j/LogManager的错误。因为Hibernate3.3提供的jar包,缺少了slf4j-nop-1.5.8.jar这个包,解决方法可以到百度等其他地方下载或者从hibernate-annotations-3.4.0.GA中的\lib\test加入slf4j-log4j12.jar和slf4j-api.jar,加入 slf4j-log4j12.jar后如果没有加入log4j的话也会java.lang.NoClassDefFoundError:org/apache/log4j/LogManager的错误所以还需要加入log4j 的jar包,当所有Hibernate需要的jar包加入后就正式开始我们的第一步:实体bean User:代码如下:
package org.lxh.bean; importjava.io.Serializable; import javax.persistence.Column; importjavax.persistence.Entity; import javax.persistence.GeneratedValue; importjavax.persistence.GenerationType; import javax.persistence.Id; importjavax.persistence.Table; @Entity @Table(name="tb_user") publicclass User implements Serializable{ private Integer id ; private String username; private String password; @Id@GeneratedValue(strategy=GenerationType.IDENTITY) public Integer getId() { return id; } publicvoid setId(Integer id) { this.id = id; } @Column(length=18,unique=true) public String getUsername() { return username; } publicvoid setUsername(String username) { this.username = username; }@Column(length=18) public String getPassword() { return password; } publicvoid setPassword(String password) { this.password = password; } }
创建完实体Bean后,使用Spring的aop模式注入Hibernate的SessionFactory和事务,这样可以不用再另外创建一个Hibernate.cfg.xml文件独立配置
Hibernate和创建一个SessionFactory工具类,直接让Spring进行对Hibernate的事务跟SessionFactory管理,在src目录下创建一个XML文件名字自定义
我这里把Spring的配置文件叫做applicationContext.xml,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"> </property><property name="url" value="jdbc:mysql://localhost:3306/datatest"> </property><property name="username" value="root"></property> <propertyname="password" value="root"></property></bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property><property name="hibernateProperties"> <props> <propkey="hibernate.dialect">org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <propkey="hibernate.format_sql">true</prop> <prop key="hibernate.show_sql">true</prop> </props></property> <property name="packagesToScan"> <list><value>org.lxh.bean</value> </list> </property></bean> </beans> 可以发现上面的XML配置中是有个名为DataSource的bean,因为Spring需要连接池来管理数据库,所以我们需要从Apache的官网上下载对应的Jar包分别是
Commons-dbcp和Commons-pool,把commons-pool-1.5.4.jar和commons-dbcp-1.2.2.jar放入/WebContent/WEB-INF/lib下,这样就不会报错找不到
该类了.这样我们的第一步配置Hibernate到Spring就基本完成
实体Bean创建完毕后,接下来就是关键的Dao层了,为了使各个实体Bean可以只通过一个Dao层进行基本的增删改查,我们采用了JDK1.5里面的新特性泛型进行配置.这里只是简单说明BasicDaoImpl的实现方法,代码如下:
package org.lxh.dao.impl; import java.io.Serializable; import java.util.List; importorg.hibernate.criterion.DetachedCriteria; import org.lxh.dao.interfaces.BasicDaoIf; importorg.springframework.stereotype.Repository; @Repository("basicDao") publicclass BasicDaoImpl<T,PK extends Serializable>extends BasicSupportDao implements BasicDaoIf<T, PK> { @Override publicboolean deleteAll(final T t) {getHibernateTemplate().deleteAll(this.findAll((Class<T>)t.getClass()));returntrue; } @Override publicboolean deleteById(final Class<T>entityClass,final PK id) { getHibernateTemplate().delete(this.findById(entityClass,id)); returntrue; } @Override public List<T> findAll(finalClass<T> entityClass) { returngetHibernateTemplate().findByCriteria(DetachedCriteria.forClass(entityClass));} @Override public T findById(final Class<T>entityClass,final PK id) { return(T)getHibernateTemplate().get(entityClass, id); } @Override publicboolean save(final T t) {getHibernateTemplate().save(t); returntrue; } @Override publicboolean update(final T t) {getHibernateTemplate().update(t); returntrue; }}
Dao层的实现采用SpringJpa的方式,里面的Repository相当于xml中<bean>里面内容,而
basicDao是等同于<beanid=”basicDao”></bean>从类中发现除了引用了接口之外,还会发现继承了一个BasicSupportDao
,BasicSupportDao 目前功能只有一个用于继承Spring中的HibernateDaoSupport,然后把HibernateTemplate注入,如果不采用这个方法的话而采用直接extendsHibernateDaoSupport会出现以下错误代码:"org.springframework.beans.factory.NoSuchBeanDefinitionException:No
bean named 'basicDao' is defined”,因为 Spring在采用JPA定义的时候会把当前类实例化,如果继承了HibernateDaoSupport的话,因为 HibernateDaoSupport源码中SessionFactory和HibernateTemplate是final的不能修改的,所以会报错不能从Spring配置文件中注入,所以必须要新创建一个BasicSupportDao用来代替。代码如下:
package org.lxh.dao.impl; import javax.annotation.Resource; importorg.springframework.orm.hibernate3.HibernateTemplate; importorg.springframework.orm.hibernate3.support.HibernateDaoSupport; publicclass BasicSupportDao extends HibernateDaoSupport {@Resource(name="hibernateTemplate") publicvoid setHibernatetemplate(HibernateTemplatehibernateTemplate){ super.setHibernateTemplate(hibernateTemplate);} }
其中@Resource(name="hibernateTemplate") 是用于指向Spring中配置的xml文件里面bean的id名字为hibernateTemplate, 也可以指向@Service、@Repository、@Component所对应的名字,除了上面的方法可以在BasicDaoImpl中加入 Spring中Hibernate的模板,hibernateTemplate,生成getter、setter方法,也可以运行通过不会报错,在 Spring3.0中的例子是比较推荐使用这种直接加入hibernateTemplate方法的。
注意:如果在publicclass BasicDaoImpl class 前面加入 abstract 的话也会出现找不到basicDao这个错误的,解决方法暂时没有找到