實際開發中的模板設計模式

  最近的項目中,在使用spring+springJBDC 開發時,從一開始的一臉懵逼到愈來愈順手,着一切,都歸功於一大堆的封裝方法.在這裏,記錄兩個很是有用方法以便查閱學習java

      

 

一. 組合查詢的基礎類(BaseCondition)spring

該類中,抽取了經常使用的組合查詢的公共屬性和方法,例如:分頁查詢中使用的 sql

pagaSize// 頁大小、pageNumber// 當前頁碼、rowCount;// 記錄總數 apache

rowCount;// 記錄總數 設計模式

拼接sql語句使用的多個重載add()方法,更據不一樣數據類型重載;數組

最重要的是獲取最終拼接條件sqlgetCondition()方法,此處使用模板方法,子類在繼承該基礎類以後須要重寫模板中的addCondition()方法來拼接查詢條件。app

 


import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.common.constant.Constant; import com.common.util.DataUtil; /** * @功能說明:拼加頁面查詢條件的基礎類 * @author gzz */ public abstract class BaseCondition { private Log logger = LogFactory.getLog(getClass());// 日誌類 private List<Object> paramList = new ArrayList<Object>();// 參數值 private StringBuffer condition = new StringBuffer();// 條件語句 private Integer pageSize = 15;// 頁大小(每頁記錄條) private Integer rowCount;// 記錄總數 private Integer rowCount;// 記錄總數 private Integer curPage = 1;// 當前頁碼 /** * @功能: 拼加條件使用等於大於小於....運算符(String類型) */ protected void add(String value, String strSQL) { if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) { condition.append(" " + strSQL); paramList.add(value); } } /** * @功能: 拼加條件使用等於大於小於....運算符(Long類型) */ protected void add(Long value, String strSQL) { if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) { condition.append(" " + strSQL); paramList.add(value); } } /** * @功能: 拼加條件使用等於大於小於....運算符(Boolean類型) */ protected void add(Boolean value, String strSQL) { if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) { condition.append(" " + strSQL); paramList.add(value); } } /** * @功能: 拼加條件使用等於大於小於....運算符(BigDecimal類型) */ protected void add(BigDecimal value, String strSQL) { if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) { condition.append(" " + strSQL); paramList.add(value); } } /** * @功能: 拼加條件使用等於大於小於....運算符(Integer類型) */ protected void add(Integer value, String strSQL) { if (null != value && !"".equals(strSQL) && null != strSQL) { condition.append(" " + strSQL); paramList.add(value); } } /** * @功能: 拼加條件使用等於大於小於....運算符(Date類型) */ protected void add(Date value, String strSQL) { if (null != value && !"".equals(strSQL) && null != strSQL) { condition.append(" " + strSQL); paramList.add(value); } } /** * @功能: 拼加條件 */ protected void add(String strSQL) { if (null != strSQL && !"".equals(strSQL)) { condition.append(" " + strSQL); } } /** * @功能: 拼加條件使用like關鍵字模糊查詢時 * * @param value * :屬性名稱 * @param strSQL * :參數SQL字符 * @param posLike * :字句中百分號出現位置 * @return strSQL:拼加後SQL字符包括佔位符 */ protected void add(String value, String strSQL, int pos) { if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) { condition.append(" " + strSQL); if (pos == 1) { paramList.add("%" + value); } else if (pos == 2) { paramList.add(value + "%"); } else if (pos == 3) { paramList.add("%" + value + "%"); } } } /** * @功能: 拼加IN字句條件 */ protected void addIn(String value, String strSQL) { if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) { condition.append(" " + strSQL); } } /** * @功能: 將List轉爲數組 */ public Object[] getArray() { return paramList.toArray(); } /** * @功能: 取條件字符串(模板設計模式) */ public String getCondition() { // 清除查詢條件  condition.setLength(0); paramList.clear(); addCondition(); return condition.toString(); } /** * @功能: 拼加條件方法 */ public abstract void addCondition(); public BaseCondition() { } public BaseCondition(Object[][] obj) { Method method; Class<?> paraClass; try { for (Object[] o : obj) { if (o[1].getClass().getName().contains("Integer")) { paraClass = Integer.class; } else if (o[1].getClass().getName().contains("Date")) { paraClass = Date.class; } else { paraClass = String.class; } method = this.getClass().getDeclaredMethod("set" + DataUtil.firstUpper(o[0].toString()), paraClass); method.invoke(this, o[1]); } } catch (Exception e) { logger.error("構造條件賦值時發生的錯誤,請覈對條件字段名稱."); e.printStackTrace(); } } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public Integer getRowCount() { return rowCount; } public void setRowCount(Integer rowCount) { this.rowCount = rowCount; } public Integer getPageCount() { return pageCount; } public void setPageCount(Integer pageCount) { this.pageCount = pageCount; } public Integer getCurPage() { return curPage; } public void setCurPage(Integer curPage) { this.curPage = curPage; } } 

 

二.dao公共類(BaseDao)學習

本項目中,使用了springJDBC,爲避免在實現過程當中產生了大量的冗餘代碼,本類誕生了。this

該類中注入了每一個dao都會用的JdbcTemplate,以及分頁查詢的方法。spa

 

 

import java.util.List;

import java.util.Map;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.BeanPropertyRowMapper;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.common.condition.BaseCondition;

/**

 * @功能描述:dao類公共類

 * @author 

 * @param <T>

 */

public class BaseDao<T> {

protected final Log logger = LogFactory.getLog(BaseDao.class);// 日誌類

@Autowired

protected JdbcTemplate jdbcTemplate;// jdbc模版類

@Autowired

protected NamedParameterJdbcTemplate namedJdbcTemplate;// jdbc模版類

protected void queryPage(Map<String, Object> map, String sql, BaseCondition cond, Class<T> clazz) {

String countSQL = "SELECT count(1) FROM (" + sql + ") t";// 統計記錄個數的SQL語句

int rowCount = jdbcTemplate.queryForObject(countSQL, cond.getArray(), Integer.class);// 查詢記錄個數

cond.setRowCount(rowCount);

int pageSize = cond.getPageSize();// 頁大小

int curPage = cond.getCurPage();// 當前頁

cond.setPageCount(rowCount % pageSize == 0 ? rowCount / pageSize : rowCount / pageSize + 1);// 頁數

String listSql = sql + " LIMIT " + (curPage - 1) * pageSize + "," + pageSize;// 查詢分頁數據列表的SQL語句

List<T> dataList = jdbcTemplate.query(listSql.toString(), cond.getArray(), new BeanPropertyRowMapper<T>(clazz));

map.put("dataList", dataList);

 

方法使用實例:

//這是public class BannerDaoImpl extends BaseDao<Banner> implements IBannerDao

//中的一個方法,它繼承了BaseDao; 一樣BannerCond繼承了BaseCondition,BannerCond

//中重寫了模板中的addCondition() 方法,在方法中按照項目要求拼接條件

//BannerCond中的方法addCondition()實現

public void addCondition() {

add(name_c,"and name like ?",3);//模糊查詢

add(order_num_c,"and order_num=?");

add(picture_path_c,"and picture_path=?");

.......................//等等別的屬性拼接

 

add(name_v,"and name=?");//精確查詢

add(id_c,"and id!=?");

 

}

/**

*功能:實現分頁查詢

*/

public void queryList(BannerCond cond, Map<String, Object> map) {

StringBuffer sb =new StringBuffer();

sb.append("select * from cms_banner where 1=1 ");

sb.append(cond.getCondition());

sb.append(" order by id");

queryPage(map, sb.toString(), cond, Banner.class);

}

//該方法處於dao層,其中的BannerCond cond 實際上是由 處理器傳遞給serviceservice//遞給dao層的,(參數中的map是用來共享數據的,在BaseDao中能夠看到)

//service層調用dao代碼

public void queryList(BannerCond cond, Map<String, Object> map) {

dao.queryList(cond, map);

}

 

咱們看到,在service層中,咱們只須要關心主要業務便可,開發變得異常簡單。固然,前提是理解了衆多如上述的基礎方法。實現業務,完成項目不在困難。

相關文章
相關標籤/搜索