作者:ssslinppp     

1. 摘要



版本:
Spring4.0.4;Hibernate4.3.5;struts2.3.16;
主要介绍了如下内容:
  1. 项目结构的规划;
  2. Spring下整合Hibernate的具体过程;
  3. 整合struts的过程;
  4. 重点介绍Dao层的设计;

2. 项目结构




lib文件:



3. web.xml



因为需要整合struts和Hibernate,所以需要配置spring监听器、以及struts分发器。

  1. <?xml version="1.0" encoding="GBK"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  5. http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  6. <listener>
  7. <listener-class>org.springframework.web.context.ContextLoaderListener
  8. </listener-class>
  9. </listener>
  10. <filter>
  11. <filter-name>struts2</filter-name>
  12. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  13. </filter>
  14. <filter-mapping>
  15. <filter-name>struts2</filter-name>
  16. <url-pattern>/*</url-pattern>
  17. </filter-mapping>
  18. <welcome-file-list>
  19. <welcome-file>/WEB-INF/content/bookForm.jsp</welcome-file>
  20. </welcome-file-list>
  21. </web-app>



4. applicationContext.xml


主要完成了如下工作:
  1. 首先需要配置 数据源,这里使用C3P0数据源;
  2. 配置sessionFactory;
  3. 配置Hibernate事务管理器;
  4. 配置切入点、通告等;



  1. <?xml version="1.0" encoding="GBK"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://www.springframework.org/schema/beans"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:aop="http://www.springframework.org/schema/aop"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  9. http://www.springframework.org/schema/tx
  10. http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
  13. <!-- 定义数据源Bean,使用C3P0数据源实现,并注入数据源的必要信息 -->
  14. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
  15. destroy-method="close"
  16. p:driverClass="com.mysql.jdbc.Driver"
  17. p:jdbcUrl="jdbc:mysql://localhost:3306/sampledb"
  18. p:user="root"
  19. p:password="qaz"
  20. p:maxPoolSize="40"
  21. p:minPoolSize="2"
  22. p:initialPoolSize="2"
  23. p:maxIdleTime="30"/>
  24. <!-- 定义Hibernate的SessionFactory,SessionFactory需要依赖数据源,注入dataSource -->
  25. <bean id="sessionFactory"
  26. class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
  27. p:dataSource-ref="dataSource">
  28. <!-- annotatedClasses用来列出全部持久化类 -->
  29. <property name="annotatedClasses">
  30. <list>
  31. <!-- 以下用来列出所有的PO类-->
  32. <value>org.crazyit.booksys.domain.Book</value>
  33. </list>
  34. </property>
  35. <!-- 定义Hibernate SessionFactory的属性 -->
  36. <property name="hibernateProperties">
  37. <props>
  38. <!-- 指定Hibernate的连接方言 -->
  39. <prop key="hibernate.dialect">
  40. org.hibernate.dialect.MySQL5InnoDBDialect</prop>
  41. <!--是否根据Hiberante映射创建数据表 -->
  42. <prop key="hibernate.hbm2ddl.auto">update</prop>
  43. <prop key="hibernate.show_sql">true</prop>
  44. <prop key="hibernate.format_sql">true</prop>
  45. </props>
  46. </property>
  47. </bean>
  48. <!-- 定义Service组件,并将DAO组件注入Service组件 -->
  49. <bean id="bookService" class="org.crazyit.booksys.service.impl.BookServiceImpl"
  50. p:bookDao-ref="bookDao"/>
  51. <!-- 定义DAO组件,并将SessionFactory注入DAO组件 -->
  52. <bean id="bookDao" class="org.crazyit.booksys.dao.impl.BookDaoHibernate4"
  53. p:sessionFactory-ref="sessionFactory"/>
  54. <!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 -->
  55. <!-- 该类是PlatformTransactionManager接口针对采用Hibernate的特定实现类 -->
  56. <!-- 配置HibernateTransactionManager需依赖注入SessionFactory -->
  57. <bean id="transactionManager"
  58. class="org.springframework.orm.hibernate4.HibernateTransactionManager"
  59. p:sessionFactory-ref="sessionFactory"/>
  60. <!-- 配置事务增强处理Bean,指定事务管理器 -->
  61. <tx:advice id="txAdvice"
  62. transaction-manager="transactionManager">
  63. <!-- 用于配置详细的事务定义 -->
  64. <tx:attributes>
  65. <!-- 所有以'get'开头的方法是read-only的 -->
  66. <tx:method name="get*" read-only="true"/>
  67. <!-- 其他方法使用默认的事务设置,指定超时时长为5秒 -->
  68. <tx:method name="*" isolation="DEFAULT"
  69. propagation="REQUIRED" timeout="5"/>
  70. </tx:attributes>
  71. </tx:advice>
  72. <!-- AOP配置的元素 -->
  73. <aop:config>
  74. <!-- 配置一个切入点 -->
  75. <aop:pointcut id="myPointcut" expression="bean(bookService)"/>
  76. <!-- 指定在myPointcut切入点应用txAdvice事务增强处理 -->
  77. <aop:advisor advice-ref="txAdvice"
  78. pointcut-ref="myPointcut"/>
  79. </aop:config>
  80. </beans>


5. struts.xml


struts.xml配置文件,没有多少要说明的,就是常规的。

  1. <?xml version="1.0" encoding="GBK"?>
  2. <!-- 指定Struts 2配置文件的DTD信息 -->
  3. <!DOCTYPE struts PUBLIC
  4. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  5. "http://struts.apache.org/dtds/struts-2.3.dtd">
  6. <struts>
  7. <!-- 配置了系列常量 -->
  8. <constant name="struts.i18n.encoding" value="GBK"/>
  9. <constant name="struts.enable.DynamicMethodInvocation" value="false" />
  10. <constant name="struts.devMode" value="true"/>
  11. <package name="lee" extends="struts-default">
  12. <action name="addBook" class="org.crazyit.booksys.action.BookAction"
  13. method="add">
  14. <!-- 添加图书成功,列出所有图书 -->
  15. <result type="chain">listBooks</result>
  16. <!-- 添加图书失败,跳转到添加图书的表单页 -->
  17. <result name="error">/WEB-INF/content/bookForm.jsp</result>
  18. </action>
  19. <action name="listBooks" class="org.crazyit.booksys.action.BookAction"
  20. method="list">
  21. <result>/WEB-INF/content/listBooks.jsp</result>
  22. </action>
  23. <action name="deleteBook" class="org.crazyit.booksys.action.BookAction"
  24. method="delete">
  25. <result type="chain">listBooks</result>
  26. </action>
  27. <!-- 让用户直接访问该应用时列出所有视图页面 -->
  28. <action name="*">
  29. <result>/WEB-INF/content/{1}.jsp</result>
  30. </action>
  31. </package>
  32. </struts>


6. Dao层设计


项目时分层设计结构,分为控制层、业务层、持久层(Dao)层、PO层(持久化对象),如下图:


在进行Dao层设计的时候,我们按照接口编程的原则,如下图所示:
dao层作为持久层,需要与数据库打交道,而所有的数据库操作基本都涉及增、删、改、查等相同的基本操作,而这些通用的操作主要包括:
  1. 根据ID加载实体;
  2. 保存实体;
  3. 更新实体;
  4. 删除实体;
  5. 根据ID删除实体;
  6. 获取所有实体;
  7. 获取实体总数;
  8. 等等等;
我们可以编写一个dao层基类来实现这些基本操作,然后让其他的dao层类来继承这个基类,这样就可以减少重复的工作量。
dao层基类的编写也采用按照接口编程的原则,这样我们就可以得到继承关系图,如下所示:



dao层基类接口:BaseDao.java

  1. package org.crazyit.common.dao;
  2. import java.util.List;
  3. import java.io.Serializable;
  4. public interface BaseDao<T>
  5. {
  6. // 根据ID加载实体
  7. T get(Class<T> entityClazz , Serializable id);
  8. // 保存实体
  9. Serializable save(T entity);
  10. // 更新实体
  11. void update(T entity);
  12. // 删除实体
  13. void delete(T entity);
  14. // 根据ID删除实体
  15. void delete(Class<T> entityClazz , Serializable id);
  16. // 获取所有实体
  17. List<T> findAll(Class<T> entityClazz);
  18. // 获取实体总数
  19. long findCount(Class<T> entityClazz);
  20. }

dao层基类实现类:BaseDaoHibernate4.java
说明:程序中有两个实现类,分别对应Hibernate3和Hibernate4的,我们推荐使用Hibernate4的实现类。
Hibernate配置时,需要配置sessionFactory,这个sessionFactory实际上就是对应数据库,我们可以通过sessionFactory获取对应的session(相当于数据库连接),然后通过session对数据库进行访问,因此,如果我们想对数据库进行操作,就需要获取sessionFactory,而这个sessionFactory的获取我们采用spring的依赖注入方式,只需要在实现类中配置这个sessionFactory属性即可。
 * 1. Spring推荐使用sessionFactory的getCurrentSession()来获取Session,
 * 然后通过Session进行持久化操作。 ==> BaseDaoHibernate4.java
 * 
 * 2. Spring并不推荐使用HibernateTemplate、HibernateDaoSupport来实现Dao组件,
 * Spring4为了和以前编码风格兼容,才提供了HibernateTemplate、HibernateDaoSupport;

* ==>==> BaseDaoHibernate3.java  


  1. package org.crazyit.common.dao.impl;
  2. import org.hibernate.*;
  3. import java.util.List;
  4. import java.io.Serializable;
  5. import org.crazyit.common.dao.*;
  6. /***********************************
  7. * 1. Spring推荐使用sessionFactory的getCurrentSession()来获取Session,
  8. * 然后通过Session进行持久化操作。 ==> BaseDaoHibernate4.java
  9. *
  10. * 2. Spring并不推荐使用HibernateTemplate、HibernateDaoSupport来实现Dao组件,
  11. * Spring4为了和以前编码风格兼容,才提供了HibernateTemplate、HibernateDaoSupport;
  12. * ==>==> BaseDaoHibernate3.java
  13. *
  14. ***********************************/
  15. public class BaseDaoHibernate4<T> implements BaseDao<T>
  16. {
  17. // DAO组件进行持久化操作底层依赖的SessionFactory组件
  18. private SessionFactory sessionFactory;
  19. // 依赖注入SessionFactory所需的setter方法
  20. public void setSessionFactory(SessionFactory sessionFactory)
  21. {
  22. this.sessionFactory = sessionFactory;
  23. }
  24. public SessionFactory getSessionFactory()
  25. {
  26. return this.sessionFactory;
  27. }
  28. // 根据ID加载实体
  29. @SuppressWarnings("unchecked")
  30. public T get(Class<T> entityClazz , Serializable id)
  31. {
  32. return (T)getSessionFactory().getCurrentSession()
  33. .get(entityClazz , id);
  34. }
  35. // 保存实体
  36. public Serializable save(T entity)
  37. {
  38. return getSessionFactory().getCurrentSession()
  39. .save(entity);
  40. }
  41. // 更新实体
  42. public void update(T entity)
  43. {
  44. getSessionFactory().getCurrentSession().saveOrUpdate(entity);
  45. }
  46. // 删除实体
  47. public void delete(T entity)
  48. {
  49. getSessionFactory().getCurrentSession().delete(entity);
  50. }
  51. // 根据ID删除实体
  52. public void delete(Class<T> entityClazz , Serializable id)
  53. {
  54. getSessionFactory().getCurrentSession()
  55. .createQuery("delete " + entityClazz.getSimpleName()
  56. + " en where en.id = ?0")
  57. .setParameter("0" , id)
  58. .executeUpdate();
  59. }
  60. // 获取所有实体
  61. public List<T> findAll(Class<T> entityClazz)
  62. {
  63. return find("select en from "
  64. + entityClazz.getSimpleName() + " en");
  65. }
  66. // 获取实体总数
  67. public long findCount(Class<T> entityClazz)
  68. {
  69. List<?> l = find("select count(*) from "
  70. + entityClazz.getSimpleName());
  71. // 返回查询得到的实体总数
  72. if (l != null && l.size() == 1 )
  73. {
  74. return (Long)l.get(0);
  75. }
  76. return 0;
  77. }
  78. // 根据HQL语句查询实体
  79. @SuppressWarnings("unchecked")
  80. protected List<T> find(String hql)
  81. {
  82. return (List<T>)getSessionFactory().getCurrentSession()
  83. .createQuery(hql)
  84. .list();
  85. }
  86. // 根据带占位符参数HQL语句查询实体
  87. @SuppressWarnings("unchecked")
  88. protected List<T> find(String hql , Object... params)
  89. {
  90. // 创建查询
  91. Query query = getSessionFactory().getCurrentSession()
  92. .createQuery(hql);
  93. // 为包含占位符的HQL语句设置参数
  94. for(int i = 0 , len = params.length ; i < len ; i++)
  95. {
  96. query.setParameter(i + "" , params[i]);
  97. }
  98. return (List<T>)query.list();
  99. }
  100. /**
  101. * 使用hql 语句进行分页查询操作
  102. * @param hql 需要查询的hql语句
  103. * @param pageNo 查询第pageNo页的记录
  104. * @param pageSize 每页需要显示的记录数
  105. * @return 当前页的所有记录
  106. */
  107. @SuppressWarnings("unchecked")
  108. protected List<T> findByPage(String hql,
  109. int pageNo, int pageSize)
  110. {
  111. // 创建查询
  112. return getSessionFactory().getCurrentSession()
  113. .createQuery(hql)
  114. // 执行分页
  115. .setFirstResult((pageNo - 1) * pageSize)
  116. .setMaxResults(pageSize)
  117. .list();
  118. }
  119. /**
  120. * 使用hql 语句进行分页查询操作
  121. * @param hql 需要查询的hql语句
  122. * @param params 如果hql带占位符参数,params用于传入占位符参数
  123. * @param pageNo 查询第pageNo页的记录
  124. * @param pageSize 每页需要显示的记录数
  125. * @return 当前页的所有记录
  126. */
  127. @SuppressWarnings("unchecked")
  128. protected List<T> findByPage(String hql , int pageNo, int pageSize
  129. , Object... params)
  130. {
  131. // 创建查询
  132. Query query = getSessionFactory().getCurrentSession()
  133. .createQuery(hql);
  134. // 为包含占位符的HQL语句设置参数
  135. for(int i = 0 , len = params.length ; i < len ; i++)
  136. {
  137. query.setParameter(i + "" , params[i]);
  138. }
  139. // 执行分页,并返回查询结果
  140. return query.setFirstResult((pageNo - 1) * pageSize)
  141. .setMaxResults(pageSize)
  142. .list();
  143. }
  144. }


