這兩天忙公司的項目,沒有把項目的demo寫出來。趁如今空閒,偷偷的寫一下。
先上demo結構目錄圖:
你們看到了吧,項目層次分得很清楚。
config 是 spring和itatis的配置文件。接下來就是經典的mvc分層架構啦,bean ---- dao ---- service ----- action --- view。理論的東西,我就很少說了。下面我按照這個demo開發流程一步一步寫出來:
一。在eclipse新建項目,導入jar包,有木有??!!!
二。集成spring和struts,web.xml文件配置以下:javascript
- <span style="font-size:16px;"><?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <display-name>ctcoms</display-name>
- <description>A Java Forum System Based on Struts2</description>
- <!-- 加載spring 配置文件 -->
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:config/spring*.xml</param-value>
- </context-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
-
- <!-- 定義Struts 2的FilterDispatcher的Filter -->
- <filter>
- <!-- 定義核心Filter的名字 -->
- <filter-name>struts2</filter-name>
- <!-- 定義核心Filter的實現類 -->
- <filter-class>
- org.apache.struts2.dispatcher.FilterDispatcher
- </filter-class>
- <!-- 設置編碼 -->
- <init-param>
- <param-name>encoding</param-name>
- <param-value>utf-8</param-value>
- </init-param>
- </filter>
-
- <!-- FilterDispatcher用來初始化Struts 2而且處理全部的Web請求 -->
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <!-- jsp等頭文件的過濾器,解決亂碼用 -->
- <filter>
- <filter-name>AddHeaderFilter</filter-name>
- <filter-class>
- org.mission.ctcoms.web.filter.AddHeaderFilter
- </filter-class>
- <init-param>
- <param-name>headers</param-name>
- <param-value>Content-Encoding=gzip</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>AddHeaderFilter</filter-name>
- <url-pattern>*.gzjs</url-pattern>
- </filter-mapping>
- <welcome-file-list>
- <welcome-file>/login.jsp</welcome-file>
- <welcome-file>/index.jsp</welcome-file>
- </welcome-file-list>
-
-
- <error-page>
- <exception-type>java.lang.Exception</exception-type>
- <location>/error.jsp</location>
- </error-page>
- </web-app>
- </span>
三。項目裏,spring是用來配置數據庫,事物管理,配置ibatis, 管理struts的action,管理dao層的bean,管理service的bean。相關的配置文件以下圖:css
四。在classpath路徑下,新建struts.xml 和log4j.properties 文件,分別是 struts的映射文件 和 日誌信息的配置。html
五。把配置文件建好之後,就開始寫代碼了。這個demo業務很簡單,只有一個bean,一張表就足夠了。表的話 你們就本身建把,一個主鍵,一個產品名就OK啦。java
bean的代碼就不貼出來了,就是getter 和setting方法。jquery
六。創建ibatis的sql配置文件,StoreProduct.xml以下:web
- <span style="font-size:16px;"><?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE sqlMap
- PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
- "http://ibatis.apache.org/dtd/sql-map-2.dtd">
- <sqlMap namespace="StoreProduct">
- <select id="findStoreProdctListNameForJson" parameterClass="java.lang.String" resultClass="java.lang.String" >
- select S.name from zy_store_product S where lower(S.name) LIKE lower('%$productName$%')
- </select>
- </sqlMap>
- </span>
namespace 就是 sql的命名空間;findStoreProdctListNameForJson 爲 調用sql 的惟一標識id; parameterClass 爲參數類型,這裏是傳了一個產品名的字符串;resultClass爲返回值類型。spring
select S.name from zy_store_product S where lower(S.name) LIKE lower('%$productName$%') 就是一句標準的sql語句了,$productName$ 表明參數。在這裏能夠執行任何複雜的sql語句,這就是sql
ibatis的靈活之處。ibatis的用法這裏就不詳細說了,之後有機會貼上一篇ibatis的增刪查改的demo。數據庫
七。封裝一個操做ibatis的類,用於簡化ibatis的crud(增刪查改)操做,每一個dao都要繼承這個類。BaseIbaitsDAO 以下:apache
- <span style="font-size:16px;">package org.mission.ctcoms.ibatis;
-
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
-
- import org.apache.log4j.Logger;
- import org.apache.struts2.ServletActionContext;
- import org.mission.ctcoms.exception.ApplicationException;
- import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
-
- /**
- *
- * @author 黃宇強
- * @date 2011-8-5 上午09:27:06
- * @description This base class is prepared for subclass to do CRUD easily.
- */
- public class BaseIbaitsDAO extends SqlMapClientDaoSupport {
- private Logger log4j = Logger.getLogger(BaseIbaitsDAO.class);
-
- /**
- * 根據條件查詢對象集合
- *
- * @param sqlid
- * 對應IBATIS xml SQL_ID
- * @param paramObj
- * 參數對象
- * @return
- */
- @SuppressWarnings("unchecked")
- public <T> List<T> loadList(String sqlid, Object paramObj) {
- return (List<T>) getSqlMapClientTemplate()
- .queryForList(sqlid, paramObj);
- }
-
- /**
- * 根據條件查詢對象全部數據
- *
- * @param <T>
- * @param sqlid
- * 對應IBATIS xml SQL_ID
- * @return
- */
- @SuppressWarnings("unchecked")
- public <T> List<T> loadList(String sqlid) {
- return (List<T>) getSqlMapClientTemplate().queryForList(sqlid);
- }
-
- /**
- * 根據ID查詢ENTITY 對象
- *
- * @param <T>
- * @param sqlid對應IBATIS
- * xml SQL_ID
- * @return <T> 實體對象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlid) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlid);
- }
-
- /**
- * 根據ID查詢ENTITY 對象
- *
- * @param <T>
- * @param sqlid對應IBATIS
- * xml SQL_ID
- * @param id
- * 實體ID
- * @return <T> 實體對象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlid, String id) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlid, id);
- }
-
- /**
- * 根據ID查詢ENTITY 對象
- *
- * @param <T>
- * @param sqlid對應IBATIS
- * xml SQL_ID
- * @param id
- * 實體ID
- * @return <T> 實體對象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlId, Long id) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlId, id);
- }
-
- /**
- * 根據條件查詢對象
- *
- * @param <T>
- * @param sqlid對應IBATIS
- * xml SQL_ID
- * @param paramObj
- * 參數
- * @return <T> 實體對象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlId, Object paramObj) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlId, paramObj);
- }
-
- /**
- * 保存對象
- *
- * @param sqlid
- * 對應IBATIS xml SQL_ID
- * @param entity
- * 保存的對象
- */
- public void save(String sqlid, Object entity) {
- getSqlMapClientTemplate().insert(sqlid, entity);
- }
-
- /**
- * 保存對象
- *
- * @param sqlid
- * 對應IBATIS xml SQL_ID
- * @param entity
- * 保存的對象
- */
- public void save(String sqlid, Map<String, Object> entity) {
- getSqlMapClientTemplate().insert(sqlid, entity);
- }
-
- /**
- * 更新對象
- *
- * @param sqlid
- * 對應IBATIS xml SQL_ID
- * @param entity
- * 修改對象
- */
- public void update(String sqlId, Map<String, Object> entity) {
- getSqlMapClientTemplate().update(sqlId, entity);
- }
-
- /**
- * 更新對象
- *
- * @param sqlid
- * 對應IBATIS xml SQL_ID
- * @param entity
- * 修改對象
- */
- public void update(String sqlId, Object entity) {
- getSqlMapClientTemplate().update(sqlId, entity);
- }
-
- /**
- * 刪除指定的對象
- *
- * @param sqlId
- * @param object
- * 須要刪除的對象
- */
- public void delete(String sqlId, Object object) {
- getSqlMapClientTemplate().delete(sqlId, object);
- }
-
- /**
- * 查詢數據總條數
- *
- * @param sqlid
- * @param object
- * @return
- */
- public Long loadRecordCountObject(String sqlid, Object object) {
- log4j.info("sqlid====" + sqlid);
- return (Long) getSqlMapClientTemplate().queryForObject(sqlid, object);
- }
-
- /**
- * 查詢數據總條數
- *
- * @param sqlid
- * @param object
- * @return 返回Int
- */
- public Integer loadRecordCount(String sqlid, Object object) {
- log4j.info("sqlid====" + sqlid);
- return (Integer) getSqlMapClientTemplate()
- .queryForObject(sqlid, object);
- }
-
- /**
- * @Title: findTNextId
- * @Description: 返回表中ID最大值加一
- * @param:
- * @param tabName
- * 表名
- * @return:
- * @returnType: Long
- * @throws
- */
- public Long findTNextId(String tabName) {
- Long id = 0l;
- String seqName = tabName.substring(3) + "_S";
- id = (Long) getSqlMapClientTemplate().queryForObject(
- "Common.findTNextId", seqName);
- if (id == null || id.equals(0l))
- throw new ApplicationException("ID查詢錯誤");
- return id;
- }
-
- public Date findOracleSysdate() {
-
- return (Date) getSqlMapClientTemplate().queryForObject(
- "Common.findOracleSysdate", null);
- }
-
- }
- </span>
八。用到spring ,是基於接口的編程了。分別實現 service、dao層的接口以及其實現類。須要注意的是,每一個service、dao都要寫進spring的相關配置文件去,實現spring對bean的管理。
九。crum的代碼寫好了,就到action層了。
- <span style="font-size:16px;">package org.mission.ctcoms.web.action.storage;
-
- import java.util.List;
-
- import org.apache.log4j.Logger;
- import org.mission.ctcoms.business.storage.IStoreProductService;
- import org.mission.ctcoms.web.code.BaseAction;
-
- public class StorageProductAction extends BaseAction {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
-
- private Logger log4j = Logger.getLogger(StorageProductAction.class);
-
- private IStoreProductService storeProductService;
-
- private List<String> content; //傳到前臺顯示用
-
- private String productName; // 產品名
-
-
- public String findStoreProdctListNameForJson() {
- try {
- String newProductName = new String(productName.getBytes("ISO-8859-1"),"utf-8"); // !!!解決參數亂碼
- List<String> list = storeProductService.findStoreProdctListNameForJson(newProductName);
- this.setContent(list);
- } catch (Exception e) {
- log4j.error("findStoreProdctListNameForJson error", e);
- }
-
- return SUCCESS;
-
- }
-
-
-
- public Logger getLog4j() {
- return log4j;
- }
-
- public void setLog4j(Logger log4j) {
- this.log4j = log4j;
- }
-
-
- public IStoreProductService getStoreProductService() {
- return storeProductService;
- }
-
- public void setStoreProductService(IStoreProductService storeProductService) {
- this.storeProductService = storeProductService;
- }
-
- public String getProductName() {
- return productName;
- }
-
- public void setProductName(String productName) {
- this.productName = productName;
- }
-
- public List<String> getContent() {
- return content;
- }
-
- public void setContent(List<String> content) {
- this.content = content;
- }
-
-
- }
- </span>
而後,該action查詢到的數據庫數據是以json方傳遞到前臺的,因此該action註冊到struts的配置文件以下:
- <span style="font-size:16px;"><?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
-
- <struts>
-
- <package name="json-storage"
- extends="json-default">
- <action name="findStoreProdctListNameForJson" method="findStoreProdctListNameForJson"
- class="storageProductAction">
- <result type="json">
- <param name="root">content</param>
- </result>
- </action>
- </package>
- <constant name="struts.action.extension" value="do" />
- </struts>
- </span>
其中 content是json的標識,與action的content和稍後說起的jquery調用 相對應。extends="json-default" 是繼承 struts-json插件的方法。
注: 該action 繼承了封裝好了的BaseAction,該類以下:
- <span style="font-size:16px;">package org.mission.ctcoms.web.code;
-
- import java.io.IOException;
- import java.io.PrintWriter;
-
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
-
- import org.apache.log4j.Logger;
- import org.apache.struts2.ServletActionContext;
-
- import com.opensymphony.xwork2.ActionSupport;
-
- /**
- *
- * @author 黃宇強
- * @date 2011-8-5 上午09:25:04
- * @description 抽象類
- */
- public class BaseAction extends ActionSupport {
- /**
- *
- */
- private static final long serialVersionUID = -4025716041310497629L;
-
- private Logger log4j = Logger.getLogger(BaseAction.class);
-
- public String jsonString;
-
- public void outJsonString(String str) {
- getResponse().setContentType("text/javascript;charset=UTF-8");
- outString(str);
- }
-
- public void outString(String str) {
- try {
- PrintWriter out = getResponse().getWriter();
- out.write(str);
- } catch (IOException e) {
- e.printStackTrace();
- log4j.error("out print failed:" + e);
- }
- }
-
- public void outXMLString(String xmlStr) {
- getResponse().setContentType("application/xml;charset=UTF-8");
- outString(xmlStr);
- }
-
- /**
- * 得到request
- *
- * @return
- */
- public HttpServletRequest getRequest() {
- return ServletActionContext.getRequest();
- }
-
- /**
- * 得到response
- *
- * @return
- */
- public HttpServletResponse getResponse() {
- return ServletActionContext.getResponse();
- }
-
- /**
- * 得到session
- *
- * @return
- */
- public HttpSession getSession() {
- return getRequest().getSession();
- }
-
- /**
- * 得到servlet上下文
- *
- *
- *
- * @return
- */
- public ServletContext getServletContext() {
- return ServletActionContext.getServletContext();
- }
-
- public String getRealyPath(String path) {
- return getServletContext().getRealPath(path);
- }
-
- }
- </span>
十。最後一步了,就是到前臺頁面。如何調用jquery.autocomplete,這個很簡單,下載官方的demo下來,很容易就看明白了。貼出jsp的實現頁面:
- <span style="font-size:16px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
-
- <title>產品自動補全</title>
-
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="cache-control" content="no-cache">
- <meta http-equiv="expires" content="0">
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <script type="text/javascript" src="jquery/jquery.js"></script>
- <script type="text/javascript" src="jquery/jquery.autocomplete.js"></script>
- <link rel="Stylesheet" type="text/css" href="jquery/jquery.autocomplete.css" />
- <script type="text/javascript">
- var v_product_Store ;
- $().ready(function() {
- $("#productName").autocomplete("findStoreProdctListNameForJson.do", { //當用戶輸入關鍵字的時候 ,經過 url的方式調用action的findStoreProdctListNameForJson方法
- minChars: 1, //最小顯示條數
- max: 12, //最大顯示條數
- autoFill: false,
- dataType : "json", //指定數據類型的渲染方式
- extraParams:
- {
- productName: function()
- {
- return $("#productName").val(); //url的參數傳遞
- }
- },
-
- //進行對返回數據的格式處理
- parse: function(data)
- {
- var rows = [];
- for(var i=; i<data.length; i++)
- {
- rows[rows.length] = {
- data:data[i],
- value:data[i],
- //result裏面顯示的是要返回到列表裏面的值
- result:data[i]
- };
- }
- return rows;
- },
- formatItem: function(item) {
- //沒有特殊的要求,直接返回了
- return item;
- }
- });
-
- });
- </script>
-
- </head>
-
- <body>
- <div>
- 產品名: <input type="text" id="productName" />
- </div>
- </body>
- </html>
- </span>
OK!搞定!再看一下效果圖: