2007-03-06

关于DAO设计的一个问题 (讨论)

关键字: Dao设计
假设有两个实体模型User 和 account .
那么在设计DAO的时候:
UserDAO里面放只涉及到User信息的数据库操作,AccountDAO里面放只涉及到Account的信息,
涉及到User和Account共同的信息全部放到UserAccountDAO里面.
不知道大家是怎么样设计的
评论
ASDF1982 2007-03-16
谢谢楼上的,
首先MVC只是个表示层模式而已
再次越是频繁变动的系统越应该分层,正因为分层了,引入了一些接口辅助模式,才不会改一处牵全身.
包括你说的开闭原则的理解也有问题哈,分层引入接口模式不正式为了符合开闭原则么?
你说的话完全反了,不太理解...

我的问题是怎样在jdbc的情况下没有Spring等容器,怎么设计实现spring所提供的事物管理 比如怎样设计自己 的组建!
giscat 2007-03-16
分层,MVC即可
至于其他的分层,设计的好,完全可以达到同样的效果

对于频繁变动,更不宜分层太多
一个修改,要去改N个地方,用struts/webwork/spring+hibernate/ibatis做系统的朋友肯定经历过
其实这样的架构,这样的设计不见得好
设计上有一个很重要的原则:扩展开放,修改封闭
一处修改,扩散污染到其他层(层次很深)的设计不见得好
水平方向的分层可细一些,垂直方向上的分层,要控制好层次
(绝不是越多越好)
MVC的垂直分层粒度已经比较适用了
ASDF1982 2007-03-16
java是语言,但考虑到java企业应用是面象规范的,考虑到不同的产品很多.分层隔离虽然有点繁琐,但是在大项目中的时候,需要很多人合作编程的时候,需求可能变动的时候,还是必要的.
giscat 2007-03-16
ASDF1982 写道
看不太明白楼上的代码,有几个问题呀
1.这里的Action是否和struts等框架的action一样起到控制流程的作用,如果是这样的话那不太好吧,数据库的操作不应该和ation发生关系吧
2. 在哪里用的代理?
3. connection的创键和销毁怎样做才能不和dao以及service绑死呢
(有没有什么办法能象spring那样教给容器处理),提供一个组建呢代替spring的事务控制



设计上是不合理,实践效果确很好

j2ee讲模式讲分层,理论上很上层次上境界
实战效果确输给ROR(这个东东可不管啥分层不分层的)

dao,service,action 呀,搞得一堆一堆
合久必分,分久必合
统统合并掉,啥烦恼都不会有了
唯一不能合的是mvc 三个部分分开(无论是物理上的还是逻辑上的分离)
维护性,扩展性自然而然就会上去
事情变得简单了,工作轻松了,质量上去了,成本下来了,票票进来了,老板也开心了

个人意见,仅供参考
ASDF1982 2007-03-16
看不太明白楼上的代码,有几个问题呀
1.这里的Action是否和struts等框架的action一样起到控制流程的作用,如果是这样的话那不太好吧,数据库的操作不应该和ation发生关系吧
2. 在哪里用的代理?
3. connection的创键和销毁怎样做才能不和dao以及service绑死呢
(有没有什么办法能象spring那样教给容器处理),提供一个组建呢代替spring的事务控制
giscat 2007-03-16
ASDF1982 写道
继续...connection采用从哪里创建 从哪里关闭!


可组合使用 command,template,proxy,decorator,filter,chain等设计模式

一个简单的实现思路,供参考 (可参考webwork,struts,spring等设计思路)
更具体的可参考上楼的上楼的俺的小破文,见笑拉

public class Action{
 Connection cn = null;

  public void preHandler(){

  }

  public void postHandler(){

  }

  public void exceptionHandler(Exception e){

  }


  Connection getConn(){
        
           if(cn==null){cn = DBUtil.getConn();}
  }

  
  void closeConn(){
            return DBUtil.close(cn);
  }

  public void run(){
           try{
             preHandler();
           getConn();
           execute();
           postHandler();
           }catch(Exception e){
              exceptionHandler(e);
           }finally{closeConn();}
  }

    public void execute(){
         
  }

}




public class BaseAction extends Action{

        //这里可实现 preHandler,postHadler,exceptionHandler   等方法  
          //连接获取和关闭由getConn()和closeConn()实现
}





           XAction extends BaseAction{

               //实现业务方法execute
        }




Action action = new XAction();
        action.run();