上面介绍的是Hibernate4推荐使用的方式,当然,我们也可以使用HibernateTemplete和HibernateDaoSupport来实现这个基类,这种方式主要是Hibernate3使用的方式,现在不推荐。
HibernateTemplete是spring提供的模板,这里面封装好了基本的数据库操作方法。
HibernateDaoSupport提供了两个方法:
  1. getHibernateTemplate():获取HibernateTemplate,通过HibernateTemplate来实现数据库操作;
  2. setSessionFactory():使用spring的依赖注入;
BaseDaoHibernate3.java


  1. package org.crazyit.common.dao.impl;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import org.crazyit.common.dao.BaseDao;
  5. import org.hibernate.*;
  6. import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
  7. import org.springframework.orm.hibernate4.HibernateCallback;
  8. /***********************************
  9. * 1. Spring推荐使用sessionFactory的getCurrentSession()来获取Session,
  10. * 然后通过Session进行持久化操作。 ==> BaseDaoHibernate4.java
  11. *
  12. * 2. Spring并不推荐使用HibernateTemplate、HibernateDaoSupport来实现Dao组件,
  13. * Spring4为了和以前编码风格兼容,才提供了HibernateTemplate、HibernateDaoSupport;
  14. * ==>==> BaseDaoHibernate3.java
  15. *
  16. ***********************************/
  17. public class BaseDaoHibernate3<T> extends HibernateDaoSupport
  18. implements BaseDao<T>
  19. {
  20. // 根据ID加载实体
  21. public T get(Class<T> entityClazz, Serializable id)
  22. {
  23. return getHibernateTemplate().get(entityClazz, id);
  24. }
  25. // 保存实体
  26. public Serializable save(T entity)
  27. {
  28. return getHibernateTemplate().save(entity);
  29. }
  30. // 更新实体
  31. public void update(T entity)
  32. {
  33. getHibernateTemplate().saveOrUpdate(entity);
  34. }
  35. // 删除实体
  36. public void delete(T entity)
  37. {
  38. getHibernateTemplate().delete(entity);
  39. }
  40. // 根据ID删除实体
  41. public void delete(Class<T> entityClazz, Serializable id)
  42. {
  43. delete(get(entityClazz , id));
  44. }
  45. @Override
  46. @SuppressWarnings("unchecked")
  47. public List<T> findAll(Class<T> entityClazz)
  48. {
  49. return (List<T>)getHibernateTemplate().find("select en from "
  50. + entityClazz.getSimpleName() + " en");
  51. }
  52. @Override
  53. @SuppressWarnings("unchecked")
  54. public long findCount(Class<T> entityClazz)
  55. {
  56. List<Long> list = (List<Long>)getHibernateTemplate().find(
  57. "select count(*) from " + entityClazz.getSimpleName() + " en");
  58. return list.get(0);
  59. }
  60. /**
  61. * 使用hql 语句进行分页查询操作
  62. * @param hql 需要查询的hql语句
  63. * @param pageNo 查询第pageNo页的记录
  64. * @param pageSize 每页需要显示的记录数
  65. * @return 当前页的所有记录
  66. */
  67. @SuppressWarnings("unchecked")
  68. protected List<T> findByPage(final String hql,
  69. final int pageNo, final int pageSize)
  70. {
  71. // 通过一个HibernateCallback对象来执行查询
  72. List<T> list = getHibernateTemplate()
  73. .execute(new HibernateCallback<List<T>>(){
  74. // 实现HibernateCallback接口必须实现的方法
  75. public List<T> doInHibernate(Session session)
  76. {
  77. // 执行Hibernate分页查询
  78. List<T> result = session.createQuery(hql)
  79. .setFirstResult((pageNo - 1) * pageSize)
  80. .setMaxResults(pageSize)
  81. .list();
  82. return result;
  83. }
  84. });
  85. return list;
  86. }
  87. /**
  88. * 使用hql 语句进行分页查询操作
  89. * @param hql 需要查询的hql语句
  90. * @param pageNo 查询第pageNo页的记录
  91. * @param pageSize 每页需要显示的记录数
  92. * @param params 如果hql带占位符参数,params用于传入占位符参数
  93. * @return 当前页的所有记录
  94. */
  95. @SuppressWarnings("unchecked")
  96. protected List<T> findByPage(final String hql , final int pageNo,
  97. final int pageSize , final Object... params)
  98. {
  99. // 通过一个HibernateCallback对象来执行查询
  100. List<T> list = getHibernateTemplate()
  101. .execute(new HibernateCallback<List<T>>()
  102. {
  103. // 实现HibernateCallback接口必须实现的方法
  104. public List<T> doInHibernate(Session session)
  105. {
  106. // 执行Hibernate分页查询
  107. Query query = session.createQuery(hql);
  108. // 为包含占位符的HQL语句设置参数
  109. for(int i = 0 , len = params.length ; i < len ; i++)
  110. {
  111. query.setParameter(i + "" , params[i]);
  112. }
  113. List<T> result = query.setFirstResult((pageNo - 1) * pageSize)
  114. .setMaxResults(pageSize)
  115. .list();
  116. return result;
  117. }
  118. });
  119. return list;
  120. }
  121. }


