天天看點

SpringMVC,Ajax內建的背景基礎字典資訊的通用方法設計

兩三年前曾經寫過相似的通用方法,後來由于工作忙碌的原因,沒有進行後續維護和改進,近來處來項目空閑期,回顧一遍後發現之前的方法過于依賴ExtJS與struts2,耦合性高,并且重用性也不好,對于目前流行的springMVC與Ajax也不能重寫或修改,是以這裡我決定基于原先的設計思路重新設計出了一套基于springMVC與Ajax的資料字典資訊的通用方法。

資料字典,即我們所說的最基本的字典表,該對象僅僅包含id,name兩個屬性,是最基礎的對象。下面就用具體的代碼展現設計的通用方法,我也很希望各位技術牛人能在看完後給予我建議或意見,畢竟我僅僅隻有兩年的工作經驗。

1.controller層

該層屬于模闆層,我用靜态屬性變量的方式使之成為一種模闆,開發時,根據特定的項目約定和規則修改靜态變量。

package com.java.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.java.business.DictionaryObjectBus;
import com.java.tool.Page;


/**
 * 此類用于資料字典表的通用複制粘貼類,
 * @author liuyuqin
 * @date 2015年2月3日10:01:37
 * 說明:
 * ①:該方法中包含了分頁對象page,是以使用該類時,需要導入page分頁對象,如果不使用分頁對象Page,則需對周遊方法進行重寫
 * ②:字典資料對象的id和name的資料類型都是String類型,否則,需要修改添加,修改,删除的字段資料類型
 * ③:msg資訊包含了操作的傳回資訊,如果成功,即為SUCCESS,如果失敗,會傳回String類型的詳細資訊,前台列印詳細資訊即可
 * ④:周遊和查找對象方法涉及到頁面跳轉,使用了springMVC的ModelAndView對象
 * 	   添加和修改方法沒有涉及頁面跳轉,使用了傳統的ajax
 */
@Controller
public class DictionaryObjectController {
	private static final Log log = LogFactory
			.getLog(DictionaryObjectController.class);

	/**類相關資訊**/
	//輸入類對象位置
	private static final String OBJECTNAME = "首字母大寫的對象名稱,例如Xxxx";
	//輸入類對象包全名
	private static final String OBJECTFULLNAME = "包含包名在内的對象全稱,例如com.java.bean.XXX";
	/*以下是測試用例
	private static final String OBJECTNAME = "Dictionary";
	private static final String OBJECTFULLNAME = "com.java.bean.Dictionary";	
	*/
	
	
	/**requestMapping路徑位置**/
	
	private static final String QUERY_REQUESTMAPPING = "Query方法中的requestMapping路徑";
	private static final String INSERT_REQUESTMAPPING = "Insert方法中的requestMapping路徑";
	private static final String UPDATE_REQUESTMAPPING = "Update方法中的requestMapping路徑";
	private static final String FINDBYID_REQUESTMAPPING = "FindById方法中的requestMapping路徑";
	private static final String DELETE_REQUESTMAPPING = "Delete方法中的requestMapping路徑";
	private static final String DELETE_BATCH_REQUESTMAPPING = "批量Delete方法中的requestMapping路徑";
	/*以下是測試用例
	private static final String QUERY_REQUESTMAPPING = "admin/dictionary/queryDictionaryObject";
	private static final String INSERT_REQUESTMAPPING = "admin/dictionary/insertDictionaryObject";
	private static final String UPDATE_REQUESTMAPPING = "admin/dictionary/updateDictionaryObject";
	private static final String FINDBYID_REQUESTMAPPING = "admin/dictionary/findDictionaryObjectById";
	private static final String DELETE_REQUESTMAPPING = "admin/dictionary/deleteDictionaryObject";
	private static final String DELETE_BATCH_REQUESTMAPPING = "admin/dictionary/deleteBatchDictionaryObject";
	*/
	
	/**輸入跳轉url頁面位置**/
	
	private static final String QUERY_RETURN_VIEW = "Query方法中傳回的跳轉url頁面"; 
	private static final String FINDBYID_RETURN_VIEW = "FindById方法中傳回的跳轉url頁面";
	/*以下是測試用例
	private static final String FINDBYID_RETURN_VIEW = "admin/dictionary/dictionaryEdit"; 
	private static final String QUERY_RETURN_VIEW = "admin/dictionary/dictionaryList";
	*/
	
	/**輸出傳輸參數**/
	private static final String QUERY_RETURN_LIST="Query方法中傳回的傳輸對象List集合";
	private static final String FINDBYID_RETURN_OBJECT="FindById方法中傳回的傳輸對象";
	/*以下是測試用例
	private static final String FINDBYID_RETURN_OBJECT="dictionary";
	private static final String QUERY_RETURN_LIST="dictionaryList";
	*/
	
	
	/**輸入傳輸參數**/
	private static final String OBJECTID="FindById方法中需要傳入的參數";
	/*以下是測試用例
	private static final String OBJECTID="dictionaryId";
	*/
	
