本章简介
第1章、第2章中分别介绍了 Spring的控制反转和面向切面编程,我们了解了依赖注入的含义、依赖注入的方式、面向切面的编程以及4种通知。本章先介绍Spring与Hibernate整合的目的,然后采用对Emp表的CURD作为综合案例,介绍两大框架整合的步骤、关键整合点、整合之后如何操作数据库。最后采用Spring的声明式事务对Hibernate进行管理,增加程序的健壮性。
核心技能部分
第1章
1.1 Spring与Hibernate整合简介
当我们用JDBC编程的时候,数据库操作的代码非常繁琐,后来学习Hibernate,数据库的操作代码大大简化,但代码仍然比较繁琐,我们可以充分使用Spring依赖注入和AOP简化Hibernate应用。
Spring在资源管理、DAO 的实现及事务策略方面提供与Hibernate 的集成,通过IOC对Hibernate提供一流的支持,并在解决典型的 Hibernate整合问题中展现了突出的作用。Spring提供的支持都遵循其通用的事务及DAO异常体系。
在实际应用开发中,web程序的依赖关系是这样的:Action依赖Biz,Biz依赖DAO,DAO依赖SessionFactory,SessionFactory依赖DataSource。可以使用Spring的依赖注入来管理这些对象。事务处理在实际应用中非常重要,如果在每个涉及数据库操作的方法中都加入事务控制代码,那将是一件很痛苦的事情,而Spring AOP可以很好的解决这个问题。
Spring 向不同的事务 API提供一致的编程模型,提供比传统事务 API更简单且易用的编程式事务管理 API,能够整合数据访问,支持声明式事务管理。
1.1 Spring与Hibernate整合
我们以操作emp表为例,来探索两大框架的整合过程。
1.1.1 处理SessionFactory
Spring与Hibernate集成开发主要包括两种方式,二者的区别在于配置文件的使用。
1.将Spring与Hibernate各自的配置文件进行合并
两种方式都可以使用MyEclipse工具完成,操作步骤如下:
步骤1 添加Spring特性,如图4.1.2所示。
步骤2 勾选Spring支持包,如图4.1.3所示。
步骤6 把Hibernate配置放入现有的Spring配置文件,生成sessionFactory,如图4.1.7所示。
步骤7 确定数据库信息,完成配置,如图4.1.8所示。
2. Spring与Hibernate分别使用各自的配置文件
当需要将Spring的配置文件与Hibernate配置文件分开配置的时候,只有步骤5和步骤6不一样,分别将两个步骤替换如下:
步骤5 勾选单独的Hibernate配置文件,如图4.1.9所示。
步骤6 生成Hibernate配置文件和sessionFactory,如图4.1.10所示。
合并后的配置文件如示例4.1所示。
示例4.1
<!-- dataSource的配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver">
</property>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">
</property>
<property name="username" value="scott"></property>
<property name="password" value="tiger"></property>
</bean>
<!-- sessionFactory的配置 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<!—显示sql语句 -->
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
<!—映射文件的配置-->
<property name="mappingResources">
<list>
<value>entity/Emp.hbm.xml</value>
</list>
</property>
</bean>
两个文件单独配置时,Spring配置如示例4.2所示。
示例4.2
<!-- 加载Hibernate配置 -->
<!-- 定义Hibernate的SessionFactory bean -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 使用Spring提供的LocalSessionFactoryBean,传入一个Hibernate配置文件的位置 -->
<property name="configLocation" value="file:src/hibernate.cfg.xml">
</property>
</bean>
无论使用哪种整合方式,在Spring配置文件中都有一个sessionFactory,我们知道Hibernate对数据库的操作依靠session完成,而sessionFactory正是用来产生session。
1.1.1 使用HibernateTemplate简化DAO
Spring提供多种数据库访问技术的DAO支持,可以使用相同的访问模式,使用不同的数据库访问技术。这种DAO支持大大地减少数据库访问的代码量,提高开发效率。接下来我们设计如示例4.3所示的DAO接口。
示例4.3
public interface EmpDao {
public void addEmp(Emp emp);
public void delEmp(short empNo);
public void updateEmp(Emp emp);
public Emp get(short empNo);
public List searchEmp(Emp emp);
public List searchEmp(String hql);
}
我们可以使用Spring提供的HibernateTemplate来简化EmpDao的实现。如示例4.4所示。
示例4.4
public class EmpDaoImpl extends HibernateDaoSupport implements EmpDao {
public void addEmp(Emp emp) {
super.getHibernateTemplate().save(emp);
}
public void delEmp(short empNo) {
super.getHibernateTemplate().delete(this.get(empNo));
}
public Emp get(short empNo) {
Emp emp = (Emp) super.getHibernateTemplate().get(Emp.class, empNo);
return emp;
}
public List searchEmp(final Emp condition) {
List list = super.getHibernateTemplate().executeFind(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
// 构建查询
Criteria c = session.createCriteria(Emp.class);
if (condition != null) {
// 构造Criteria查询条件的代码
}
return c.list();
}
});
return list;
}
public List searchEmp(String hql) {
return super.getHibernateTemplate().find(hql);
}
public void updateEmp(Emp emp) {
super.getHibernateTemplate().update(emp);
}
}
在示例4.4现中,我们发现Spring提供的HibernateDaoSupport类可以简化Hibernate的开发。HibernateDaoSupport类提供了getHibernateTemplate()方法获得HibernateTemplate对象,HibernateTemplate对象提供了非常多的方法,如表4-1-1所示。
表4-1-1 HibernateTemplate常用的方法
编号 |
方法 |
功能 |
1 |
find(String queryString) |
根据HQL查询字符串来返回集合示例 |
2 |
save(Object entity) |
保存新的示例 |
3 |
update(Object entity) |
根据给定的持久化对象更新记录 |
4 |
delete(Object entity) |
删除指定持久化实例 |
5 |
deleteAll(Collection entities) |
删除集合内全部持久化类实例 |
6 |
get(Class entityClass,Serializable id) |
根据主键加载特定持久化类的实例 |
7 |
saveOrUpdate(Object entity) |
根据实例状态,选择保存或更新 |
我们并没有在示例4.4中看到有关SessionFactory的代码,Spring为HibernateDaoSupport类提供了setSessionFactory方法,我们将通过这个setter方法向DAO类注入SessionFactory。配置方式如示例4.5所示。
示例4.5
<!--EmpDaoImpl的配置 -->
<bean id="EmpDao" class="dao.impl.EmpDaoImpl">
<!-- 注入sessionFactory -->
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
1.1.2 业务层的处理
我们已经完成了EmpDao的定义,将EmpDao注入到empBiz中需要在EmpBiz中增加EmpDao属性及对应setter和getter方法。
代码如示例4.6所示。
示例4.6
public class EmpBizImpl implements EmpBiz {
private EmpDao EmpDao;
public void addEmp(Emp emp) {
EmpDao.addEmp(emp);
}
public void delEmp(short empNo) {
EmpDao.delEmp(empNo);
}
public Emp get(short empNo) {
return EmpDao.get(empNo);
}
public List searchEmp(Emp condition) {
return EmpDao.searchEmp(condition);
}
public List searchAllEmp() {
String hql="from Emp";
return EmpDao.searchEmp(hql);
}
public void updateEmp(Emp emp) {
EmpDao.updateEmp(emp);
}
//setter & getter
}
在Spring配置文件中,我们需要在业务逻辑中注入DAO,如示例4.7所示。
示例4.7
<bean id="empBiz" class="biz.impl.EmpBizImpl">
<property name="EmpDao" ref="EmpDao"></property>
</bean>
1.1 声明式事务
之前我们编写的程序,事务都是在DAO层控制,在实际应用开发中显然是不合适的。比如某银行的业务逻辑方法中需要对DAO进行多次调用,如示例4.8所示。
示例4.8
public void transferAccount(CardVo from,CardVo to,double money)
{
from.setMoney(from.getMoney()+money);
cardDAO.update(from);//修改转账人账户
to.setMoney(to.getMoney()-money);
cardDAO.update(to);//修改收款账户
RecordVO record=new RecordVO(from,to,money);
recordDAO.add(record);//增加交易记录
}
这个业务方法中执行了三个持久化操作,根据业务需求要求这三个操作要么全部成功,要么都不能成功,也就是:客观上需要对业务逻辑层的方法进行事务控制。
事务处理是企业应用开发中不能回避的一个重要问题。在Hibernate风行之前,JDBC是数据持久化的主要手段,为了达到在业务逻辑层进行事务控制,一个通用的做法是将Connection对象以参数的形式传来传去。业务逻辑层应该只出现描述业务逻辑的代码,Connection在业务逻辑层的出现破坏了三层结构的基本原则。另外一个做法是将业务逻辑放到DAO层实现,DAO层依据业务逻辑创建方法,编写复杂的业务逻辑代码,这样进行架构设计的系统很快就会尝到苦果。
事务是系统开发过程中的一个方面,散步在系统里,我们可以通过AOP来实现。
1.1.1 事务通知
使用Spring的声明式事务,我们无需编写程序代码,所有的工作都在配置文件中完成,这种不需要编程的事务称为“声明式事务”。配置事务通知需要先声明一个事务管理器,我们可以新建一个aop.xml文件,将事务配置放在该配置文件中。如示例4.9所示。
示例4.9
<!-- 事务管理器的配置 -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<!-- 注入applicationContext.xml中配置的sessionFactory -->
<ref bean="sessionFactory" />
</property>
</bean>
接下来可以使用 Spring带有的一个<tx:advice>标签,该标签会创建一个事务通知,我们所需要的就是创建一个切入点,该切入点配置所有带事务的方法并引用事务性通知。事务通知的配置如示例4.10所示,该示例采用Spring2.x方式,需要加入命名空间的引用。
示例4.10
<!-- 事务通知的配置,需要指定一个事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- 定义属性,声明事务规则 -->
<tx:attributes>
<!-- 对get/find/search/query开头的方法要求只读事务 -->
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="search*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
<!-- 对add/del/update/do开头的方法要求必须运行在事务环境中 -->
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="do*" propagation="REQUIRED" />
<!-- 对其他方法采用如下配置 -->
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
在<tx:advice>标签内设值id和transaction-manager属性,id是advice Bean的标识,而transaction-manager引用一个事务管理器。
除了这两个属性外,还可以通过<tx:attributes/>标签配置事务属性。<tx:method>的propagation属性表示事务的传播行为,REQUIRED表示如果存在一个事务,则支持当前事务,如果当前没有事务,则开启一个新的事务。SUPPORTS表示如果存在一个事务,则支持当前事务,如果当前没有事务,则按非事务方式执行。<tx:method> 的属性name="*"表示匹配所有其他的方法readOnly表示启用只读事务。这样数据库库就可以采取合适的优化措施避免不必要的操作。
1.1.2 事务通知和切入点组合
我们已经定义一个id为txAdvice的事务通知,接下来,我们需要将事务通知和切入点组合,最合适的切入点是biz的方法,可以是接口中声明的方法,也可以直接将切入点定义为biz实现的方法。代码片段如示例4.11所示。
示例4.11
<!-- 将事务通知和切入点组合 -->
<aop:config>
<aop:pointcut expression="execution(* biz.*.*(..))" id="pc" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc" />
</aop:config>
上面的代码表示biz包下所有类的所有方法都应用事务规则。至此,Spring与 Hibernate的整合完成。数据库操作还是需要Hibernate完成,Spring起到管理的作用,比如Spring管理各个Bean,管理Hibernate的事务。这样的代码不但简介,而且健壮性也得到了很好的保证,是企业应用开发的首选。
对以上整合的测试代码如示例4.12所示。
示例4.12
public static void main(String[] args) throws ParseException {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml", "aop.xml" });
EmpBiz empBiz = (EmpBiz) context.getBean("empBiz");
Emp emp = new Emp();
emp.setEmpno((short) 1000);
emp.setEname("张翠山");
emp.setJob("主管");
emp.setMgr((short) 7879);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date hiredate = sdf.parse("2001-12-12");
emp.setHiredate(new Timestamp(hiredate.getTime()));
emp.setSal(8000.0);
emp.setComm(2000.0);
emp.setDeptno((byte) 20);
empBiz.addEmp(emp);//添加新员工
}
添加之后,数据库的记录如图4.1.11所示:
测试查询所有的员工,如示例4.13所示。
示例4.13
List<Emp> empList = empBiz.searchAllEmp();
for (Emp emp : empList) {
System.out.println(emp.getEmpno() + "\t" + emp.getEname() + "\t"
+ emp.getSal() + "\t" + emp.getComm());
}
测试结果如图4.1.12所示。
1.1 使用工具生成Spring DAO
开发过程中,一般通过反向工程生成表对应的实体对象,同时也可以勾选Spring DAO选项,通过MyEclipse生成实体对象的DAO。操作如图4.1.13所示。
生成的DAO代码如示例4.14所示。
示例4.14
public class EmpDao extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(EmpDao.class);
// property constants
public static final String ENAME = "ename";
public static final String JOB = "job";
public static final String MGR = "mgr";
public static final String SAL = "sal";
public static final String COMM = "comm";
public static final String DEPTNO = "deptno";
protected void initDao() {
// do nothing
}
public void save(Emp transientInstance) {
log.debug("saving Emp instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
public void delete(Emp persistentInstance) {
log.debug("deleting Emp instance");
try {
getHibernateTemplate().delete(persistentInstance);
log.debug("delete successful");
} catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
}
public Emp findById(java.lang.Short id) {
log.debug("getting Emp instance with id: " + id);
try {
Emp instance = (Emp) getHibernateTemplate().get("orm.Emp", id);
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
public List findByExample(Emp instance) {
log.debug("finding Emp instance by example");
try {
List results = getHibernateTemplate().findByExample(instance);
log.debug("find by example successful, result size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find by example failed", re);
throw re;
}
}
public List findByProperty(String propertyName, Object value) {
log.debug("finding Emp instance with property: " + propertyName
+ ", value: " + value);
try {
String queryString = "from Emp as model where model."
+ propertyName + "= ?";
return getHibernateTemplate().find(queryString, value);
} catch (RuntimeException re) {
log.error("find by property name failed", re);
throw re;
}
}
public List findByEname(Object ename) {
return findByProperty(ENAME, ename);
}
public List findByJob(Object job) {
return findByProperty(JOB, job);
}
public List findByMgr(Object mgr) {
return findByProperty(MGR, mgr);
}
public List findBySal(Object sal) {
return findByProperty(SAL, sal);
}
public List findByComm(Object comm) {
return findByProperty(COMM, comm);
}
public List findByDeptno(Object deptno) {
return findByProperty(DEPTNO, deptno);
}
public List findAll() {
log.debug("finding all Emp instances");
try {
String queryString = "from Emp";
return getHibernateTemplate().find(queryString);
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
}
public Emp merge(Emp detachedInstance) {
log.debug("merging Emp instance");
try {
Emp result = (Emp) getHibernateTemplate().merge(detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
public void attachDirty(Emp instance) {
log.debug("attaching dirty Emp instance");
try {
getHibernateTemplate().saveOrUpdate(instance);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}
public void attachClean(Emp instance) {
log.debug("attaching clean Emp instance");
try {
getHibernateTemplate().lock(instance, LockMode.NONE);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}
public static EmpDao getFromApplicationContext(ApplicationContext ctx) {
return (EmpDao) ctx.getBean("EmpDao");
}
}
以上代码我们可以看到,使用工具生成的DAO中有大量的方法,这些方法我们可以直接在业务层调用,也会在配置文件中自动配置。这些方法的功能描述见表4-1-2所示。
表4-1-2 DAO的方法及功能描述
方法名称 |
描述 |
void save(Emp transientInstance) |
根据对象添加 |
delete(Emp persistentInstance) |
根据对象删除 |
findById(java.lang.Short id) |
根据ID查询对象 |
findByExample(Emp instance) |
根据对象查询,查询条件为对象的属性值 |
findByEname(Object ename) |
根据员工名查询 |
findAll() |
查询所有员工 |
merge(Emp detachedInstance) |
合并session中存在相同ID的对象 |
attachDirty(Emp instance) |
添加与修改,相当于saveOrUpdate |
attachClean(Emp instance) |
将传入的对象状态设值为Transient状态 |
本章总结
Ø Spring整合Hibernate
n 配置SessionFactory
n HibernateTemplate
n HibernateDaoSupport
Ø 声明式事务管理
n 配置事物管理器HibernateTransactionManager
n 使用<tx:advice>结合事务管理器配置事物通知
n 在<tx:advice>内使用<tx:attributes>和<tx:method>针对不同的方法配置事物属性
Ø 使用工具自动生成 Spring DAO
任务实训部分
1:完成银行账户系统的框架搭建
训练技能点
Ø sessionFactory的配置
Ø HibernateTemplate的使用
需求说明
某银行系统需要开发一个小系统,该系统能查看账户信息、销户、开户、转账、查看交易记录等功能,要求使用Spring+Hibernate实现。该系统两张表,分别是账户信息表、交易记录表,账户信息表的字段说明如表4-2-1所示。
表4-2-1 账户信息表(ACCOUNT)
编号 |
字段名称 |
字段说明 |
1 |
ACCOUNT_ID |
账户ID,主键使用序列seq_account,number(10) |
2 |
USER_NAME |
账户名,varchar2(20); |
3 |
MONEY |
账户余额,number(6) |
4 |
CREATEDATE |
开户时间,date |
交易记录表的字段说明如表4-2-2所示。
表4-2-2 交易记录表(TBL_RECORD)
编号 |
字段名称 |
字段说明 |
1 |
RECORD_ID |
交易编号,主键使用序列seq_record,number(10) |
2 |
FROMACCOUNT |
转出帐号,number(10) |
3 |
TOACCOUNT |
转入帐号,number(10) |
4 |
RECORD_DATE |
交易时间,date |
5 |
REMARK |
备注 varchar2(80) |
实现思路
(1) 创建数据表。
(2) 为项目添加Spring和Hibernate支持。
(3) 编写实体类和映射文件。
(4) 定义DAO接口和实现。
(5) 定义Biz接口和实现。
关键代码
(1) 配置文件的配置。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver">
</property>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl">
</property>
<property name="username" value="scott"></property>
<property name="password" value="tiger"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>orm/Account.hbm.xml</value>
<value>orm/TblRecord.hbm.xml</value>
</list>
</property>
</bean>
(2) 实体类和映射文件。
//账户实体类
public class Account implements java.io.Serializable {
private Long accountId;//账户编号
private String userName;//账户名
private Integer money;//余额
private Timestamp createdate;//开户时间
//setter & getter
}
//交易记录实体
public class TblRecord implements java.io.Serializable {
private Long recordId;//交易编号
private Long fromaccount;//转账账户编号
private Long toaccount;//收款帐号
private Timestamp recordDate;//转账时间
private String remark;//备注
//setter & getter
}
(3) 定义DAO接口和实现,DAO实现需要继承HibernateDaoSupport,但不写方法和方法体。
//账户DAO
public interface AccountDAO {
}
//交易记录DAO
public interface RecordDAO {
}
(4) 定义Biz接口和实现,Biz的实现类需要增加两个属性,AccountDAO和RecordDAO,并生成setter和getter方法,但不添加任何方法和方法体。
//业务逻辑接口
public interface BankBiz {
}
2:声明式事务配置
训练技能点
Ø 声明式事务
需求说明
完善框架搭建,增加Biz和DAO的配置件和声明式事务。
实现思路
(1) 增加Biz和DAO的配置。
(2) 编写配置文件,增加声明式事务配置。
3:实现银行系统的开户和查看账户信息功能
训练技能点
Ø HibernateTemplate的使用
需求说明
实现开户和账户信息查询功能。
实现思路
(1) 完善DAO层的实现,编写方法和方法体。
(2) 完善Biz层的实现,编写方法和方法体。
(3) 编写测试代码,测试开户和账户信息查看功能。
关键代码
(1)在DAO中增加以下方法声明,并实现DAO的方法。
//RecordDAO中的方法声明
public TblRecord get(long id);
public void addRecord(TblRecord record);//增加交易记录
public void delRecord(long recordId);//删除交易记录
//AccountDAO中的方法声明
public Account get(long id);//根据主键查询账户信息
public void addAccount(Account account);//添加账户信息
public void delAccount(long id);//根据主键删除账户信息
public void updateAccount(Account account);//修改账户信息
public List findAllAccount();//查询所有账户信息
(2) 在Biz中增加以下方法声明,并实现Biz的方法。
//BankBiz接口中添加的方法声明
public Account findAccountById(long id);//查询账户信息
public void doAddAcount(Account account);//用户开户
//BankBiz方法的实现
public void doAddAcount(Account account) {
accountDAO.addAccount(account);
}
public Account findAccountById(long id) {
return accountDAO.get(id);
}
4:完善银行系统,增加转账功能
训练技能点
Ø HibernateTemplate的使用
Ø 业务逻辑层的实现
需求说明
实现转账功能。
实现思路
(1) 在Biz接口中增加转账方法声明。
(2) 实现转账方法。
(3) 编写测试代码,测试转账功能。
关键代码
(1)在Biz接口中增加转账方法声明。
//BankBiz中声明转账方法
public boolean doTransferAccount(long from,long to,int money);//转账
(2) 实现转账方法。
public boolean doTransferAccount(long from, long to, int money) {
boolean result = false;
// 根据编号获取账户信息
Account from_Account = accountDAO.get(from);
Account to_Account = accountDAO.get(to);
if (from_Account!=null&&from_Account.getMoney() > money)// 如果余额大于转账金额
{
if (to_Account != null)// 如果收款帐号存在
{
//扣除转账人账户余额
//添加收款人账户余额
//记录交易记录
result = true;
}
}
return result;
}
巩固练习
一.选择题
以下关于Spring对Hibernate提供支持的说法中,错误的是()。
A. Spring提供了基类大大简化了程序代码
B. Spring提供的基类支持分页查询
C. Spring提供的基类需要注入sessionFactory才能正常运行
D. Spring提供的基类不需要注入sessionFactory
2. Spring整合Hibernate后,能够用于保存数据的方法有()。
A. save
B. load
C. saveOrUpdate
D. merge
3. Spring整合Hibernate后,以下关于findByCriteria方法的说法中,正确的是()。
A. 参数是HQL
B. 参数是Restrictions对象
C. 参数是DetachedCriteria对象
D. 该方法不支持分页
4. 以下关于 Spring与Hibernate集成的说法中,错误的是()。
A. 通过集成Spring与Hibernate,以Spring管理程序的依赖关系,将SessionFactory注入 DataSource
B. 通过Spring,在Biz层代码中无须直接实例化DAO类,而是通过注入获得
C. 通过Spring,在DAO类中无须实例化SessionFactory,而是通过注入获得
D. Spring提供HibemateDaoSupport类简化Hibernate的使用
5.关于声明式事务,下面说法错误的是()。
A.Spring采用AOP方式实现声明式事务
B.声明式事务是非侵入式的,可以不修改原来代码就给系统增加事务支持
C.配置声明式事务必须tx和aop两个命名空间的支持
D.事务有编程式事务和非编程式事务,声明式事务是非编程式事务
二.操作题
1.结合EMP的CURD,编写一个业务方法,实现员工的分页查询,每页显示5条员工信息。
2.查看课外书籍,使用注解重构实训任务的声明式事务。
3.升级实训任务,实现交易记录的分页查询。
提示:分页查询的实现
List list = super.getHibernateTemplate().executeFind(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
String hql = "from TblRecord record where record.fromaccount=" + fromId;
Query query = session.createQuery(hql);
query.setFirstResult(firstResult);
query.setMaxResults(5);
return query.list();
}
});
4.重构“会员账户管理系统”,使用Hibernate实现DAO层开发,并编写测试代码,测试业务逻辑层的功能。要求使用声明式事务,每项业务操作都必须有日志记录。