6.2 dao层具体类的实现


这是BookDao的接口和实现类;

我们需要让BookDao继承BaseDao,让BookDaoHibernate4类继承BaseDaoHibernate4;如下图所示:

接口:BookDao.java

  1. package org.crazyit.booksys.dao;
  2. import org.crazyit.booksys.domain.Book;
  3. import org.crazyit.common.dao.BaseDao;
  4. public interface BookDao extends BaseDao<Book>
  5. {
  6. }

  1. package org.crazyit.booksys.dao.impl;
  2. import org.crazyit.booksys.dao.BookDao;
  3. import org.crazyit.booksys.domain.Book;
  4. import org.crazyit.common.dao.impl.BaseDaoHibernate4;
  5. /**
  6. * Spring推荐使用继承前面的BaseDaoHibernate4,也可以继承前面的BaseDaoHibernate3
  7. */
  8. public class BookDaoHibernate4 extends BaseDaoHibernate4<Book>
  9. implements BookDao{
  10. }

对应的spring配置==>依赖注入:sessionFactory;

BookDaoHibernate4继承了BaseDaoHibernate4,而BaseDaoHibernate4有SessionFactory属性;

7. 持久层类的编写


Book.java:为持久层类,与数据表相对应;
  1. package org.crazyit.booksys.domain;
  2. import javax.persistence.*;
  3. @Entity
  4. @Table(name="book_inf")
  5. public class Book
  6. {
  7. @Id @Column(name="book_id")
  8. @GeneratedValue(strategy=GenerationType.IDENTITY)
  9. private Integer id;
  10. @Column(name="book_name")
  11. private String name;
  12. private double price;
  13. private String author;
  14. public Integer getId()
  15. {
  16. return id;
  17. }
  18. public void setId(Integer id)
  19. {
  20. this.id = id;
  21. }
  22. public String getName()
  23. {
  24. return name;
  25. }
  26. public void setName(String name)
  27. {
  28. this.name = name;
  29. }
  30. public double getPrice()
  31. {
  32. return price;
  33. }
  34. public void setPrice(double price)
  35. {
  36. this.price = price;
  37. }
  38. public String getAuthor()
  39. {
  40. return author;
  41. }
  42. public void setAuthor(String author)
  43. {
  44. this.author = author;
  45. }
  46. }