	@Autowired
	private DictionaryObjectBus dictionaryObjectBus;
	
	/**
	 * 分頁周遊清單顯示
	 * @param page
	 */
	@RequestMapping(value = QUERY_REQUESTMAPPING)
	public ModelAndView queryDictionaryObject(Page page) throws Exception {
		ModelAndView mav = new ModelAndView();
		Map<String , Object> map = new HashMap<String, Object>();
		map = dictionaryObjectBus.queryDictionaryObject(page,OBJECTNAME);
		mav.setViewName(QUERY_RETURN_VIEW);
		mav.addObject(QUERY_RETURN_LIST,map.get("list"));
		mav.addObject("page", map.get("page"));	
		return mav;
	}

	/**
	 * 添加對象
	 * @param object
	 * @param session
	 * @param response
	 * @throws Exception 
	 */
	@RequestMapping(value = INSERT_REQUESTMAPPING)
	public void insertDictionaryObject(String name,HttpSession session,HttpServletResponse response) throws Exception {
		JSONObject obj = new JSONObject();
		PrintWriter out = null;
		String msg = "";
		try{
			out = response.getWriter();
			msg = dictionaryObjectBus.insertDictionaryByCheckRepeatYES(name,OBJECTNAME,OBJECTFULLNAME);
			obj.put("msg", msg);
			out.print(obj);
		}catch (Exception e) {  
            e.printStackTrace();  
        }  
 		finally{
			out.close();
		}
	}

	/**
	 * 修改對象
	 * @param object
	 * @param session
	 * @param response
	 * @throws Exception 
	 */
	@RequestMapping(value = UPDATE_REQUESTMAPPING)
	public void updateDictionaryObject(String id,String name,HttpSession session,HttpServletResponse response) throws Exception {
		JSONObject obj = new JSONObject();
		PrintWriter out = null;
		String msg = "";
		try{
			out = response.getWriter();
			msg = dictionaryObjectBus.updateDictionaryObject(id,name,OBJECTNAME,OBJECTFULLNAME);
			obj.put("msg", msg);
			out.print(obj);
		}catch (Exception e){  
            e.printStackTrace();  
        }  
 		finally{
			out.close();
		}
	}
	
	
	/**
	 * 通過對象ID查找對象集合
	 * @param object
	 * @throws Exception 
	 */
	@RequestMapping(value =FINDBYID_REQUESTMAPPING)
	public ModelAndView findDictionaryObjectById(
			@RequestParam(OBJECTID) String objectId) throws Exception {
		ModelAndView mav = new ModelAndView();
		Object obj =  dictionaryObjectBus.findDictionaryObjectById(objectId,OBJECTNAME);
		mav.setViewName(FINDBYID_RETURN_VIEW);
		mav.addObject(FINDBYID_RETURN_OBJECT, obj);
		return mav;
	}
	
	

	/**
	 * 删除對象(單個删除)
	 * @param OBJECTID
	 */
	@RequestMapping(value = DELETE_REQUESTMAPPING)
	public void deleteDictionaryObject(@RequestParam(OBJECTID) String objectId,
			HttpServletResponse response) throws Exception {
		PrintWriter out = null;
		String msg = "";
		try{
			out = response.getWriter();
			msg = dictionaryObjectBus.deleteDictionaryObject(objectId,OBJECTNAME);
			out.print(msg);
		}catch (Exception e) {  
			e.printStackTrace();  
		}  
		finally{
			out.close();
		}
	}
	
	/**
	 * 删除商品分類(批量删除)
	 * @param idArray
	 */
	@RequestMapping(value = DELETE_BATCH_REQUESTMAPPING)
	public void deleteBatchDictionaryObject(
			String idArray,HttpServletResponse response){
		PrintWriter out = null;
		String msg = "";
		try{
			out = response.getWriter();
			msg = dictionaryObjectBus.deleteDictionaryObject(idArray,OBJECTNAME);
			out.print(msg);
		}catch (Exception e) {  
			e.printStackTrace();  
		}  
		finally{
			out.close();
		}
	}
}
           

2.business層

business層是此設計模式的重點java方法,該方法利用反射的設計思路寫了一套通用方法

package com.java.business;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.java.dao.DictionaryObjectDao;
import com.java.tool.Page;

/**
 * 字典資訊通用CRUD方法,适用于id name兩個字段的字典資料的CRUD
 * @author liuyuqin
 * @date 2015年2月3日14:14:27
 *
 */
@Service("dictionaryObjectBus")
public class DictionaryObjectBus {