ASDF1982 2007-03-16
继续...connection采用从哪里创建 从哪里关闭!
weiqingfei 2007-03-15
ASDF1982 写道

目的二是:
用直接用jdbc操作数据库不采用第三方框架的时候(如Spring)大家是怎么控制事物的,connection是在哪里创建的
象我这个例子有什么不好么,应该怎么做好些呢?


java的开发我不是很清楚,.net里面,一般分为

表现层,facade层,业务逻辑层,数据访问层,后面就是sqlhelper一类用jdbc直接操作数据库。

一般,事务和连接都是在业务逻辑层创建,然后一层层向后传的。
giscat 2007-03-15
dao,service可以合并
dao,service,action也可以合并
connection的打开关闭操作可交给父类做

一个DIY的框架,供参考,献丑了

超级简单的mvc框架ajf(agile java framework)

http://www.javaeye.com/topic/38847
yiding_he 2007-03-15
从业务逻辑上看第一种方式比较自然。

jdbc 的数据库连接当然是从 DriverManager 得到的。处理事务的话,如果把 Connection 传来传去容易乱套,不传又影响了代码的重用,哈哈
ASDF1982 2007-03-06
写这个例子有两个目的:
目的一是:

是大家碰到象这样的一对多(一个User可以对应多过Account)或者
多对多的时候,会建例几个实体模型我想到两种方式
1.建立一个User对象,一个Account对象
user里面包含List accounts;
account里面包含 userId;
2.建立一个User对象,一个Account对象,
在建立一个UserAccount关联对象(里面包含所有的user对象和account对象的属性);

目的二是:
用直接用jdbc操作数据库不采用第三方框架的时候(如Spring)大家是怎么控制事物的,connection是在哪里创建的
象我这个例子有什么不好么,应该怎么做好些呢?
ASDF1982 2007-03-06
Client客户端调用程序

/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.client;
import com.java.service.UserService;
/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class Client 
{

	public static void main(String[] args)
	 {
	 	//定义用户Id
	 	int userId = 100;
	 	UserService userService = new UserService();
	 	userService.delUser(userId);
	 	
	}
}
ASDF1982 2007-03-06
DaoFactory
/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.dao;

import java.sql.Connection;

 

/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class DaoFactory 
{
   public static UserDAO getUserDAO(Connection connection)
   {
	return new UserDAOImpl(connection);
   	
   }
   public static AccountDAO getAccountDAO(Connection connection)
   {
   	 return new AccountDAOImpl(connection);
   }
}


UserService 类

/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import com.java.db.Account;
import com.java.db.User;
import com.java.dao.AccountDAO;
import com.java.dao.DaoFactory;
import com.java.dao.UserDAO;