因为我们在spring的配置文件中配置了:
而Book类又添加了注解:

所以,spring容器会自动将book类看作是持久化类;
与此同时,我们还在spring配置文件中配置了:hibernate.hbm2ddl.auto=update

所以当我们第一次运行程序,执行数据库操作时,会在数据库中自动生成数据表:

8. 控制层和业务层


控制层:BookAction.java
  1. package org.crazyit.booksys.action;
  2. import java.util.List;
  3. import org.crazyit.booksys.domain.Book;
  4. import org.crazyit.booksys.service.BookService;
  5. import com.opensymphony.xwork2.ActionSupport;
  6. public class BookAction extends ActionSupport
  7. {
  8. private BookService bookService; //业务层组件
  9. private Book book;
  10. private List<Book> books;
  11. private int id;
  12. // 处理添加图书的add()方法
  13. public String add()
  14. {
  15. if(book == null){
  16. book = new Book();
  17. book.setAuthor("zhangsan");
  18. book.setName("zhangsan");
  19. book.setPrice(123);
  20. }
  21. // 调用业务逻辑组件的addBook()方法来处理用户请求
  22. int result = bookService.addBook(book);
  23. if(result > 0)
  24. {
  25. addActionMessage("恭喜您,图书添加成功!");
  26. return SUCCESS;
  27. }
  28. addActionError("图书添加失败,请重新输入!");
  29. return ERROR;
  30. }
  31. public String list()
  32. {
  33. setBooks(bookService.getAllBooks());
  34. return SUCCESS;
  35. }
  36. public String delete()
  37. {
  38. bookService.deleteBook(id);
  39. return SUCCESS;
  40. }
  41. public void setBookService(BookService bookService)
  42. {
  43. this.bookService = bookService;
  44. }
  45. public Book getBook()
  46. {
  47. return book;
  48. }
  49. public void setBook(Book book)
  50. {
  51. this.book = book;
  52. }
  53. public List<Book> getBooks()
  54. {
  55. return books;
  56. }
  57. public void setBooks(List<Book> books)
  58. {
  59. this.books = books;
  60. }
  61. public int getId()
  62. {
  63. return id;
  64. }
  65. public void setId(int id)
  66. {
  67. this.id = id;
  68. }
  69. }

