兩三年前曾經寫過相似的通用方法,後來由于工作忙碌的原因,沒有進行後續維護和改進,近來處來項目空閑期,回顧一遍後發現之前的方法過于依賴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;
}
}