/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class UserService 
{  
	private Connection connection;
	private Connection getConnection()
	{   
		//to-do  open a connection form the dbPool
		this.connection =null; 
		return connection;
	}
	public  User findUser(int userId)
	{   
		User user = null ;
		try
		{
		 getConnection();
		 UserDAO userDAO = DaoFactory.getUserDAO(this.connection);
		 user = userDAO.findUserById(userId);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try {
				connection.close();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		return user;
		 
	}
	public void delUser(int userId)
	{
		
				try
				{
				 getConnection();
				 connection.setAutoCommit(false);
				 
				 AccountDAO accountDao = DaoFactory.getAccountDAO(this.connection);
				 UserDAO userDao =DaoFactory.getUserDAO(this.connection);
				 List list = userDao.findAccountByUserId(userId);
				 int[] accounts = new int[list.size()]; 
				 for(int i = 0;i<list.size();i++)
				 {
				 	Account account =(Account)list.get(i);
				 	accounts[i]= account.getAccountId();
				 }
				 accountDao.batchDelAccount(accounts);
				 userDao.delUser(userId);
				 connection.commit();
				 
				}
				catch(Exception e)
				{
					e.printStackTrace();
					try 
					{
						connection.rollback();
					} catch (SQLException e1)
					 {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				finally
				{
					try 
					{
						connection.close();
					} catch (SQLException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				
	}

}
ASDF1982 2007-03-06
AccountDao


/*
* Created on Mar 6, 2007
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package com.java.dao;

import java.util.List;

import com.java.db.Account;
import com.java.db.User;

/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public interface AccountDAO 
{
   public int saveAccount(Account account)throws Exception;
   public boolean delAccount(int accountId)throws Exception;
   public void updateAccount(Account account)throws Exception;
   public Account findAccountByID(int id)throws Exception;
   public User findUserByAccountId(int accountId)throws Exception;
   public List findAllAccount()throws Exception;
   public boolean batchDelAccount(int[] accountId)throws Exception;
}



AccountDaoImpl


/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.dao;

import java.sql.Connection;
import java.util.List;

import com.java.db.Account;
import com.java.db.User;

/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class AccountDAOImpl implements AccountDAO {

	private Connection connection =null;
	public AccountDAOImpl(Connection connection) {
		this.connection =connection;
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#saveAccount(com.java.db.Account)
	 */
	public int saveAccount(Account account) {
		// TODO Auto-generated method stub
		return 0;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#delAccount(int)
	 */
	public boolean delAccount(int accountId) {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#updateAccount(com.java.db.Account)
	 */
	public void updateAccount(Account account) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#findAccountByID(int)
	 */
	public Account findAccountByID(int id) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#findUserByAccountId(int)
	 */
	public User findUserByAccountId(int accountId) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#findAllAccount()
	 */
	public List findAllAccount() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#batchDelAccount(int[])
	 */
	public boolean batchDelAccount(int[] accountId) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}

}


UserDAO 类

/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.dao;

import java.util.List;

import com.java.db.User;

/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public interface UserDAO 
{
	
	public int saveUser(User user)throws Exception;
	public boolean delUser(int userId) throws Exception;
	public void updateUser(User user) throws Exception;
	public User findUserById(int userId) throws Exception;
	public List findUserByName(String userName) throws Exception;
	public List findAllUser()throws Exception;
	public List findAccountByUserId(int userId)throws Exception;

}


UserDAOImpl类


/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.dao;

import java.sql.Connection;
import java.util.List;

import com.java.db.Account;
import com.java.db.User;

/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class AccountDAOImpl implements AccountDAO {

	private Connection connection =null;
	public AccountDAOImpl(Connection connection) {
		this.connection =connection;
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#saveAccount(com.java.db.Account)
	 */
	public int saveAccount(Account account) {
		// TODO Auto-generated method stub
		return 0;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#delAccount(int)
	 */
	public boolean delAccount(int accountId) {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#updateAccount(com.java.db.Account)
	 */
	public void updateAccount(Account account) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#findAccountByID(int)
	 */
	public Account findAccountByID(int id) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#findUserByAccountId(int)
	 */
	public User findUserByAccountId(int accountId) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#findAllAccount()
	 */
	public List findAllAccount() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.java.dao.AccountDAO#batchDelAccount(int[])
	 */
	public boolean batchDelAccount(int[] accountId) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}

}
ASDF1982 2007-03-06
User 类

	/*
	 * Created on Mar 6, 2007
	 *
	 * To change the template for this generated file go to
	 * Window>Preferences>Java>Code Generation>Code and Comments
	 */
	package com.java.db;
	
	import java.io.Serializable;
	
	/**
	 * @author asdf
	 *
	 * To change the template for this generated type comment go to
	 * Window>Preferences>Java>Code Generation>Code and Comments
	 */
	public class User implements Serializable 
	{
		
		private int userId;
		private String userName;
		private String firstName;
		private String lastName;
		private String nickName;
		private String email;
		
	}



Account类

/*
 * Created on Mar 6, 2007
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.java.db;

import java.io.Serializable;
import java.util.Date;

/**
 * @author asdf
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class Account implements Serializable 
{
	private int accountId;
	private int userId;
	private String accountType;
	private Date createDate;
	private Date updateDate;
	

}


省略get/set方法
ASDF1982 2007-03-06
包结构为
com.java.client
  Client.java
com.java.dao
  AccountDao.java
  AccountDaoImpl.java
  UserDao.java
  UserDaoImpl.java
  DaoFactory.java
com.java.db
  Account.java
  User.java
com.java.service
  UserService.java


************************************
ASDF1982 2007-03-06
一对多写了几行代码;改改吧
刑天战士 2007-03-06
涉及到共同的信息?难道User和Account是多对多的?不合常理阿?如果你指的是数据库方面的多个操作,应该写成Service
hgq0011 2007-03-06
方法:
1)在上面添加一个service层
2)直接在某个DAO中操作。
hgq0011 2007-03-06
方法:
1)在上面添加一个service层
2)直接在某个DAO中操作。
ASDF1982
搜索本博客
存档
最新评论
评论排行榜