实际开发中的模板设计模式

最近的项目中,在使用spring+springJBDC 开发时,从一开始的一脸懵逼到越来越顺手,着一切,都归功于一大堆的封装方法.在这里,记录两个非常有用方法以便查阅学习

一. 组合查询的基础类(BaseCondition)

该类中,抽取了常用的组合查询的公共属性和方法,例如:分页查询中使用的

pagaSize// 页大小、pageNumber// 当前页码、rowCount;// 记录总数

rowCount;// 记录总数

拼接sql语句使用的多个重载add()方法,更据不同数据类型重载;

最重要的是获取最终拼接条件sql的getCondition()方法,此处使用模板方法,子类在继承该基础类之后需要重写模板中的addCondition()方法来拼接查询条件。

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,为避免在实现过程中产生了大量的冗余代码,本类诞生了。

该类中注入了每个dao都会用的JdbcTemplate,以及分页查询的方法。

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 其实是由 处理器传递给service,service传//递给dao层的,(参数中的map是用来共享数据的,在BaseDao中可以看到)


//service层调用dao代码

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

dao.queryList(cond, map);

}

我们看到,在service层中,我们只需要关心主要业务即可,开发变得异常简单。当然,前提是理解了众多如上述的基础方法。实现业务,完成项目不在困难。

时间: 2024-08-21 09:01:27

实际开发中的模板设计模式的相关文章

Android开发中无处不在的设计模式——原型模式

不知不觉这个系列已经写了三篇了,其实很早之前就想写设计模式了,只不过怕自己误人子弟没有提笔去写.后来在实际开发中,发现设计模式可以让一个开发人员融会贯通所学的知识,为了进一步巩固自己,就写下了这一些列文章.前面介绍了三个模式. Android开发中无处不在的设计模式--单例模式 Android开发中无处不在的设计模式--Builder模式 Android开发中无处不在的设计模式--观察者模式 本篇文章介绍的模式其实很简单,即原型模式,按照惯例,先看定义. 用原型实例指定创建对象的种类,并通过拷贝

Android开发中无处不在的设计模式——策略模式

这个系列停更了好久了,差不多可以重新拿起来更一篇了,这篇文章主要介绍策略模式.在这之前,先温习一下前面介绍的4种模式. 设计模式很重要! 设计模式很重要! 设计模式很重要! 重要的事说三遍!!! Android开发中无处不在的设计模式--单例模式 Android开发中无处不在的设计模式--Builder模式 Android开发中无处不在的设计模式--观察者模式 Android开发中无处不在的设计模式--原型模式 接着看下策略模式的定义 策略模式定义了一些列的算法,并将每一个算法封装起来,而且使它

Android开发中的MVC设计模式

Android开发中的MVC设计模式的理解 1. Android系统中分层的理解: (1).在Android的软件开发工作中,应用程序的开发人员主要是应用Android Application Framework层封装好的Api进行快速开发. (2).在Android框架的四个层次中,下层为上层服务,上层需要下层的支持,上层需要调用下层的服务. (3).这种分层的方式带来极大的稳定性.灵活性和可扩展性,使得不同层的开发人员可以按照规范专心特定层的开发. (4). Android的官方建议应用程序

Android开发中无处不在的设计模式——动态代理模式

继续更新设计模式系列,写这个模式的主要原因是最近看到了动态代理的代码. 先来回顾一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式--Builder模式 - Android开发中无处不在的设计模式--观察者模式 - Android开发中无处不在的设计模式--原型模式 - Android开发中无处不在的设计模式--策略模式 动态代理模式在Java WEB中的应用简直是随处可见,尤其在Spring框架中大量的用到了动态代理:算是最重要

Android开发中无处不在的设计模式——单例模式

对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的同学,这里推荐2本书.一本是Head First系列的Head Hirst Design Pattern,英文好的可以看英文,可以多读几遍.另外一本是大话设计模式. 这篇文章介绍一个模式,就是单例模式,因为个人觉得这个模式理解起来最容易,而且不是太复杂. 首先了解一些什么是单例,从名字中就可以听出来

Android开发中常见的设计模式

对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的同学,这里推荐2本书.一本是Head First系列的Head Hirst Design Pattern,英文好的可以看英文,可以多读几遍.另外一本是大话设计模式. 单例模式 首先了解一些单例模式的概念. 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这样做有以下几个优点 对于

Android开发中常见的设计模式(一)——单例模式

首先了解一些单例模式的概念. 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这样做有以下几个优点 对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中. 保持程序运行的时候该中始终只有一个实例存在内存中 其实单例有很多种实现方式,但是个人比较倾向于其中1种.可以见单例模式 代码如下 public class Singleton { private static volatile Singleton instance = null; private Sin

在WindowsPhone开发中使用MVVM设计模式

相信.NET程序员多多少少都听说过MVVM的设计模式,对于一个大一点的项目来说,使用这种设计模式无疑是一种不错的选择, 它提高了程序的可维护性,降低了耦合度,可以实现代码的重用,方便独立开发和进行测试.这里,笔者讲述一下如何在WindowsPhone中开发使用这种设计模式. 功能描述:通过在前台显示和更改数据来保证后台数据可以实时更新,始终与前台保持一致. 首先,我们建立一个空的WindowsPhone工程,分别为当前工程中添加一个ViewModel文件夹和Model文件夹,用于储存不同的类文件

iOS开发中常用的设计模式

常用的设计模式(一)代理模式应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现.优势:解耦合敏捷原则:开放-封闭原则实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求.列表row个数delegate自定义的delegate (二)观察者模式应用场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,只负责发布信息.优势:解耦合敏捷原则:接口隔离原则,开放-封闭原则实例:Notificatio