Spring + JDBC + Struts联合开发(实现单表的CRUD)

这里使用Spring + JDBC +Struts,完成新闻表的添加,修改,删除和查询功能。

建立数据库:

[sql] view plain copy
  1. CREATE TABLE news_type (  
  2.        tid                      number(8)           primary key ,  
  3.        tname                    varchar2(50)        not null                      
  4. );  
  5.   
  6. INSERT INTO news_type VALUES (1,'财经');  
  7. INSERT INTO news_type VALUES (2,'娱乐');  
  8. INSERT INTO news_type VALUES (3,'影视');  
  9. INSERT INTO news_type VALUES (4,'军事');  
  10. INSERT INTO news_type VALUES (5,'生活');  
  11.   
  12. CREATE TABLE news (  
  13.        id                       number(8)           primary key ,  
  14.        title                    varchar2(50)        not null,  
  15.        content                  varchar2(500)       not null,  
  16.        pub_date                 date                not null,  
  17.        type_id                  number(8)           not null,  
  18.        foreign key (type_id) references news_type (tid) on delete cascade   
  19. );  
  20. commit;  

一、加入Spring支持库

Spring + JDBC + Struts联合开发(实现单表的CRUD)_第1张图片

加入Struts支持库:


加入Struts2支持时,一定也要多选择一个SpringLibraries支持库。

还要删除掉Struts2中擅自加入的Spring2.5支持包,这是Struts2自动添加的,Remove掉就可以。

Spring + JDBC + Struts联合开发(实现单表的CRUD)_第2张图片

拷贝数据库驱动(不要忘记)。

开始进行后台开发,先完成数据库连接处理。

这里通过配置文件完成。

[java] view plain copy
  1. <span style="white-space:pre">  </span><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  
  2.         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>  
  3.         <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>  
  4.         <property name="username" value="SUNXUN"></property>  
  5.         <property name="password" value="123"></property>  
  6.     </bean>     

二、编写vo类