bookService 采用依赖注入的方式:
 

业务层:

  1. package org.crazyit.booksys.service;
  2. import java.util.List;
  3. import org.crazyit.booksys.domain.Book;
  4. public interface BookService
  5. {
  6. // 添加图书
  7. int addBook(Book book);
  8. List<Book> getAllBooks();
  9. void deleteBook(int id);
  10. }

实现类:BookServiceImpl.java

  1. package org.crazyit.booksys.service.impl;
  2. import java.util.List;
  3. import org.crazyit.booksys.dao.BookDao;
  4. import org.crazyit.booksys.domain.Book;
  5. import org.crazyit.booksys.service.BookService;
  6. public class BookServiceImpl implements BookService
  7. {
  8. private BookDao bookDao;
  9. public void setBookDao(BookDao bookDao)
  10. {
  11. this.bookDao = bookDao;
  12. }
  13. @Override
  14. public int addBook(Book book)
  15. {
  16. return (Integer) bookDao.save(book);
  17. }
  18. @Override
  19. public List<Book> getAllBooks()
  20. {
  21. return bookDao.findAll(Book.class);
  22. }
  23. @Override
  24. public void deleteBook(int id)
  25. {
  26. bookDao.delete(Book.class, id);
  27. }
  28. }



9. 前台界面



