Spring与Hibernate整合小细节与测试问题

来源:互联网 发布:2016淘宝新店如何运营 编辑:程序博客网 时间:2024/06/06 13:10

学习SSH框架的童鞋们肯定有一个学习过程,此篇文章详述了关于Spring和Hibernater整合会遇到的一些小问题,废话不多说,接下来开始正文

首先贴出来文件目录结构:


1:Spring和Hibernate支持添加顺序

首先添加Spring支持,而后在添加Hibernate支持时,一定要将Hibernate的工具包添加入Spring configuration file中,点击下一步中勾选Existing Spring configuration file。

这两步作用则是将以往Hibernate.cfg.xml文件中的内容迁移至Spring配置文件中,完成配置文件的整合(注意文件头部可能会因为某些包未引入而产生文件找不到错误)

2:整合配合文件中配置事务:声明式事务配置

作用是使用session进行数据库操作前后,无需手动调用beginTransaction和事务提交,交由Spring管理,具体配置如下:

<!-- 声明式事务配置 --><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory"><ref local="sessionFactory" /></property></bean>
<!-- AOP切面声明事务管理 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 支持当前事务,如果执行到save开头的任何方法时没有事务则开启一个事务--><tx:method name="save*" propagation="REQUIRED" /> <!-- 支持当前事务,如果执行到update开头的任何方法时没有事务则开启一个事务 --><tx:method name="update*" propagation="REQUIRED" /><!-- 支持当前事务,如果执行到add开头的任何方法时没有事务则开启一个事务 --><tx:method name="add*" propagation="REQUIRED" /><!-- 支持当前事务,如果执行到delete开头的任何方法时没有事务则开启一个事务 --><tx:method name="delete*" propagation="REQUIRED" /><!-- 支持当前事务,查询没有事务,就以非事务方式执行。只读 --><tx:method name="get*" propagation="SUPPORTS" read-only="true" /><!-- 支持当前事务,查询没有事务,就以非事务方式执行。只读 --><tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="*" read-only="true" propagation="NOT_SUPPORTED" /></tx:attributes></tx:advice>

3:类通过配置标签bean注册入ApplicationContext.xml

类的注册分为有无值注入两种

简单的一种无值注入,也就是类中没有需要通过xml实例对象注入到类中的:

<span style="white-space:pre"></span><bean id="advice" class="com.aop.advice.Advice"></bean>
复杂点儿的有值注入,也就是类中有私有数据成员为其他类的对象,这时就需要通过xml实例对象然后进行注入:

<span style="white-space:pre"></span><bean id="userDao1" class="com.hp.dao.impl.UserDaoJDBCImpl" /><bean id="userservice" class="com.hp.service.UserService"><property name="userDao" ref="userDao1" /></bean>
上贴代码,就是在UserService类中有一个私有数据成员:private UserDaoJDBCImpl userDao;

过程是:通过bean:userservice获取对象时,通过配置文件的属性ref指代的bean,映射到相应的类,实例一个对象,而后进行对象注入到UserService中,实例出来一个UserService对象。

需要注意的是,注入时找的注入方法:应为set+name属性首字母大写(ref属性映射的类);例如:以上例子找的方法应该为

public void setUserDao(UserDaoJDBCImpl userDao);

4:SessionFactory注入

session工厂注入点:

考虑到哪儿用到session就注入到哪个类中,可得到结果注入位置应为dao.impl,即应在每个对数据库操作的实现类中

注入方式:

1:hibernate配置整合入spring框架中时,spring配置文件中有bean建立了对SessionFactory

<span style="white-space:pre"></span><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/shop"></property><property name="username" value="sa"></property><property name="password" value="123456"></property></bean><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><!-- 保证数据库连接通畅 --><property name="dataSource"><ref bean="dataSource" /></property><!-- 常规属性设置,方言(本地化处理) --><property name="hibernateProperties"><props><!-- 设置Hibernate方言 --><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><!-- 是否打印sql --><prop key="hibernate.show_sql">true</prop><!-- 格式化sql --><prop key="hibernate.format_sql">true</prop><!-- 是否自动更新表 --><prop key="hibernate.hbm2ddl.auto">update</prop><prop key="hibernate.current_session_context_class">thread</prop><!-- 最大抓取深度,如果为0,则关闭默认的外连接抓取。建议值为0-3 --><prop key="hibernate.max_fetch_depth">1</prop><!-- 用于生成有助于调试的注释信息,默认为关闭 --><prop key="hibernate.use_sql_comments">true</prop><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop></props></property>

2:仔细阅读标注3的有值注入方式,在property 标签中ref引用SessionFactory的bean id

<span style="white-space:pre"></span><bean id="productDao" class="com.aop.dao.impl.ProductDaoImpl"><property name="sessionFactory" ref="sessionFactory"></property></bean>

3:在Spring框架中自带有对Session工程的管理类HibernateTemplate,所以值注入的是SessionFactory,但需要转换成HibernateTemplate进行管理

ProductDaoImpl类中添加HibernateTemplate属性及必要的注入方法:

<span style="white-space:pre"></span>//增加hibernateTemplate属性private HibernateTemplate hibernateTemplate;public void setSessionFactory(SessionFactory sessionFactory) {this.hibernateTemplate =new HibernateTemplate(sessionFactory);}
然后你就可以把hibernateTemplate当做session来进行数据库操作了,例如:

<span style="white-space:pre"></span>public void deleteCategory(Category category) {hibernateTemplate.delete(category);}
由于前面已经讲述了在xml中配置声明式事务,所以在操作是无需手动控制事务的开启和提交

5:测试时小问题

之所以贴出来delete删除方法,是提醒各位需要注意,hibernate处理的对象分为持久态和游离态,当你创建一个匿名对象用于删除时,如果数据库其他字段设置不允许为空,而你创建的匿名对象其他字段为空时,在删除操作过程前的对象持久化,则会出现问题,切记切记


声明:以上英文字符串除了代码段是贴过来的不会出错外,其余纯手工(笔者外语学的是俄语。。。),如有出错,还望海涵
笔者也是在学习阶段,有什么说错的地方或者描述不详细的地方还望指出,一块儿学习



1 0
原创粉丝点击