	@Resource
	private DictionaryObjectDao dictionaryObjectDao;
	
	private static final Logger log = LoggerFactory.getLogger("dictionaryObjectLog");
	
	
	/**
	 * 添加字典表資訊(加入名稱驗證重複性驗證)
	 * <字典表結構 必須是 name value屬性設定,即鍵值對設定>
	 * @return
	 * @throws Exception 
	 */
	public String insertDictionaryByCheckRepeatYES(String objectName,String OBJECTNAME,String OBJECTFULLNAME) throws Exception{
		Object o = null;
		Class object  = Class.forName(OBJECTFULLNAME);
		//建立動态對象執行個體
		o = object.newInstance();
		//通過字典表資訊名稱查詢是否已經存在該字典表資訊,如果存在傳回重複資訊,不存在則進行添加 
		List<Object> dictionaryObjectList = (List<Object>) dictionaryObjectDao.findSpecificByName(objectName,OBJECTNAME);
		//判斷添加的對象的屬性名稱是否與資料庫已有資料名稱重名
		if(dictionaryObjectList.size() == 0){
			try {
				//将名稱值傳入
				Method tAge = object.getMethod("setName", String.class);
				tAge.invoke(o, objectName);
				dictionaryObjectDao.save(o);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "SUCCESS";
		}
		else 
			return "輸入的名稱已存在,請重新輸入";
	}
	
	/**
	 * 添加字典表資訊(不加入名稱驗證重複性驗證)
	 *  <字典表結構 必須是 name value屬性設定,即鍵值對設定>
	 * @return
	 * @throws Exception 
	 */
	public String insertDictionaryByCheckRepeatNO(String objectName,String OBJECTNAME,String OBJECTFULLNAME) throws Exception{
		Object o = null;
		Class object  = Class.forName(OBJECTFULLNAME);
		//建立動态對象執行個體
		o = object.newInstance();
		try {
			//将名稱值傳入
			Method tAge = object.getMethod("setName", String.class);
			tAge.invoke(o, objectName);
			dictionaryObjectDao.save(o);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "SUCCESS";
	}
	
	/**
	 * 修改字典表對象資訊
	 * @param Object
	 * @return
	 */
	public String updateDictionaryObject(String id,String name,String OBJECTNAME,String OBJECTFULLNAME) throws Exception{
		List<Object> dictionaryObjectList = (List<Object>) dictionaryObjectDao.findOtherSpecificByIdAndName(id,name,OBJECTNAME);
		if(dictionaryObjectList.size() >0){
			return "輸入的名稱已存在,請重新輸入";
		}
		else{
			Object obb = dictionaryObjectDao.findSpecificById(id, OBJECTNAME);
			Class c = obb.getClass();
			Method sAge = c.getMethod("setName", String.class);
			sAge.invoke(obb, name);
			//log.info(LogHelper.userLog("update class<"+className+">["+dictionaryObjectName+"]"));
			return "SUCCESS";
		}
	}
	
	 /**  删除字典表某條資訊(支援多條删除)
	 * @throws Exception 
	 */
	public String deleteDictionaryObject(String delData,String className) throws Exception{
		 String[] ids = delData.split(",");
		 String objectName ="";
		 for (int i = 0; i < ids.length; i++) {
			 Object object =dictionaryObjectDao.findSpecificById(ids[i], className); 
			 dictionaryObjectDao.delete(object);
			 if(objectName.equals("")){
				 objectName += ids[i] ;
			 }
			 else 
				objectName += "," + ids[i] ;
		 }
		 //log.info(LogHelper.userLog("delete class<"+className+">["+objectName+"]"));
		 return "SUCCESS";
	}
	
	/**
	 * 分頁顯示所有字典表資訊
	 * @throws Exception 
	 * @return
	 */
	public Map<String, Object> queryDictionaryObject(Page page,String className){
		return dictionaryObjectDao.queryDictionaryObject(page,className);
	}
	
	/**
	 * 根據字典表對象Id找到相應對象
	 * @return 
	 */
	public Object findDictionaryObjectById(String objectId,String className) throws Exception{
		return dictionaryObjectDao.findSpecificById(objectId,className);
	}
}
           

3,dao層

dao層也為通用方法

package com.java.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.java.tool.Page;

/**
 * A data access object (DAO) providing persistence and search support for Role
 * entities. Transaction control of the save(), update() and delete() operations
 * can directly support Spring container-managed transactions or they can be
 * augmented to handle user-managed Spring transactions. Each of these methods
 * provides additional information for how to configure it for the desired type
 * of transaction control.
 * 
 * @see com.donglusoft.rightmanagerment.domain.Role
 * @author MyEclipse Persistence Tools
 */

/**
 * 字典資訊通用CRUD方法,适用于id name兩個字段的字典資料的CRUD
 * @author liuyuqin
 * @date 2015年2月3日14:14:27
 *
 */
@Repository("dictionaryObjectDao")
public class DictionaryObjectDao extends EntityDaoImpl {
	private static final Logger log = LoggerFactory.getLogger(DictionaryObjectDao.class);
	
	
	/**********************自定義方法(↓)****************************/
	/**
	 *  通過Id查找特定的對象
	 */
	public Object findSpecificById(String dictionaryObjectId,String className){
		try{
			String queryString = "from " + className + " as t where " +
					"t.id=:dictionaryObjectId";
			Query query = getSession().createQuery(queryString);
			query.setString("dictionaryObjectId", dictionaryObjectId);
			return query.uniqueResult();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			throw e;
			}
	}
	
	/**
	 *  通過name查找特定的對象
	 */
	public List<Object> findSpecificByName(String dictionaryObjectName,String className){
		try{
			String queryString = "from "+className +" as t where t.name =:name";
			Query query = getSession().createQuery(queryString);
			query.setString("name", dictionaryObjectName);
			return query.list();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			throw e;
			}
	}
	
	/**
	 *  通過name查找特定的id不是dictionaryObjectId的對象
	 */
	public List findOtherSpecificByIdAndName(String dictionaryObjectId,String dictionaryObjectName,String className){
		try{
			String queryString = "from "+className +" as t where t.name =:name and t.id<>:id ";
			Query query = getSession().createQuery(queryString);
			query.setString("name", dictionaryObjectName);
			query.setString("id", dictionaryObjectId);
			return query.list();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			throw e;
			}
	}
	
	 /**
	 * 周遊所有可用的DictionaryObject對象
	 * @param page
	 * @param className
	 * @return
	 */
	public Map<String, Object> queryDictionaryObject(Page page , String className){
		Map<String, Object> map = new HashMap<String, Object>();
		try { 
			String queryString = "from " +className;
			String countString = "select count(*) from " +className;
			Query query = getSession().createQuery(queryString);
			Query countquery = getSession().createQuery(countString);
			query.setFirstResult(page.getPageNo() * page.getPageLines());
			query.setMaxResults(page.getPageLines());
			int totalRows = Integer.parseInt(countquery.uniqueResult().toString());
			page.setTotalPages(totalRows, page.getPageLines());
			map.put("list", query.list());
			map.put("page", page);
			return map;
		} catch (HibernateException e) {
			throw e;
		}
	}

	
	/**********************自定義方法(↑)****************************/

	public void save(Object transientInstance) {
		log.debug("saving Object instance");
		try {
			getSession().save(transientInstance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	public void delete(Object persistentInstance) {
		log.debug("deleting Object instance");
		try {
			getSession().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}
}
           

前台利用表單送出insert與update,其他使用ajax送出即可

最後還有Page分頁對象,javaBean如下

package com.java.tool;

public class Page {

	private int totalRows; // 總記錄數

	private int pageLines; // 每頁顯示行數

	private int pageNo; // 目前頁數

	private int totalPages; // 總頁數

	public Page() {
		totalRows = 0;
		pageLines = 10;
		pageNo = 0;
		totalPages = 1;
	}

	public int getTotalRows() {
		return totalRows;
	}

	public void setTotalRows(int totalRows) {
		if (totalRows >= 0)
			this.totalRows = totalRows;
	}

	public int getPageLines() {
		return pageLines;
	}

	public void setPageLines(int pageLines) {
		if (pageLines > 0)
			this.pageLines = pageLines;
	}

	public void setPageLines(String pageLines) {
		if (pageLines == null || pageLines.length() == 0
				|| pageLines.equals("0")) {
			this.pageLines = 50;
		} else {
			this.pageLines = Integer.parseInt(pageLines);
		}
	}

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
//		if (pageNo > 0)
			this.pageNo = pageNo;
	}

	public void setPageNo(String pageNo) {
//		if (pageNo == null || pageNo.length() == 0) {
//			this.pageNo = 1;
//		} else {
			this.pageNo = Integer.parseInt(pageNo);
//		}
	}

	public int getTotalPages() {
		return totalPages;
	}

	// 總頁數 記錄數和每頁記錄數
	public void setTotalPages(int totalRows, int pageLines) {
		this.totalRows = totalRows;
		if (pageLines > 0)
			this.pageLines = pageLines;
		if (pageLines > 0)
			this.totalPages = totalRows % pageLines == 0 ? totalRows
					/ pageLines : totalRows / pageLines + 1;
	}

	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}

	public void validateData() {
		if (this.pageNo > this.totalPages)
			this.pageNo = this.totalPages;
		if (this.pageNo <= 0)
			this.pageNo = 1;
		if (this.pageLines <= 0)
			this.pageLines = 10;
	}
}