J2EE中DAO模式解析(一)

       为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装到一个公共的API中。也就是见了一个接口,接口中定义了此应用程序中将会用到的所有事务方法。当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口在逻辑上对应这个特定的数据存储。

 

       DAO模式是标准的j2ee设计模式之一。开发人员使用这个模式把底层的数据访问操作和上层的商务逻辑分开。一个典型的DAO实现有下列几个组件

1、  DAO工厂类

2、  一个DAO接口

3、  一个实现DAO接口的具体类

4、  数据传递对象

      我们要注意,DAO是事务性对象。每个被DAO执行的操作(对象创建、更新或删除数据)都是和事务相关联的。J2EE规范中为事务划分描述了两种模式:编程性事务和声明式事务

 

      举个例子来具体的看一下DAO模式的使用。添加分销商从jsp界面的添加到底层的流程

      我们从底层来进行介绍。首先,我们先通过读取xml文件的形式连接上数据库。

      存储数据库相关信息的sys-config.xml文件

      

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<db-info>
		<driver-name>oracle.jdbc.driver.OracleDriver</driver-name>
		<url>jdbc:oracle:thin:@localhost:1521:YANMEI</url>
		<user-name>drp1</user-name>
		<password>drp1</password>
	</db-info>
</config>

       读取得它的相关信息

/**
 * 采用单例模式解析sys-config.xml文件
 * @author pc
 *
 */
public class XmlConfigReader {
	/**
	//饿汉式
	private static XmlConfigReader instance=new XmlConfigReader();
	private XmlConfigReader()
	{}
	public static XmlConfigReader getInstance()
	{
		return instance;
	}
	*/
	//懒汉式(延迟加载)
	private JdbcConfig jdbcConfig=new JdbcConfig();
	
	//保存dao工厂的名称
	//key=名称,value=具体类完整路径
	private Map<String,String> daoFactoryMap=new HashMap();
	
	
	private static XmlConfigReader instance=null;
	private XmlConfigReader(){
		SAXReader reader=new SAXReader();
		InputStream in=Thread.currentThread().getContextClassLoader().getResourceAsStream("sys-config.xml");
		try {
		  Document doc= reader.read(in);
		  //取得jdbc相关配置信息
		  Element driverNameElt=(Element) doc.selectObject("/config/db-info/driver-name");
		  Element urlElt=(Element) doc.selectObject("/config/db-info/url");
		  Element userNameElt=(Element) doc.selectObject("/config/db-info/user-name");
		  Element passwordElt=(Element) doc.selectObject("/config/db-info/password");
		  //设置jdbc相关的配置
		  jdbcConfig.setDriverName(driverNameElt.getStringValue());
		  jdbcConfig.setUrl(urlElt.getStringValue());
		  jdbcConfig.setUserName(userNameElt.getStringValue());
		  jdbcConfig.setPassWord(passwordElt.getStringValue());
		  
		  System.out.println("读取jdbcConfig--》"+jdbcConfig);
		  //取得DaoFactory信息
		  List daoFactorylist=doc.selectNodes("/config/dao-factory/*");
		  for(int i=0;i<daoFactorylist.size();i++)
		  {
			  Element daoFactoryElt=(Element)daoFactorylist.get(i);
			  String tagName=daoFactoryElt.getName();
			  String tagText=daoFactoryElt.getText();
			  System.out.println("读取DaoFactory-->>"+tagText);
			  //放入到Map中
			  daoFactoryMap.put(tagName, tagText);
			  
		  }
		  
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static synchronized XmlConfigReader getInstance()
	{
		if(instance==null)
		{
			instance=new XmlConfigReader();
		}
		return instance;
	}
	/**
	 * 返回jdbc配置
	 * @return
	 */
	public JdbcConfig getJdbcConfig()
	{
		return jdbcConfig;
	}
	/**
	 * 根据标签名称取得DaoFactory的 名字
	 * @param name
	 * @return daoFactory的完整类路径
	 */
	public String getDaoFactory(String name)
	{
		return daoFactoryMap.get(name);
	}
	
}

        下面再看一下对Connection连接进行操作的类

/**
 * 采用ThreadLocal封装Connection
 * @author pc
 *
 */
public class ConnectionManager {
	private static ThreadLocal<Connection> connectionHolder=new ThreadLocal<Connection>();
	
	public static Connection getConnection()
	{
		Connection conn=connectionHolder.get();
		//如果在当前线程中没有绑定相应的Connection
		if(conn==null)
		{
			try
			{
				JdbcConfig jdbcConfig=XmlConfigReader.getInstance().getJdbcConfig();
				Class.forName(jdbcConfig.getDriverName());
				conn=DriverManager.getConnection(jdbcConfig.getUrl(),jdbcConfig.getUserName(),jdbcConfig.getPassWord());
				//将Connection设置到ThreadLocal
				connectionHolder.set(conn);
			}
			catch(ClassNotFoundException e)
			{
				e.printStackTrace();
				throw new ApplicationException("系统错误,请联系系统管理员");
			}catch(SQLException e)
			{
				e.printStackTrace();
				throw new ApplicationException("系统错误,请联系系统管理员");
			}
		}
		return conn;
	}
	
	public static void closeConnection()
	{
		Connection conn=connectionHolder.get();
		if(conn!=null)
		{
			try
			{
				conn.close();
				//从ThreadLocal中清楚Conection
				connectionHolder.remove();
			}catch(SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
	
	public static void close(Connection conn)
	{
		if(conn!=null)
		{
			try
			{
				conn.close();
			}catch(SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
	public static void close(Statement pstmt)
	{
		if(pstmt!=null)
		{
			try{
				pstmt.close();
			}catch(SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
	
	public static void close(ResultSet rs)
	{
		if(rs!=null)
		{
			try
			{
				rs.close();
			}catch(SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
	public static void beginTransaction(Connection conn)
	{
		try{
			if(conn!=null)
			{
				if(conn.getAutoCommit()){
					conn.setAutoCommit(false);  //手动提交
				}
			}
		}catch(SQLException e){}
	}
	public static void commitTransaction(Connection conn)
	{
		try{
			if(conn!=null)
			{
				if(!conn.getAutoCommit())
				{
					conn.commit();
				}
			}
		}catch(SQLException e)
		{}
	}		
		public static void rollbackTransaction(Connection conn)
		{
			try{
				if(conn!=null)
				{
					if(!conn.getAutoCommit())
					{
						conn.rollback();
					}
				}
			}catch(SQLException e){}
		}
}

        
         好了,到这里一些基本要用的信息就准备好了。下一篇看一下工厂的实现。

posted @ 2012-03-15 16:42  转航  阅读(383)  评论(0编辑  收藏  举报