`
yiding_he
  • 浏览: 448193 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

DAO 设计2、查询方式的设计

阅读更多
创建了一个 <dao-config><datasource><connection>DAO 类用来做所有的事情,包括查询。查询方法如下:

</connection></datasource></dao-config>
java 代码
  1. public List query(Class clazz, String sql, List params) throws DAOException;  

第一个参数是用来接受封装的类。
有时候仅查询一个字段,根本不用封装:
java 代码
  1. public List query(String sql, List params) throws DAOException; 

如果封装,就要考虑查询结果字段到对象属性的映射关系。根据公司的数据库设计规范,单词之间用下划线连起来。所以简单的替换一下就可以了。比如 USER_NAME 字段<dao-config><datasource><connection>就映射到 userName 属性。

如果查询结果中的字段有多,那这个字段的值就只好丢弃;如果类的属性有多,也不会给它赋值。




分页查询。有时候会用到分页查询,所以添加了一个方法:
</connection></datasource></dao-config>
java 代码
  1. public Page queryPage(Class clazz, String sql, List params, int pageIndex, int pageSize)  
  2.             throws DAOException;  

Page 对象除了包含查询结果外还有 totalNum 属性,表示查询总结果数。




表格封装的查询。有时候查询语句是动态生成的,没法确定查询结果的字段个数,用类来封装显然不合适。于是定义了一个通用的表格结构用来封装,并添加了 queryTable() <dao-config><datasource><connection>方法: </connection></datasource></dao-config>
java 代码
 
  1. public DataTable queryTable(String sql) throws DAOException;   
  2. public DataTable queryTable(String sql, List params, int pageIndex, int pageSize)     
  3.                  throws DAOException;   

DataTable 对象包含的其实就是一堆 HashMap。不过它同 Page 一样有一个查询总结果数,而且添加了一些方法方便提取数据。这种查询的使用方式如下:
java 代码
 
  1. DAO dao = DAO.getDAO(SOURCE_NAME);  
  2. DataTable table = dao.queryTable("select * from tt_test");  
  3. assertEquals(6, table.getColumns());  
  4. Map row = table.query("name""张三丰"); // 在查询结果中搜索  
  5. assertNotNull(row);  




静态字段作为映射关系配置。有些字典表或配置表,一开始就被全部读入并缓存起来。为了少写代码,DAO 提供将静态字段 TN 作为表名来查询的方式。如果类中存在 String 类型的静态字段 TN,则可以使用这个方法:
java 代码
 
  1. public List query(Class clazz) throws DAOException; 
<dao-config><datasource><connection></datasource></dao-config>
分享到:
评论
7 楼 weiqingfei 2007-08-24  
yiding_he 写道
确实可以这样像 pdw2009 兄这样写,如果不考虑事务的话。另外要注意的是,不要出现“rownum”或“from dual”这样的耦合于特定数据库的语句。虽然我在 dao 里面写了只一个 OraDbExecutor 类,但实际上 dao 在 MySql 下也能很好的使用。


事务应该在上一次考虑呀,dao不管这事。
6 楼 yiding_he 2007-08-24  
确实可以这样像 pdw2009 兄这样写,如果不考虑事务的话。另外要注意的是,不要出现“rownum”或“from dual”这样的耦合于特定数据库的语句。虽然我在 dao 里面写了只一个 OraDbExecutor 类,但实际上 dao 在 MySql 下也能很好的使用。
5 楼 pdw2009 2007-08-23  
这是一个DAO常用操作的封装,使用起来是非常方便
4 楼 pdw2009 2007-08-23  

package com.scitel.gdnumcommon.utils;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.scitel.gdnumcommon.entity.Pagination;
import com.scitel.gdnumcommon.entity.BaseVO;

public class BaseDAO {
	private static final Log log = LogFactory.getLog(BaseDAO.class);

	/**
	 * 保存数据,新建和修改都用这个
	 *
	 * @param con
	 * @param SQL
	 * @param params
	 * @throws Exception
	 * @author 
	 */
	public void save(Connection con, String SQL, List params)
			throws Exception {
		PreparedStatement ps = null;
		try {
			ps = con.prepareStatement(SQL);
			if (SQL == null) {
				throw new Exception();
			}

			if (params != null && params.size() > 0) {
				int count = 0;
				for (Iterator iterator = params.iterator(); iterator.hasNext(); count++) {
					Object object = iterator.next();
					setObjectValue(ps, count + 1, object);
				}
			}
			ps.executeUpdate();
		} catch (Exception e) {
			log.error(e);
			throw e;
		} finally {
			try{
				if(ps != null) {
					ps.close();
				}
			}catch(Exception e){

			}
		}
	}

	/**
	 * 保存数据,新建和修改都用这个,通过字段名称匹配类型
	 * @param con
	 * @param SQL
	 * @param voclass
	 * @param paramMap
	 * @throws Exception
	 * @author 
	 */
	public void save(Connection con, String SQL, Class voclass, Map paramMap)
			throws Exception {
		PreparedStatement ps = null;
		try {
			ps = con.prepareStatement(SQL);
			if (SQL == null) {
				throw new Exception();
			}

			if (paramMap != null && paramMap.size() > 0) {
				int count = 0;
				for (Iterator iterator = paramMap.keySet().iterator(); iterator.hasNext(); count++) {

					String key = (String)iterator.next();
					Object object = paramMap.get(key);
					setObjectValue(ps, voclass, count+1, key, object);
				}
			}
			ps.executeUpdate();
		} catch (Exception e) {
			log.error(e);
			throw e;
		} finally {
			try{
				if(ps != null) {
					ps.close();
				}
			}catch(Exception e){

			}
		}
	}

	/**
	 * 删除数据
	 *
	 * @param con
	 * @param SQL
	 * @param params
	 * @throws Exception
	 * @author 
	 */
	public void remove(Connection con, String SQL, List params)
			throws Exception {
		PreparedStatement ps = null;
		try {
			ps = con.prepareStatement(SQL);
			if (SQL == null) {
				throw new Exception();
			}
			if (params != null && params.size() > 0) {
				int count = 0;
				for (Iterator iterator = params.iterator(); iterator.hasNext(); count++) {
					Object object = iterator.next();
					setObjectValue(ps, count + 1, object);
				}
			}
			ps.executeUpdate();
		} catch (Exception e) {
			log.error(e);
			throw e;
		} finally {
			try{
				if(ps != null) {
					ps.close();
				}
			}catch(Exception e){

			}
		}
	}

	/**
	 * 根据ID选择数据
	 *
	 * @param con
	 * @param SQL
	 * @param id
	 * @param voclass
	 * @return
	 * @throws Exception
	 * @author 
	 */
	public BaseVO selectById(Connection con, String SQL, String id,
			Class voclass) throws Exception {
		Object po = null; // 承载值对象
		PreparedStatement ps = null;
		ResultSet rs = null;
		ResultSetMetaData rsm = null;
		try {
			ps = con.prepareStatement(SQL);
			if (SQL == null) {
				throw new Exception();
			}

			ps.setString(1, id);

			rs = ps.executeQuery();
			rsm = rs.getMetaData();
			if (rs.next()) {
				Map entity = new HashMap();
				for (int i = 1; i <= rsm.getColumnCount(); i++) {
					String columnName = rsm.getColumnName(i).toLowerCase();
					Object columnValue = getObjectValue(rs, voclass, i, columnName);
					entity.put(columnName, columnValue);
				}
				if (voclass != null) {
					po = voclass.newInstance();
					BeanUtils.populate(po, entity);
				}
				 
			}
		} catch (Exception e) {
			log.error(e);
			throw e;
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
			} catch (Exception e) {

			}
			try {
				if (ps != null) {
					ps.close();
				}
			} catch (Exception e) {

			}
		}
		return (BaseVO) po;
	}

	/**
	 * 选择记录,不分页
	 * @param con
	 * @param SQL
	 * @param params
	 * @param voclass
	 * @return
	 * @throws Exception
	 * @author 
	 */
	public List select(Connection con, String SQL, List params, Class voclass)
			throws Exception {
		Object vo = null; // 承载值对象
		PreparedStatement ps = null;
		ResultSet rs = null;
		ResultSetMetaData rsm = null;
		List relist = null;
		try {
			ps = con.prepareStatement(SQL);
			if (SQL == null) {
				throw new Exception();
			}
			if (params != null && params.size() > 0) {
				int count = 0;
				for (Iterator iterator = params.iterator(); iterator.hasNext(); count++) {
					Object object = iterator.next();
					setObjectValue(ps, count + 1, object);
				}
			}
			rs = ps.executeQuery();
			rsm = rs.getMetaData();
			relist = new ArrayList();
			while (rs.next()) {
				Map entity = new HashMap();
				for (int i = 1; i <= rsm.getColumnCount(); i++) {
					String columnName = rsm.getColumnName(i).toLowerCase();
					Object columnValue = getObjectValue(rs, voclass, i, columnName);
					entity.put(columnName, columnValue);
					
				}
				if (voclass != null) {
					vo = voclass.newInstance();
					BeanUtils.populate(vo, entity);
					relist.add(vo);
				} else {
					relist.add(entity);
				}
			}
		} catch (Exception e) {
			log.error(e);
			throw e;
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
			} catch (Exception e) {

			}
			try {
				if (ps != null) {
					ps.close();
				}
			} catch (Exception e) {

			}
			
		}
		return relist;
	}

	/**
	 * 分页查询
	 *
	 * @param con
	 * @param SQL
	 * @param params
	 * @param voclass
	 * @param pagination
	 * @return
	 * @throws Exception
	 * @author 
	 */
	public List selectPagination(Connection con, String SQL, List params,
			Class voclass, Pagination pagination) throws Exception {
		if (SQL == null) {
			throw new NullPointerException("SQL不能为空!");
		}
		if (pagination == null) {
			throw new NullPointerException("分页类不能为空!");
		}

		// TODO Auto-generated method stub
		Object vo = null; // 承载值对象
		PreparedStatement ps = null;
		ResultSet rs = null;
		ResultSetMetaData rsm = null;
		List relist = null;
		try {

			ps = con.prepareStatement("select count(1) as count_ from ( " + SQL + " )");

			if (params != null && params.size() > 0) {
				int count = 0;
				for (Iterator iterator = params.iterator(); iterator.hasNext(); count++) {
					Object object = iterator.next();
					setObjectValue(ps, count + 1, object);
				}
			}

			rs = ps.executeQuery();
			if (rs.next()) {
				pagination.setTotalCount(rs.getInt(1));
				
			}
			

			if (pagination.getTotalCount() > 0) {
				/* 组成分页内容 */
				StringBuffer pagingSelect = new StringBuffer(100);
				pagingSelect
						.append("select * from ( select row_.*, rownum rownum_ from ( ");
				pagingSelect.append(SQL);
				pagingSelect
						.append(" ) row_ where rownum <= ?) where rownum_ > ?");

				ps = con.prepareStatement(pagingSelect.toString());
				int count = 0;
				if (params != null && params.size() > 0) {
					for (Iterator iterator = params.iterator(); iterator.hasNext(); count++) {
						Object object = iterator.next();
						setObjectValue(ps, count + 1, object);
					}
				}
				
				ps.setInt(count + 1, pagination.getPage()
						* pagination.getCount());
				ps.setInt(count + 2, (pagination.getPage() - 1)
						* pagination.getCount());

				log.info("pagination.getPage():" + pagination.getPage());
				log.info("pagination.getCount():" + pagination.getCount());
				rs = ps.executeQuery();
				rsm = rs.getMetaData();
				relist = new ArrayList();
				while (rs.next()) {
					Map entity = new HashMap();
					for (int i = 1; i <= rsm.getColumnCount(); i++) {
						String columnName = rsm.getColumnName(i).toLowerCase();
						Object columnValue = getObjectValue(rs, voclass, i, columnName);
						entity.put(columnName, columnValue);
					}
					if (voclass != null) {
						vo = voclass.newInstance();
						BeanUtils.populate(vo, entity);
						relist.add(vo);
					} else {
						relist.add(entity);
					}
				}
			}
		} catch (Exception e) {
			log.error(e);
			throw e;
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
			} catch (Exception e) {

			}
			try {
				if (ps != null) {
					ps.close();
				}
			} catch (Exception e) {

			}

		}
		return relist;
	}

	/**
	 * 获得SequenceValue
	 * @param sequenceName
	 * @return
	 * @throws Exception
	 * @author 
	 */
	public Long getSequenceValue(Connection con, String sequenceName)throws Exception {
		PreparedStatement ps = null;
		ResultSet rs = null;
		Long sequenceValue = null;
		try{
			ps = con.prepareStatement("select " + sequenceName + ".nextval from dual");
			rs = ps.executeQuery();
			if(rs.next()) {
				sequenceValue = new Long(rs.getLong(1));
			}
		}catch(Exception e){
			log.error(e);
			throw e;
		}finally{
			try {
				if (rs != null) {
					rs.close();
				}
			} catch (Exception e) {

			}
			try {
				if (ps != null) {
					ps.close();
				}
			} catch (Exception e) {

			}
		}
		return sequenceValue;
	}
	/**
	 * 把对象传入数据库
	 * @param ps
	 * @param count
	 * @param object
	 * @author 
	 */
	private final void setObjectValue(PreparedStatement ps, int count, Object object) throws Exception {
		log.debug("count is " + count + " object is " + object);
		if(object != null) {
			if(object instanceof Integer){
				ps.setInt(count, ((Integer)object).intValue());
			}else if(object instanceof Long) {
				ps.setLong(count, ((Long)object).longValue());
			}else if(object instanceof BigDecimal){
				ps.setBigDecimal(count, (BigDecimal)object);
			}else if(object instanceof String){
				ps.setString(count, (String)object);
			}else if(object instanceof java.util.Date) {
				if(object!=null){
					long time = ((java.util.Date)object).getTime();
					ps.setDate(count, new java.sql.Date(time));
				}else{
					ps.setDate(count, null);
				}
			}else{
				ps.setObject(count, object);
			}
		}else{
			ps.setNull(count, Types.INTEGER);
		}
	}

	/**
	 * 把对象传入数据库
	 * @param ps
	 * @param clazz
	 * @param count
	 * @param columnName
	 * @param object
	 * @throws Exception
	 * @author 
	 */
	private final void setObjectValue(PreparedStatement ps, Class clazz, int count,
			String columnName, Object object)throws Exception {
		log.debug("count is " + count + " columnName is " + columnName + " object is " + object);
		String classType = clazz.getDeclaredField(columnName).getType().getName();
		if(classType.equals("java.lang.Integer")){
			if(object != null) {
				ps.setInt(count, ((Integer)object).intValue());
			}else{
				ps.setNull(count, Types.INTEGER);
			}
		}else if(classType.equals("java.lang.Long")) {
			if(object != null ) {
				ps.setLong(count, ((Long)object).longValue());
			}else{
				ps.setNull(count, Types.INTEGER);
			}
		}else if(classType.equals("java.math.BigDecimal")){
			if(object != null) {
				ps.setBigDecimal(count, (BigDecimal)object);
			}else{
				ps.setNull(count, Types.NUMERIC);
			}
		}else if(classType.equals("java.lang.String")){
			if(object != null) {
				ps.setString(count, (String)object);
			}else{
				ps.setString(count, null);
			}
		}else if(classType.equals("java.util.Date")) {
			if(object!=null){
				long time = ((java.util.Date)object).getTime();
				ps.setDate(count, new java.sql.Date(time));
			}else{
				ps.setDate(count, null);
			}
		}else{
			ps.setObject(count, object);
		}
	}

	/**
	 * 把数据从数据取出来
	 * @param rs
	 * @param clazz
	 * @param count
	 * @param columnName
	 * @return
	 * @throws Exception
	 * @author 
	 */
	private final Object getObjectValue(ResultSet rs, Class clazz, int count, String columnName) throws Exception {
		Object fieldValue = null;
		log.debug("columnName is " + columnName + " count is " + count);
		if(columnName != null) {
			if("rownum".equals(columnName)) {
				fieldValue = new Long(rs.getLong(count));
			}else if("rownum_".equals(columnName)) {
				fieldValue = new Long(rs.getLong(count));
			}else if("count_".equals(columnName)) {
				fieldValue = new Long(rs.getLong(count));
			}else{
				String classType = clazz.getDeclaredField(columnName).getType().getName();

				if(classType.equals("java.lang.Integer")){
					fieldValue =new Integer( rs.getInt(count));
				}else if(classType.equals("java.lang.Long")) {
					fieldValue =new Long( rs.getLong(count));
				}else if(classType.equals("java.math.BigDecimal")){
					fieldValue = rs.getBigDecimal(count);
				}else if(classType.equals("java.lang.String")){
					fieldValue = rs.getString(count);
				}else if(classType.equals("java.util.Date")) {
					java.sql.Date date = rs.getDate(count);
					if(date!= null){
						fieldValue = new java.util.Date(date.getTime());
					}
				}else{
					fieldValue = rs.getString(count);
				}
			}
		}
		return fieldValue;
	}


}

3 楼 yiding_he 2007-03-28  
Annotation 确实是个好东西,可惜我们的项目目前没有打算升级到 java 5.0 的迹象。ADO.net 几乎是一个离线的数据库,十分全面而且庞大,要模仿它我还没那个本事。特别是并发控制,我竭力避免同这种东西打交道。
2 楼 zealic 2007-03-28  
照此深入下去
就是 .Net 中的 ADO.Net(OO版) 了

不错,Java 中的重复太多了
垄断和自由都有其优势和劣势

希望以后的什么框架多用 Annotation
1 楼 hagensas 2007-03-28  
我认为这不是一个dao,而是一个dataadpter

相关推荐

    DAO设计模式 DAO 设计模式 JAVA设计模式

    DAO(Data Access Object)设计模式是软件开发中一种常见的用于处理数据访问的模式,它将业务逻辑与数据访问逻辑分离,使得代码结构更加...因此,深入理解并灵活运用DAO设计模式对于提升Java应用程序的质量至关重要。

    Dao设计模式教程

    2. **DAO设计模式的优点** - **解耦**:DAO模式分离了数据访问逻辑和业务逻辑,使得两部分可以独立开发和维护。 - **可测试性**:通过使用模拟的DAO对象,可以在不依赖真实数据库的情况下进行单元测试。 - **灵活...

    DAO设计模式辅助资料

    下面,我们将深入探讨DAO设计模式的核心概念、实现方式以及它在实际开发中的应用。 DAO设计模式的基本思想是为数据库操作创建一个独立的接口,这个接口称为DAO接口。通过这个接口,业务层可以调用各种数据访问方法...

    李兴华 DAO设计模式 实现 增删改查 分页查询 完整代码

    在这个“李兴华 DAO设计模式 实现 增删改查 分页查询 完整代码”项目中,我们将探讨DAO模式如何应用于实现数据库的CRUD(创建、读取、更新、删除)操作以及分页查询。 1. DAO设计模式基础: DAO设计模式的核心是...

    DAO设计模式(工厂+代理)

    在这个“DAO设计模式(工厂+代理)”的例子中,我们将探讨如何结合工厂模式和代理模式来实现更灵活、更易于维护的DAO层。 首先,让我们理解DAO的基本概念。DAO是一个接口或抽象类,定义了对数据库进行操作的方法,...

    DAO设计模式

    ### DAO设计模式的实现方式 1. **JDBC DAO**:直接使用JDBC API实现,手动处理SQL和结果集映射。 2. **ORM框架**:如Hibernate、MyBatis,它们简化了SQL操作,提供了更高级的特性,如对象关系映射、缓存等。 3. **...

    基于DAO设计模式的新闻发布系统

    9. 性能优化:DAO设计模式可以通过缓存策略、批处理操作、连接池等方式提高系统性能。例如,使用 Ehcache 或 Redis 进行数据缓存,减少对数据库的频繁访问。 10. 故障处理:DAO层应当包含异常处理机制,当数据库...

    dao设计模式视频教程

    在本"DAO设计模式视频教程"中,你将深入理解这种模式的核心概念、应用场景以及实现方式。 DAO模式的主要目标是创建一个独立于数据库访问的接口层,使得业务对象可以不直接与数据库进行交互,而是通过调用DAO对象的...

    J2EE之DAO设计模式

    DAO设计模式可以通过采用抽象工厂和工厂方法模式来变得非常的灵活. 当底层数据存储实现不需要发生改变时,该策略可以使用工厂方法设计模式实现,来产生应用中所需的DAO. 当底层数据储存实现不得不发生变化的时候, ...

    Dao设计模式

    DAO设计模式是Java开发中常用的一种数据访问模式,它将底层数据访问操作与上层业务逻辑相分离。这一模式的目的在于封装所有对数据源的访问,并提供抽象接口,使得业务逻辑层与数据访问层解耦,从而降低业务代码与...

    struts2 dao 原理与设计方案

    Struts2 DAO(数据访问对象)原理与设计方案是构建企业级Java应用中不可或缺的一部分,它主要负责处理数据的持久化,即将Java对象存入数据库、文件或XML文档等持久存储介质。DAO的主要目的是将数据访问的逻辑从业务...

    Java Dao设计模式操作数据库

    Java DAO(Data Access Object)设计模式是一种常用的软件设计模式,用于在Java应用程序中与数据库进行交互。DAO模式的主要目的是为了实现数据访问层的隔离,它将业务逻辑与数据存储细节分离开来,使得代码更加模块...

    李兴华DAO设计模式

    在描述的课程中,李兴华先生讲解了DAO设计模式,并通过实例分析来阐述如何在业务层和服务层之间进行交互。例如,业务层可能需要实现以下功能: 1. 新雇员增加:业务层首先检查雇员编号是否已存在(调用数据层的查询...

    J2EE学习笔记--DAO设计模式基础.txt

    ### J2EE学习笔记——DAO设计模式基础 #### 一、引言 在J2EE(Java 2 Enterprise Edition)开发中,DAO (Data Access Object) 设计模式是一种常用的数据访问层实现方式,用于分离业务逻辑与数据访问逻辑,使得程序...

    JSP+Servlet+AJAX的dao设计模式

    **JSP+Servlet+AJAX DAO设计模式详解** 在Web开发中,DAO(Data Access Object)设计模式是一种常用的设计模式,用于将业务逻辑与数据访问层进行解耦,提高代码的可维护性和可复用性。本篇我们将深入探讨如何在JSP...

    DAO设计模式精讲(java web开发)

    DAO设计模式的核心是创建一个接口,该接口定义了对数据库进行操作的方法,如查询、插入、更新和删除等。然后,为这个接口提供具体的实现类,这些实现类会包含与数据库交互的细节。这样,业务层代码只需要与DAO接口...

    DAO设计模式设计一个论坛

    2. 主题DAO(TopicDAO):管理论坛的主题,包括创建主题、查询主题、更新主题状态等。例如,`createTopic(Topic topic)`用于创建新主题,`getTopicsByCategory(int categoryId)`用于按类别获取主题列表。 3. 帖子...

    DAO设计模式Demo

    总结来说,DAO设计模式是软件工程中用于处理数据访问的重要模式,它提高了代码的可复用性和可维护性,同时通过接口隔离了业务逻辑和数据操作的细节。在Java开发中,DAO模式常常结合JDBC或其他ORM框架实现,以实现对...

Global site tag (gtag.js) - Google Analytics