bookForm.jsp

  1. <%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
  2. <%@taglib prefix="s" uri="/struts-tags"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  4. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  5. <html xmlns="http://www.w3.org/1999/xhtml">
  6. <head>
  7. <title>添加图书</title>
  8. </head>
  9. <body>
  10. <h3>添加图书</h3>
  11. <s:form action="addBook">
  12. <s:textfield name="book.name" label="书名"/>
  13. <s:textfield name="book.price" label="价格"/>
  14. <s:textfield name="book.author" label="作者"/>
  15. <tr align="center">
  16. <td colspan="2">
  17. <s:submit value="添加" theme="simple"/>
  18. <s:reset value="重设" theme="simple"/>
  19. </td>
  20. </tr>
  21. </s:form>
  22. </body>
  23. </html>

listBooks.jsp

  1. <%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
  2. <%@taglib prefix="s" uri="/struts-tags"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  4. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  5. <html xmlns="http://www.w3.org/1999/xhtml">
  6. <head>
  7. <title>全部图书</title>
  8. </head>
  9. <body>
  10. <h3>全部图书</h3>
  11. <table width="640" border="1">
  12. <s:iterator value="books" var="b">
  13. <tr>
  14. <td><s:property value="name"/></td>
  15. <td><s:property value="price"/></td>
  16. <td><s:property value="author"/></td>
  17. <td><a href="${pageContext.request.contextPath}/deleteBook?id=${b.id}">删除</a></td>
  18. </tr>
  19. </s:iterator>
  20. </table>
  21. </body>
  22. </html>