[java] view plain copy
  1. public class News {  
  2.     private Integer id;   
  3.     private String title;   
  4.     private String content;   
  5.     private Integer typeId;   
  6.     private Date pubDate;  
这里是JDBC,因此不要考虑关系的问题。

三、编写DAO的接口并实现

[java] view plain copy
  1. public interface IDAO<K, V> {  
  2.   
  3.     public void doCreate(V vo) throws Exception;  
  4.     public void doUpdate(V vo) throws Exception;  
  5.     public void doRemove(K id) throws Exception;  
  6.     public List<V> findAll() throws Exception;  
  7.     public V findById(K id) throws Exception;  
  8.   
  9.     public List<V> findAll(int pageNo, int pageSize, String keyword,  
  10.             String column) throws Exception;  
  11.   
  12.     public int getAllCount(String keyword, String column) throws Exception;  
  13. }  
[java] view plain copy
  1. public interface INewsDAO extends IDAO<Integer, News> {  
  2. }  

实现类:

这个实现类必须继承JdbcDaoSupport类

[java] view plain copy
  1. // 实现类需要多实现一个RowMapper接口,该接口表示怎样将ResultSet转换为News对象的规则,需要覆写一个mapRow方法.  
  2. public class NewsDAOImpl extends JdbcDaoSupport implements INewsDAO,  
  3.         RowMapper<News> {  
  4.   
  5.     public void doCreate(News vo) throws Exception {  
  6.         <span style="color:#cc0000;background-color: rgb(51, 204, 0);">// 这里不要使用Connection类来操作,因为Spring封装了数据库处理,如果使用Connection,就必须自己手工关闭连接,Spring就不管了.  
  7.         // 这里需要使用的是JdbcTemplate来完成操作.</span>  
  8.         String sql = "INSERT INTO news (id,title,content,pub_date,type_id) VALUES (news_seq.nextVal,?,?,?,?)";  
  9.         super.getJdbcTemplate().update(sql, vo.getTitle(), vo.getContent(),  
  10.                 new java.sql.Date(vo.getPubDate().getTime()), vo.getTypeId());  
  11.     }  
  12.   
  13.     public void doRemove(Integer id) throws Exception {  
  14.         String sql = "DELETE FROM news WHERE id = ?";  
  15.         super.getJdbcTemplate().update(sql, id);  
  16.     }  
  17.   
  18.     public void doUpdate(News vo) throws Exception {  
  19.         String sql = "UPDATE news SET title=?,content=?,pub_date=?,type_id=? WHERE id = ?";  
  20.         super.getJdbcTemplate().update(sql, vo.getTitle(), vo.getContent(),  
  21.                 new java.sql.Date(vo.getPubDate().getTime()), vo.getTypeId(),  
  22.                 vo.getId());  
  23.     }  
  24.   
  25.     public List<News> findAll() throws Exception {  
  26.         String sql = "SELECT id,title,content,pub_date,type_id FROM news";  
  27.         // 通过写好的规则,自动转换查询结果,并自动加入到集合中返回  
  28.         List<News> all = super.getJdbcTemplate().query(sql, this);  
  29.         return all;  
  30.     }  
  31.   
  32.     public List<News> findAll(int pageNo, int pageSize, String keyword,  
  33.             String column) throws Exception {  
  34.         String sql = "SELECT * FROM (SELECT id,title,content,pub_date,type_id,ROWNUM rn FROM News WHERE "  
  35.                 + column + " LIKE ? AND ROWNUM <= ?) temp WHERE temp.rn > ?";  
  36.         List<News> all = super.getJdbcTemplate()  
  37.                 .query(sql, this"%" + keyword + "%", pageNo * pageSize,  
  38.                         (pageNo - 1) * pageSize);  
  39.         return all;  
  40.     }  
  41.   
  42.     public News findById(Integer id) throws Exception {  
  43.         String sql = "SELECT id,title,content,pub_date,typeId FROM news WHERE id = ?";  
  44.         News news = super.getJdbcTemplate().queryForObject(sql, this, id);  
  45.         return news;  
  46.     }  
  47.   
  48.     public int getAllCount(String keyword, String column) throws Exception {  
  49.         String sql = "SELECT COUNT(*) FROM news WHERE " + column + " LIKE ?";  
  50.         int count = super.getJdbcTemplate().queryForInt(sql,  
  51.                 "%" + keyword + "%");  
  52.         return count;  
  53.     }  
  54. <span style="white-space:pre">  </span>//这里是为查询缩减步骤。  
  55.     public News mapRow(ResultSet rs, int arg1) throws SQLException {  
  56.         // 建立News对象  
  57.         News news = new News();  
  58.         news.setId(rs.getInt(1));  
  59.         news.setTitle(rs.getString(2));  
  60.         news.setContent(rs.getString(3));  
  61.         news.setPubDate(rs.getDate(4));  
  62.         news.setTypeId(rs.getInt(5));  
  63.         return news;  
  64.     }  
  65. }  

配置这个类

[java] view plain copy
  1. <span style="white-space:pre">  </span><!--   
  2.         还要单独配置一个jdbcTemplate这个<bean>,为了注入到DAOImpl中.  
  3.     -->  
  4.     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  5.         <property name="dataSource">  
  6.             <ref bean="dataSource"/>  
  7.         </property>  
  8.     </bean>   
  9.     <bean id="newsDAOImpl" class="org.liky.dao.impl.NewsDAOImpl">  
  10.         <property name="jdbcTemplate">  
  11.             <ref bean="jdbcTemplate"/>  
  12.         </property>  
  13.     </bean>  

四、编写Service接口和实现类

[java] view plain copy
  1. public interface INewsService {  
  2.   
  3.     public void insert(News news) throws Exception;  
  4.   
  5.     public void delete(int id) throws Exception;  
  6.   
  7.     public News findById(int id) throws Exception;  
  8.   
  9.     public Map<String, Object> list(int pageNo, int pageSize, String column,  
  10.             String keyword) throws Exception;  
  11.   
  12. }  
[java] view plain copy
  1. public class NewsServiceImpl implements INewsService {  
  2.   
  3.     private INewsDAO newsdao;  
  4.   
  5.     public void delete(int id) throws Exception {  
  6.         newsdao.doRemove(id);  
  7.     }  
  8.   
  9.     public News findById(int id) throws Exception {  
  10.         return newsdao.findById(id);  
  11.     }  
  12.   
  13.     public void insert(News news) throws Exception {  
  14.         newsdao.doCreate(news);  
  15.     }  
  16.   
  17.     public Map<String, Object> list(int pageNo, int pageSize, String column,  
  18.             String keyword) throws Exception {  
  19.         Map<String, Object> map = new HashMap<String, Object>();  
  20.         map.put("allNews", newsdao.findAll(pageNo, pageSize, keyword, column));  
  21.         map.put("allCount", newsdao.getAllCount(keyword, column));  
  22.         return map;  
  23.     }  
  24.   
  25.     public void setNewsdao(INewsDAO newsdao) {  
  26.         this.newsdao = newsdao;  
  27.     }  
  28. }  

配置这个Service

[java] view plain copy
  1. <span style="white-space:pre">  </span><bean id="newsServiceImpl" class="org.liky.service.impl.NewsServiceImpl">  
  2.         <property name="newsdao">  
  3.             <ref bean="newsDAOImpl"/>  
  4.         </property>  
  5.     </bean>  

五、配置Spring的AOP部分,设置拦截器。

这里的拦截器由Spring提供,直接使用即可。

[java] view plain copy
  1. <span style="white-space:pre">  </span><!--   
  2.         声明一个用来规范格式的<bean>  
  3.     -->  
  4.     <bean id="transactionManager"  
  5.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  6.         <property name="dataSource">  
  7.             <ref bean="dataSource" />  
  8.         </property>  
  9.     </bean>  
  10.   
  11.     <bean id="transactionInterceptor"  
  12.         class="org.springframework.transaction.interceptor.TransactionInterceptor">  
  13.         <property name="transactionManager">  
  14.             <ref bean="transactionManager" />  
  15.         </property>  
  16.         <!--   
  17.             配置事务处理的方法和方式  
  18.         -->  
  19.         <property name="transactionAttributes">  
  20.             <props>  
  21.                 <!--  
  22.                     表示所有方法都要关闭连接,并进行事务处理.  
  23.                     PROPAGATION_REQUIRED:如果之前有事务,则将当前操作合并到之前的事务中,如果之前没有事务,则开始一个新的事务。  
  24.                     PROPAGATION_REQUIRED_NEW:无论之前是否有事务,都开始一个新的事务。  
  25.                     PROPAGATION_REQUIRED_NEVER:不使用事务处理,使用自动提交方式。  
  26.                 -->  
  27.                 <prop key="*">PROPAGATION_REQUIRED</prop>  
  28.             </props>  
  29.         </property>  
  30.     </bean>  
  31.   
  32.     <bean  
  33.         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
  34.         <property name="beanNames">  
  35.             <list>  
  36.                 <value>*ServiceImpl</value>  
  37.             </list>  
  38.         </property>  
  39.         <property name="interceptorNames">  
  40.             <list>  
  41.                 <value>transactionInterceptor</value>  
  42.             </list>  
  43.         </property>  
  44.     </bean>  

六、实现测试功能,也使用JUnit进行测试。

[java] view plain copy
  1. public class NewsServiceImplTest {  
  2.     private INewsService service;  
  3.   
  4.     // 在执行测试方法前,先执行这个方法.若不加@Before,那么在每个方法前都需要添加init()。  
  5.     @Before  
  6.     public void init() {  
  7.         ApplicationContext ctx = new ClassPathXmlApplicationContext(  
  8.                 "applicationContext.xml");  
  9.         service = (INewsService) ctx.getBean("newsServiceImpl");  
  10.     }  
  11.   
  12.     @Test  
  13.     public void testDelete() throws Exception {  
  14.         service.delete(1);  
  15.     }  
  16.   
  17.     @Test  
  18.     public void testFindById() throws Exception {  
  19.         System.out.println(service.findById(3).getTitle());  
  20.     }  
  21.   
  22.     @Test  
  23.     public void testInsert() throws Exception {  
  24.         News news = new News();  
  25.         news.setTitle("测试添加");  
  26.         news.setContent("Spring JDBC 添加测试");  
  27.         news.setPubDate(new Date());  
  28.         news.setTypeId(3);  
  29.   
  30.         service.insert(news);  
  31.     }  
  32.   
  33.     @Test  
  34.     public void testList() throws Exception {  
  35.         Map<String,Object> map = service.list(13"测试""title");  
  36.         System.out.println(map.get("allNews"));  
  37.         System.out.println(map.get("allCount"));  
  38.     }  
  39. }  

七、测试完成功,进行前台页面的编写:

如果想让Spring结合其他框架一起开发,需要先在web.xml中加入以下配置。

[html] view plain copy
  1. <span style="white-space:pre">  </span><context-param>  
  2.         <param-name>contextConfigLocation</param-name>  
  3.         <param-value>/WEB-INF/classes/applicationContext.xml</param-value> //加载Spring的配置文件  
  4.     </context-param>  
  5.   
  6.     <listener>  
  7.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  8.     </listener>  

如果怕配置错误,可以将项目部署后,启动服务器,查看控制台打印信息,如果出现以下内容,表示配置成功

信息: Initializing Spring root WebApplicationContext

如果没有问题,可以正常开始编写添加功能

[html] view plain copy
  1. <span style="white-space:pre">      </span><center>  
  2.             <a href="pages/news/news_insert.jsp">添加新闻</a>  
  3.         </center>  

完成添加页。

[java] view plain copy
  1. <span style="white-space:pre">      </span><center>  
  2.             <s:form action="news!insert.action" method="post" theme="simple" namespace="/">  
  3.                 新闻标题: <s:textfield name="news.title"></s:textfield> <br/>  
  4.                 新闻内容: <s:textfield name="news.content"></s:textfield> <br/>  
  5.                 新闻发布日期: <s:textfield name="news.pubDate"></s:textfield> <br/>  
  6.                 新闻类型: <s:textfield name="news.typeId"></s:textfield>  
  7.                 <s:submit value="提交"></s:submit>      
  8.             </s:form>  
  9.         </center>  

编写Action

[java] view plain copy
  1. public class NewsAction extends ActionSupport {  
  2.   
  3.     private INewsService service;  
  4.     private News news;  
  5.   
  6.     private String message;  
  7.     private String url;  
  8.   
  9.     public void validateInsert() {  
  10.         <span style="background-color: rgb(51, 204, 0);">// 完成验证功能,可以对表单提交的数据,在进入分发方法前进行验证,如果验证通过,则继续执行下面的操作,如果不通过,自动返回input错误页.  
  11.         // validate方法同样支持分发功能, 由于只需要对insert操作进行验证,因此将validate方法改为  
  12.         // validateInsert即可.</span>  
  13.         if (news.getTitle() == null || news.getTitle().trim().equals("")) {  
  14.             // 提示错误  
  15.             super.addFieldError("title""新闻标题不能为空!");  
  16.         }  
  17.     }  
  18.     public String insert() throws Exception {  
  19.         service.insert(news);  
  20.   
  21.         message = "添加成功" ;  
  22.         url = "index.jsp" ;   
  23.         return "success";  
  24.     }  

配置Spring:Spring中的<bean>默认是单例设计,也就是说所有的Action都是单例,

解决方法是取消Action类的单例设计。

[java] view plain copy
  1. <span style="white-space:pre">  </span><bean id="newsAction" class="org.liky.action.NewsAction" <span style="color: red; ">scope=<em>"prototype"</em></span>>  
  2.         <property name="service">  
  3.             <ref bean="newsServiceImpl"/>  
  4.         </property>  
  5.     </bean>  

配置Struts

[java] view plain copy
  1. <span style="white-space:pre">  </span><package name="root" namespace="/" extends="struts-default">  
  2.         <action name="news" class="newsAction">  
  3.             <result name="success">/success.jsp</result>  
  4.         </action>  
  5.     </package

你可能感兴趣的:(Spring + JDBC + Struts联合开发(实现单表的CRUD))