zoukankan      html  css  js  c++  java
  • Java反射结合JDBC写的一个通用DAO

    以前写反射只是用在了与设计模式的结合上,并没有考虑到反射可以与DAO结合。也是一个偶然的机会,被正在上培训的老师点到这个问题,才考虑到这个可能性,于是上网参考各种代码,然后自己动手开发了一个通用DAO。

    大家除学JDBC时,也会有这种感触,一般写的DAO只能用在一张表上,不能通用,如果你的程序有多张表,就需要写多个DAO,或者使用一些复杂设计来达到这个目的。而这个反射方式实现的DAO,就不需要很复杂的设计,就可以实现DAO的通用。


    这个通用是有前提的,就是DAO接受的参数必须是绝对符合JavaBean标准的对象。而且JavaBean的属性类型,必须跟数据库中表的数据类型保持一致。否则就会出问题,下面贴出代码,写得不好,别见怪


    package com.sldll.cms.dao;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    //0oO
    public class GeneralDAO {
    
    	//---------------------------------查询部分--------------------------------------------------------------------------
    	/**
    	 * 查询所有记录
    	 * @param obj	表对应的JavaBean对象
    	 * @return		所有记录构成的list
    	 * @throws Exception
    	 */
    	public List<Object> findAll(Object obj) throws Exception {
    
    		List<Object> list = new ArrayList<Object>();
    		ResultSet rs = null;
    		try {
    
    			// 获取数据库连接
    			Statement stmt = DBConnectionManager.getConnection()
    					.createStatement();
    			// 构建sql语句
    			String tableName = obj.getClass().getName();
    			tableName = tableName.substring(tableName.lastIndexOf(".") + 1);
    			String sql = "select * from " + tableName;
    
    			// 执行sql语句
    			rs = stmt.executeQuery(sql);
    
    			while (rs.next()) {
    				list.add(createObj(rs, obj));
    			}
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw e;
    		} finally {
    			// 关闭连接
    			if (rs != null) {
    				rs.close();
    			}
    			DBConnectionManager.closeConnection();
    		}
    
    		return list;
    	}
    
    	/**
    	 * 对指定的表执行指定的sql查询语句
    	 * @param obj
    	 * 			以该表对应的JavaBean对象决定表
    	 * @param query
    	 * 			要对该表执行的sql语句
    	 * @return
    	 * @throws Exception
    	 */
    	public List<Object> findByNameQuery(Object obj, String query) throws Exception {
    		// TODO Auto-generated method stub
    		List<Object> list = null;
    		try {
    			Statement sql_statement = DBConnectionManager.getConnection()
    					.createStatement();
    			//执行传递的sql语句
    			ResultSet rs = sql_statement.executeQuery(query);
    			list = new ArrayList<Object>();
    			if (rs != null) {
    				while (rs.next()) {
    					list.add(createObj(rs, obj));
    				}
    			}
    			return list;
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw e;
    		} finally {
    			DBConnectionManager.closeConnection();
    		}
    
    	}
    
    	/**
    	 * 按条件对指定表进行查询
    	 * @param obj
    	 * 		以该表对应的JavaBean对象决定表
    	 * @param condition
    	 * 		查询的条件,key:条件		value:值
    	 * @param isFuzzzy
    	 *		是否支持模糊查询
    	 * @return
    	 * @throws Exception
    	 */
    	public List<Object> findByNameQuery(Object obj, Map<Object,Object> condition,boolean isFuzzy) throws Exception {
    		List<Object> list = new ArrayList<Object>();
    		try {
    			
    			String tablename = getTableName(obj);
    			StringBuilder sb = new StringBuilder("select * from " + tablename);
    			PreparedStatement state = null;
    			if(isFuzzy){
    				addFuzzyConditionString(sb, condition);
    			}
    			else{
    				addConditionString(sb, condition);
    			}
    			state = DBConnectionManager.getConnection().prepareStatement(sb.toString());
    			state = setSqlValue(state, condition,isFuzzy);
    			ResultSet rs = state.executeQuery();
    			if (rs != null) {
    				while (rs.next()) {
    					list.add(createObj(rs, obj));
    				}
    			}
    			return list;
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw e;
    		} finally {
    			DBConnectionManager.closeConnection();
    		}
    	}
    
    
    
    	//-------------------------------------创建部分--------------------------------------------------------------------------
    	/**
    	 * 在数据库里新建一条记录
    	 * @param obj
    	 * 		描述记录的对象,必须是数据库中某张表对应的JavaBean对象
    	 * @return
    	 * 		新建成功返回真,否则返回假
    	 * @throws Exception
    	 */
    	public boolean create(Object obj) throws Exception{
    		// 获取数据库连接
    		try {
    			// 构建sql语句
    			Map<Object, Object> map = getObjectFieldValue(obj);
    			String tableName = obj.getClass().getName();
    			tableName = tableName.substring(tableName.lastIndexOf(".") + 1);
    			StringBuilder sb = new StringBuilder("insert into " + tableName);
    			addCreateString(sb, map);
    			PreparedStatement  stmt = DBConnectionManager.getConnection()
    					.prepareStatement(sb.toString());
    			setSqlValue(stmt, map,false);
    			int count = stmt.executeUpdate();
    			if(count>0){
    				return true;
    			}
    			else{
    				return false;
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw e;
    		} finally {
    			DBConnectionManager.closeConnection();
    		}
    	}
    
    	//-------------------------------------删除部分----------------------------------------------------------------------------
    	/**
    	 * 删除表中所有记录
    	 * @param obj
    	 * 			JavaBean对象,决定要删除的是哪张表
    	 * @return
    	 * 			删除成功返回真,否则返回假
    	 */
    	public boolean deleteAll(Object obj) throws Exception{
    		String delete_sql = "delete from "+getTableName(obj);
    		PreparedStatement pstmt;
    		try {
    			pstmt = DBConnectionManager.getConnection().prepareStatement(delete_sql);
    			int count = pstmt.executeUpdate();
    			if(count>0){
    				return true;
    			}
    			else{
    				return false;
    			}
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw e;
    		}
    		finally{
    			DBConnectionManager.closeConnection();
    		}
    		
    	}
    	
    	/**
    	 * 在指定表中删除给定ID的记录
    	 * @param obj
    	 * 		表示要删除的表
    	 * @param condition
    	 * 		删除的条件 key:字段(一般为字符串) value:值
    	 * @return
    	 */
    	public boolean delete(Object obj,Map<Object,Object> condition) throws Exception{
    		//构建sql语句
    		StringBuilder sb = new StringBuilder("delete from "+getTableName(obj));
    		addConditionString(sb, condition);
    		try {
    			PreparedStatement pstmt = DBConnectionManager.getConnection().prepareStatement(sb.toString());
    			setSqlValue(pstmt, condition,false);
    			int count = pstmt.executeUpdate();
    			if(count > 0){
    				return true;
    			}
    			else{
    				return false;
    			}
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw e;
    		}
    		finally{
    			DBConnectionManager.closeConnection();
    		}
    	}
    	
    	//-------------------------------------更新部分----------------------------------------------------------------------------
    	/**
    	 * 更新指定表的记录
    	 * @param obj
    	 * 		用来确定表的Java对象
    	 * @param map
    	 * 		要设置的字段值,key:字段(字符串),value:值
    	 * @param condition
    	 * 		筛选条件
    	 * @return
    	 */
    	public boolean update(Object obj,Map<Object,Object> map,Map<Object, Object>condition) throws Exception {
    		StringBuilder sb = new StringBuilder("update "+getTableName(obj));
    		addSetString(sb,map);
    		addConditionString(sb, condition);
    		try {
    			PreparedStatement pstmt = DBConnectionManager.getConnection().prepareStatement(sb.toString());
    			List<Object> values =  new ArrayList<Object>();
    			getValuesToList(values,map);
    			getValuesToList(values, condition);
    			setSqlValue(pstmt, values);
    
    			int count = pstmt.executeUpdate();
    			if(count > 0){
    				return true;
    			}
    			else{
    				return false;
    			}
    		} catch ( Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw e;
    		}
    		finally{
    			DBConnectionManager.closeConnection();
    		}
    	}
    
    	private List<Object> getValuesToList(List<Object> values,Map<Object, Object> map) {
    		
    		for (Iterator<Object> it = map.keySet().iterator(); it.hasNext();) {
    			Object value =  map.get(it.next());
    			values.add(value);
    		}
    		return values;
    	}
    	
    	
    
    
    	/**
    	 * 获取JavaBean对象的字段值放到容器中
    	 * @param obj
    	 * 			JavaBean对象
    	 * @return
    	 * @throws IllegalAccessException
    	 * @throws InvocationTargetException
    	 */
    	private Map<Object, Object> getObjectFieldValue(Object obj)
    			throws IllegalAccessException, InvocationTargetException {
    		Map<Object, Object> map = new HashMap<Object,Object>();
    		
    		Field fields[] = obj.getClass().getFields();
    		Method methods[] = obj.getClass().getMethods();
    
    		// 给字段设置值
    		for (int i = 0; i < fields.length; i++) {
    			// 用字段的名字构建set方法的名字
    			String fieldName = fields[i].getName();
    			
    			String methodName = "get" + fieldName.substring(0, 1).toUpperCase()
    					+ fieldName.substring(1);
    
    			// 查找对应的方法
    			Method method = null;
    			for (int j = 0; j < methods.length; j++) {
    				if (methods[j].getName().equals(methodName)) {
    					method = methods[j];
    					break;
    				}
    			}
    			// 如果存在这个方法
    			if (method != null) {
    				// 开始执行方法,获取当前的JavaBean对象字段值
    				Object value = method.invoke(obj, new Object[] { });
    				map.put(fieldName, value);
    			}
    		}
    		return map;
    	}
    	
    	private void addSetString(StringBuilder sb, Map<Object, Object> map) {
    		// TODO Auto-generated method stub
    		if (!map.isEmpty()) {
    			sb.append(" set ");
    			for (Iterator<Object> it = map.keySet().iterator(); it.hasNext();) {
    				String key = (String) it.next();
    				if (null == key) {
    					continue;
    				}
    				sb.append(key+"=?,");				
    			}
    			sb.deleteCharAt(sb.lastIndexOf(","));
    			System.out.println(sb.toString());
    		}
    	}
    	
    	/**
    	 * 在现有sql创建语句后面追加字段名和占位符
    	 * @param sb
    	 * @param map
    	 */
    	private void addCreateString(StringBuilder sb,Map<Object, Object> map) {
    		// TODO Auto-generated method stub
    		sb.append("(");
    		int count = 0;
    		for (Iterator<Object> it = map.keySet().iterator(); it.hasNext();) {
    			String key = (String) it.next();
    			if (null == key) {
    				continue;
    			}
    			sb.append(key + ",");
    			count++;
    		}
    		sb.deleteCharAt(sb.lastIndexOf(","));
    		sb.append(") values(");
    		for (int i = 0; i < count; i++) {
    			sb.append("?,");
    		}
    		sb.deleteCharAt(sb.lastIndexOf(","));
    		sb.append(")");
    		System.out.println(sb.toString());
    	}
    
    	/**
    	 * 在现有sql查询语句后面追加判断条件
    	 * @param sb  			where之前的sql         
    	 * @param condition 	条件(key:字段名;value:值)       
    	 * @return	使用占位符的sql语句
    	 */
    	private String addConditionString(StringBuilder sb, Map<Object,Object> condition) {
    		if (!condition.isEmpty()) {
    			sb.append(" where ");
    			int i = 0;
    
    			for (Iterator<Object> it = condition.keySet().iterator(); it.hasNext();) {
    				String key = (String) it.next();
    				if (null == key) {
    					continue;
    				}
    				if (i != 0) {
    					sb.append(" and ");
    				}
    				if (key.indexOf("<") != -1 || key.indexOf(">") != -1
    						|| key.indexOf("=") != -1) {
    					sb.append(key + "?");
    				} else {
    					sb.append(key + "=" + "?");
    				}
    
    				i++;
    
    			}
    
    		}
    		System.out.println(sb.toString());
    		return sb.toString();
    	}
    	
    	private String addFuzzyConditionString(StringBuilder sb,Map<Object,Object>condition) {
    		if (!condition.isEmpty()) {
    			sb.append(" where ");
    			int i = 0;
    
    			for (Iterator<Object> it = condition.keySet().iterator(); it.hasNext();) {
    				String key = (String) it.next();
    				if (null == key) {
    					continue;
    				}
    				if (i != 0) {
    					sb.append(" or ");
    				}
    				sb.append(key + " like " +"?");
    				i++;
    			}
    
    		}
    		System.out.println(sb.toString());
    		return sb.toString();
    	}
    	
    	
    	/**
    	 * 设置现有sql语句的占位符的值
    	 * @param state
    	 * @param map
    	 * @return
    	 * @throws SQLException
    	 */
    	private PreparedStatement setSqlValue(PreparedStatement state, Map<Object,Object> map,boolean isFuzzy)
    			throws SQLException {
    		if (!map.isEmpty()) {
    			int i = 1;
    			for (Iterator<Object> it = map.keySet().iterator(); it.hasNext();) {
    				Object value = map.get(it.next());
    				if(isFuzzy){
    					state.setObject(i++, "%"+value+"%");
    				}else{
    					state.setObject(i++, value);
    				}
    			}
    
    		}
    		return state;
    	}
    	private PreparedStatement setSqlValue(PreparedStatement state, List<Object> values)
    			throws SQLException {
    		if (!values.isEmpty()) {
    			int i = 1;
    			for (Iterator<Object> it = values.iterator(); it.hasNext();) {
    				Object value = it.next();
    				state.setObject(i++, value);
    			}
    			
    		}
    		return state;
    	}
    	
    	private String getTableName(Object obj) {
    		String tablename = obj.getClass().getName();
    		tablename = tablename.substring(tablename.lastIndexOf(".") + 1);
    		return tablename;
    	}
    	// 利用反射构建对象
    	
    	private Object createObj(ResultSet rs, Object obj)
    			throws  Exception {
    		// TODO Auto-generated method stub
    		Object object = obj.getClass().newInstance();
    		// 获取字段
    		Field fields[] = obj.getClass().getFields();
    		// 获取方法
    		Method methods[] = obj.getClass().getMethods();
    
    		// 给字段设置值
    		for (int i = 0; i < fields.length; i++) {
    			// 用字段的名字构建set方法的名字
    			String fieldName = fields[i].getName();
    			String methodName = "set" + fieldName.substring(0, 1).toUpperCase()
    					+ fieldName.substring(1);
    
    			// 查找对应的方法
    			Method method = null;
    			for (int j = 0; j < methods.length; j++) {
    				if (methods[j].getName().equals(methodName)) {
    					method = methods[j];
    					break;
    				}
    			}
    
    			// 如果存在这个方法
    			if (method != null) {
    				// 开始执行方法,为当前的JavaBean对象字段设置值
    				Object value = rs.getObject(fieldName);
    				method.invoke(object, new Object[] { value });
    
    			}
    		}
    		return object;
    	}
    	
    	
    }
    




  • 相关阅读:
    PHP中include和require的区别详解
    CCNP
    PHP内存缓存功能memcached
    NumPy数据的归一化
    Python计算美国总统的身高并实现数据可视化
    NumPy实现数据的聚合,计算最大值,最小值
    Python通用函数实现数组计算
    Python当中的array数组对象
    人工智能之神经科学——探索脑:高尔基染色
    Android开发:getSupportFragmentManager()不可用
  • 原文地址:https://www.cnblogs.com/lvyahui/p/4009961.html
Copyright © 2011-2022 走看看