10.运行






附件

数据库文件

  1. /*
  2. Navicat MySQL Data Transfer
  3. Source Server : default
  4. Source Server Version : 50626
  5. Source Host : localhost:3306
  6. Source Database : sampledb
  7. Target Server Type : MYSQL
  8. Target Server Version : 50626
  9. File Encoding : 65001
  10. Date: 2015-09-08 10:36:58
  11. */
  12. SET FOREIGN_KEY_CHECKS=0;
  13. -- ----------------------------
  14. -- Table structure for book_inf
  15. -- ----------------------------
  16. DROP TABLE IF EXISTS `book_inf`;
  17. CREATE TABLE `book_inf` (
  18. `book_id` int(11) NOT NULL AUTO_INCREMENT,
  19. `author` varchar(255) DEFAULT NULL,
  20. `book_name` varchar(255) DEFAULT NULL,
  21. `price` double NOT NULL,
  22. PRIMARY KEY (`book_id`)
  23. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  24. -- ----------------------------
  25. -- Records of book_inf
  26. -- ----------------------------
  27. -- ----------------------------
  28. -- Table structure for t_login_log
  29. -- ----------------------------
  30. DROP TABLE IF EXISTS `t_login_log`;
  31. CREATE TABLE `t_login_log` (
  32. `login_log_id` int(11) NOT NULL AUTO_INCREMENT,
  33. `user_id` int(11) DEFAULT NULL,
  34. `ip` varchar(23) DEFAULT NULL,
  35. `login_datetime` datetime DEFAULT NULL,
  36. PRIMARY KEY (`login_log_id`)
  37. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  38. -- ----------------------------
  39. -- Records of t_login_log
  40. -- ----------------------------
  41. -- ----------------------------
  42. -- Table structure for t_user
  43. -- ----------------------------
  44. DROP TABLE IF EXISTS `t_user`;
  45. CREATE TABLE `t_user` (
  46. `user_id` int(11) NOT NULL AUTO_INCREMENT,
  47. `user_name` varchar(30) DEFAULT NULL COMMENT '用户名',
  48. `credits` int(11) DEFAULT NULL,
  49. `password` varchar(32) DEFAULT NULL,
  50. `last_visit` datetime DEFAULT NULL,
  51. `last_ip` varchar(23) DEFAULT NULL,
  52. PRIMARY KEY (`user_id`)
  53. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
  54. -- ----------------------------
  55. -- Records of t_user
  56. -- ----------------------------
  57. INSERT INTO `t_user` VALUES ('1', 'admin', null, '123456', null, null);
  58. INSERT INTO `t_user` VALUES ('2', 'zpp', null, '888888', null, null);


附件列表

【Spring实战-3】Spring整合Hibernate、Struts的更多相关文章

  1. 【Spring实战】Spring注解配置工作原理源码解析

    一.背景知识 在[Spring实战]Spring容器初始化完成后执行初始化数据方法一文中说要分析其实现原理,于是就从源码中寻找答案,看源码容易跑偏,因此应当有个主线,或者带着问题.目标去看,这样才能最 ...

  2. 【Spring实战】Spring容器初始化完成后执行初始化数据方法

    一.背景知识及需求 在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听.Servlet加载初始化等切入点为数据库准备数据,这些初始化数据是系统开始运行前必须的数据,例如权限组.系统选项.默认 ...

  3. 【转】【Spring实战】Spring注解配置工作原理源码解析

    一.背景知识 在[Spring实战]Spring容器初始化完成后执行初始化数据方法一文中说要分析其实现原理,于是就从源码中寻找答案,看源码容易跑偏,因此应当有个主线,或者带着问题.目标去看,这样才能最 ...

  4. (一)《Spring实战》——Spring核心

    <Spring实战>(第4版) 第一章:Spring之旅 1. 简化Java开发 为了降低Java开发的复杂性,Spring采取了以下4种关键策略: 基于POJO的轻量级和最小侵入性编程: ...

  5. Spring 学习笔记之整合Hibernate

    Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心SQ ...

  6. Spring学习笔记之整合hibernate

    1.web.xml里边要配置好对应的springxml的路径 <context-param> <param-name>contextConfigLocation</par ...

  7. (二)《Spring实战》——Spring核心

    第二章:装配Bean 在Spring中,对象无需自己查找或创建与其所关联的其他对象.相反,容器负责把需要相互协作的对象引用赋予各个对象.例如,一个订单管理组件需要信用卡认证组件,但它不需要自己创建信用 ...

  8. 【Spring实战】----开篇(包含系列目录链接)

    [Spring实战]----开篇(包含系列目录链接) 置顶2016年11月10日 11:12:56 阅读数:3617 终于还是要对Spring进行解剖,接下来Spring实战篇系列会以应用了Sprin ...

  9. spring MVC(十)---spring MVC整合mybatis

    spring mvc可以通过整合hibernate来实现与数据库的数据交互,也可以通过mybatis来实现,这篇文章是总结一下怎么在springmvc中整合mybatis. 首先mybatis需要用到 ...

随机推荐

  1. SQL Server 调优系列基础篇 - 并行运算总结(一)

    前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...

  2. 如何在ubuntu16上安装docker

    自从用了docker,就一直无法忘怀,省去了很多部署成本.特别是可以统一开发环境和部署环境,在实际开发中有很大的实用价值. 作为一个伪全栈,我是力推大家学习docker技术的.这种共享linux内核的 ...

  3. Java通过继承外部类来建立该外部类的protected内部类的实例(转)

    原文链接:http://blog.sina.com.cn/s/blog_7de00ff60102xffx.html 如果想要在外部类的导出类(子类)中建立该外部类的为protected权限的内部类的实 ...

  4. Python装饰器的通俗理解

    转载:http://blog.csdn.net/u013471155 在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略 ...

  5. 【error】scripts/basic/fixdep: Syntax error: "(" unexpected

    前言 第一次安装PCIE驱动的时候容易出现各种问题,总结一下下.. 原因分析 一般情况下,直接make的时候会出现问题. scripts/basic/fixdep: : scripts/basic/f ...

  6. [LeetCode&Python] Problem 917. Reverse Only Letters

    Given a string S, return the "reversed" string where all characters that are not a letter  ...

  7. this的区别

    数据中心:this与_this的区别 getSelectData:function(){ var _this=this; _this.queryAjax(URL.selectData,'','post ...

  8. 用zcat查看压缩日志中百度抓取的量

    比如查看124.251.44.85这一台服务器的07-13,07-14,07-15的日志中百度抓取http://www.baidu.com/search/spider.html 的量 wc命令参考博客 ...

  9. javabean(实体类)转Map类型

    javabean(实体类)转Map类型 从网上"風亦飞"的导出EXCEL的源代码提取出来的.认为非常好用.分享一下给大家,主要看beanToMap方法就OK了 /*以下是从poi导 ...

  10. 利用Xamaria构建Android应用-公交发车信息屏

    原文:利用Xamaria构建Android应用-公交发车信息屏 1.背景 在公交整个运营系统中,信息展示占据了很大一部分的内容.各种除了户外的各种LED拼接屏,还有用于室内信息提示用的LCD屏幕.对于 ...