论坛首页 Java企业应用论坛

关于Service和DAO层的功能划分的迷惑

浏览 23048 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-02-13  
Service 层的代码

public class GeneralService extends AbstractService {
	private GeneralDao generalDao;

	public void setGeneralDao(GeneralDao generalDao) {
		this.generalDao = generalDao;
	}

	public void saveResourceSale(ResourceItemFormbean resourceItem)
			throws Exception {
		generalDao.saveResourceSale(resourceItem);
	}

	public List selectTodayResource(Map params) throws Exception {
		return generalDao.selectTodayResource(params);
	}

	public List selectTdPrintInfo(Integer ddid, Integer linkmanid)
			throws Exception {
		return generalDao.selectTdPrintInfo(ddid, linkmanid);
	}

	public List selectTdPrintItems(Integer ddid) throws Exception {
		return generalDao.selectTdPrintItems(ddid);
	}

	public List selectTodayBuy(Map params) throws Exception {
		return generalDao.selectTodayBuy(params);
	}

	public List selectStockKgzy(Integer ptid, Integer prodid, Integer cmdeptid,Integer page)
			throws Exception {
		return generalDao.selectStockKgzy(ptid, prodid, cmdeptid,page);
	}
	
	public List selectStockXqzy(Integer ptid, Integer prodid, Integer cmdeptid,
			Integer page) throws Exception {
		return generalDao.selectStockXqzy(ptid, prodid, cmdeptid, page);
	}

	public void deletePublishedResource(Integer pkid) throws Exception {
		generalDao.deletePublishedResource(pkid);
	}	
	
	public void saveXqResourcePublish(XqZyfbModel data) throws Exception {
		generalDao.saveXqResourcePublish(data);
	}
	
	public XqZyfbModel selectXqResourceDetail(Integer pkid) throws Exception {
		return generalDao.selectXqResourceDetail(pkid);
	}	
}


DAO 层的代码

public class GeneralDao extends AbstractDao {
	public void saveResourcePublish(ZyfbModel data) throws Exception {
		getSqlMapClientTemplate().update("MainProcedure.saveResourcePublish",
				data);
	}

	public void updateResourcePublish(ZyfbModel data) throws Exception {
		getSqlMapClientTemplate().update("MainProcedure.updateResourcePublish",
				data);
	}
	
	public void deletePublishedResource(Integer pkid) throws Exception {
		getSqlMapClientTemplate().update("MainProcedure.deletePublishedResource",
				pkid);
	}	
	

	public List selectStockXqzy(Integer ptid, Integer prodid, Integer cmdeptid,
			Integer page) throws Exception {
		Map params = new HashMap();
		params.put("ptid", ptid);
		params.put("prodid", prodid);
		params.put("cmdeptid", cmdeptid);
		params.put("row", new Integer(15));
		params.put("page", page);
		return getSqlMapClientTemplate().queryForList(
				"MainProcedure.selectStockXqzy", params);
	}	
	
	public void saveXqResourcePublish(XqZyfbModel data) throws Exception {
		getSqlMapClientTemplate().update("MainProcedure.saveXqResourcePublish",
				data);
	}	
	
	public XqZyfbModel selectXqResourceDetail(Integer pkid) throws Exception {
		return (XqZyfbModel) getSqlMapClientTemplate().queryForObject(
				"MainProcedure.selectXqResourceDetail", pkid);
	}
}


迷惑的是在上面的代码中,Service 并没有什么业务逻辑,似乎可有可无,是否上面的代码可以将Service层省略,直接在DAO层操作和事务拦截,只有涉及到具体业务逻辑的时候使用Service,当然这会造成Controller和DAO层之间的紧耦合,大家在项目中遇到如上情况都是如何做的?
   发表时间:2007-02-13  

视情况而定,简单的合并
复杂的分分层
0 请登录后投票
   发表时间:2007-02-13  
一种折中的办法是业务层继承dao层 业务对象要用到多个dao时会麻烦一些
像cms系统就是这种情况,大多数的操作是crud,要是按照上面的写法还不疯了
可以参考一下springside2中的方法
0 请登录后投票
   发表时间:2007-02-13  
xly_971223 写道
一种折中的办法是业务层继承dao层 业务对象要用到多个dao时会麻烦一些
像cms系统就是这种情况,大多数的操作是crud,要是按照上面的写法还不疯了
可以参考一下springside2中的方法
业务层继承DAO层,Service 肯定要访问多个DAO的,这个继承的方案有些行不通,现在已经快疯了:)

giscat 写道
视情况而定,简单的合并
复杂的分分层


现在的业务基本都是这种简单的情况,因为复杂的方式要求写存储过程. 简单情况如何合并?不是很理解




0 请登录后投票
   发表时间:2007-02-13  

在 service层, if (pkid==null) 这样的代码从来就没写过???????

0 请登录后投票
   发表时间:2007-02-13  
codeutil 写道

在 service层, if (pkid==null) 这样的代码从来就没写过???????

楼上的意思是不是向Hibernate的saveOrUpdate一样,对于save和update在Service层只有一个方法,save和update是可以简单的合并,但是我还是有很多的get,select之类的啊!
0 请登录后投票
   发表时间:2007-02-14  
目的是为了减少Service和DAO之间代码的过分重复,想来想去,以上代码在Service层代码简化的可能性很小!因此把方向放在对DAO层代码的优化上面来!

初步想法是DAO设计如下几个通用方法:

List queryForList(Object entity);
Object queryForObject(Object entity);
int saveEntity(Object entity);
int updateEntity(Object entity);
int deleteEntity(Object entity);


我用的是iBatis,有一个如何确定Statementid的问题,本来考虑在如上代码中添加一个String类型的参数,或者自己设计一个StatementType实现对Statmentid 的包装,感觉是一个道理.这样坏处就是Statementid需要由Service来指定,但是这些东西职责上应该由DAO来关心!

考虑再三决定根据参数类型来决定statmentid,这样需要一定的命名规范.

List queryForList(Object entity
{
    String statemntid = this.getClass().getName()+".query"+entity.getClass().getName();
    return getSqlMapTemplate().queryForList(statemntid,entity);
}


其它类同,这样一来要求命名空间的名字同DAO的名字一致,而statement的ID同entityObject的名字一致,不过多了前缀为query,select,insert,update等.

将如上代码放入DAO的超类中,这样我每一个DAO就不需要重复写这些功能雷同的代码!不知道有什么不合适之处.
0 请登录后投票
   发表时间:2007-02-14  
如果以上方案可行,可以考虑使用代码生成工具,在DB的数据结构确定后,直接生成entity model和SqlMap文件(包含select,query,update,delete)之类的几个statement声明,可以简化很多工作量!

当然这里涉及一个先有实体模型还是先有数据模型的问题!
0 请登录后投票
   发表时间:2007-02-14  
写一个service和DAO的基类不就成了吗,service中有一个BaseDAO的实例,service基类的save方法调用dao的save方法,
0 请登录后投票
   发表时间:2007-02-14  
xuni 写道
写一个service和DAO的基类不就成了吗,service中有一个BaseDAO的实例,service基类的save方法调用dao的save方法,
我一直以为Service层的接口声明应该是清晰,你这样所有的save,update,delete之类的参数都是Object类型的参数了!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics