当前位置: 代码迷 >> SQL >> 利用反照机制实现的sql语句自动生成、简化实体类封装
  详细解决方案

利用反照机制实现的sql语句自动生成、简化实体类封装

热度:76   发布时间:2016-05-05 13:56:47.0
利用反射机制实现的sql语句自动生成、简化实体类封装
现在所学的东西,有很多的共性。Dao层对于臃肿,很多都是ctrl+c和ctrl+v 完成的,这种事情纯粹就是苦力代码。利用双周的时间,用反射机制实现了sql自动生成,简化list封装。

大家看看还有什么需要改进的地方吧。

sql工具类
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Time;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;public class SqlFactory {	/**	 * @author fule	 * @param args	 *            反射工具类 自动生成sql 语句 和参数赋值 实体类中含有id字样的只能唯一	 *            对外接口 对象 语句类型 查询参数Map<String,object>字段名 字段值	 *            	 *            如果是查询操作,构造方法传入一个jvm初始化的对象实体,生成语句时调用createQuerySql(map ma)方法 	 *            Map<String,object>字段名 字段值	 *            	 *            其他操作,构造方法传入一个具体对象实体,生成语句时调用createUpdateSql(String type)方法	 *            type为update delete insert 的字符串	 */	/** 需自动化的对象 **/	private Object obj;		/** 生成的sql语句 **/	private String sql;	/** 参数值 **/	private List objParam = new ArrayList();	/** 保存对象的属性名和属性值 **/	private Map<String, Object> paramMap = new HashMap<String, Object>();		public SqlFactory(Object obj){		/**		 * 构造方法		 * 自动加载load		 */		try {			this.obj=obj;			load(obj);		} catch (IllegalArgumentException e) {			// TODO Auto-generated catch block			e.printStackTrace();			System.out.println("IllegalArgumentException***类反射失败");		} catch (IllegalAccessException e) {			// TODO Auto-generated catch block			e.printStackTrace();			System.out.println("IllegalAccessException***类反射失败");		} catch (InvocationTargetException e) {			// TODO Auto-generated catch block			e.printStackTrace();			System.out.println("InvocationTargetException***类反射失败");		}	}		@SuppressWarnings("unchecked")	private void load(Object obj) throws IllegalArgumentException,			IllegalAccessException, InvocationTargetException {		/**		 * 获得属性名称和值的集合		 * 		 */		Class c = obj.getClass();		Method[] methods = c.getMethods();		for (Method m : methods) {						String mName = m.getName();			if (mName.startsWith("get") && !mName.startsWith("getClass")) {				String fieldName = mName.substring(3, mName.length());								Object value = m.invoke(obj, null);				if (value instanceof String) {					paramMap.put(fieldName, "\"" + value + "\"");				} else {					paramMap.put(fieldName, value);				}			}		}	}	public Object[] getSqlParams() {		/**		 * 参数值		 */		return objParam.toArray();	}	@SuppressWarnings("unchecked")	public String createQuerySql(Map<String,Object> map){		/**		 * 查询单表记录的sql		 * map 数据表的字段名 与值 		 * 不支持分组与多表		 */		Class c = obj.getClass();		String tableName = c.getSimpleName();		String sql="select * from "+tableName;		if(map!=null){			StringBuffer strb = new StringBuffer("select * from "+tableName+" where 1=1");			Set<String> set = map.keySet();			Object[] keys = set.toArray();			int len = keys.length;			for (int i = 0; i < len; i++) {				strb.append(" and "+keys[i]+"=?");				objParam.add(map.get(keys[i]));//将值加入到参数			}			sql = strb.toString();		}		return sql;	}		@SuppressWarnings("unchecked")	public String createUpdateSql(String type) {		/**		 * createUpdateSql 自动生成添删改的SQL语句 		 * 表中 字段名只能有一个包含id的字段		 * @param obj 对象		 * @param type 传递过来的操作类型 delete update insert		 * @return String		 */		Class c = obj.getClass();		String tableName = c.getSimpleName();		StringBuffer strb = new StringBuffer();		Set<String> set = paramMap.keySet();		Object[] keys = set.toArray();		int len = keys.length;		if ("insert".compareToIgnoreCase(type)==0) {			strb.append("insert into " + tableName + "(");			for (int i = 0; i < len; i++) {				if (i < len - 1) {					strb.append(keys[i]);					objParam.add(paramMap.get(keys[i]));					strb.append(",");				} else {					strb.append(keys[i]);					objParam.add(paramMap.get(keys[i]));					strb.append(") values(");				}			}			for (int i = 0; i < len; i++) {				if (i < len - 1) {					strb.append("?" + ",");				} else {					strb.append("?" + ")");				}			}		}		if ("delete".compareToIgnoreCase(type)==0) {			strb.append("delete from " + tableName);			for (int i = 0; i < len; i++) {				if (((String) keys[i]).contains("id")						|| ((String) keys[i]).contains("Id")) {					strb.append(" where " + keys[i] + "=?");					objParam.add(paramMap.get(keys[i]));				}			}		}		if ("update".compareToIgnoreCase(type)==0) {			strb.append("update " + tableName + " ");			for (int i = 0; i < len; i++) {				if (i < len - 1) {					strb.append("set" + keys[i] + "=?");					objParam.add(paramMap.get(keys[i]));					strb.append(",");				} else {					strb.append("set" + keys[i] + "=?");					objParam.add(paramMap.get(keys[i]));				}			}			for (int i = 0; i < len; i++) {				if (((String) keys[i]).contains("id")						|| ((String) keys[i]).contains("Id")) {					strb.append(" where " + keys[i] + "=?");					objParam.add(paramMap.get(keys[i]));				}			}		}		sql = strb.toString();		return sql;	}			/**	 * Test	 * 	 * @param args	 */	public static void main(String[] args) {		// TODO Auto-generated method stub		Users te = new Users();		te.setName("张三");		te.setPass("123456");		te.setId(123);		te.setBir(new Time(new Date().getTime()));		System.out.println("********添删改********");		SqlFactory sf = new SqlFactory(te);		String sql = sf.createUpdateSql("delete");		Object[] oo = sf.getSqlParams();		System.out.println(sql);		System.out.println(Arrays.toString(oo));				System.out.println("********查询********");		SqlFactory sf2 = new SqlFactory(te);//1		Map<String, Object> ma = new HashMap<String, Object>();		ma.put("userName", "张三");		ma.put("userPass", new Time(new Date().getTime()));		String qsql = sf2.createQuerySql(ma);//2		System.out.println(qsql);		Object[] oo2 = sf2.getSqlParams();//3		System.out.println(Arrays.toString(oo2));						String sstr = "setUid";		System.out.println(sstr.substring(3));	}}class Users {	private String name;	private String pass;	private int id;	private Time Bir;	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public Time getBir() {		return Bir;	}	public void setBir(Time bir) {		Bir = bir;	}	public String getPass() {		return pass;	}	public void setPass(String pass) {		this.pass = pass;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public Users() {}}


反射工具类:ReflecTionUtil
package com.util;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import java.util.SortedMap;import javax.servlet.jsp.jstl.sql.Result;import com.entity.Nr_users;public class ReflecTionUtil {	/**	 * @author fule	 * 反射工具类 	 * 封装数据结果到集合	 * 传入result 实体和 实体类具体url	 */	private String[] classMethods = new String[20];// set方法数组	private Class[] classParams = new Class[20];// set方法参数类型	private int classMethodsNum = 0;// 实体类属性个数	private Class cs = null;// 会话管理器	private List list = null;// 实体类属性字段名的集合	public void getStandardManager(String url) throws ClassNotFoundException {		cs = Class.forName(url);	}	public void getProtect(String url) throws ClassNotFoundException {		// 实体类变量字段		list = new ArrayList();		this.getStandardManager(url);		Field[] fields = cs.getDeclaredFields();		for (int i = 0; i < fields.length; i++) {			list.add(fields[i].getName());		}	}	public void getConsructor(String url) throws ClassNotFoundException {		// set方法和参数类型		this.getStandardManager(url);		Method[] methods = cs.getMethods();		int count = 0;		for (Method m : methods) {			if (m.getName().substring(0, 3).equals("set")) {				Class[] parms = m.getParameterTypes();				classMethods[count] = m.getName();				classParams[count] = parms[0];//				count++;			}		}		classMethodsNum = count;	}	public Object getObject(String url) throws SecurityException,			NoSuchMethodException, ClassNotFoundException,			IllegalArgumentException, InstantiationException,			IllegalAccessException, InvocationTargetException {		/**		 * 创建类对象		 */		this.getStandardManager(url);		Constructor constructor = cs.getConstructor();		Object  object = constructor.newInstance();                return object;	}	public Result checkResult(Result rs) {		/**		 * 验证数据库中的数据		 */		for (int i = 0; i < rs.getRowCount(); i++) {			SortedMap map = rs.getRows()[i];			for (int j = 0; j < list.size(); j++) {				Object value = map.get(list.get(j));//testtest				if(value==null){					System.out.println("数据验证失败,检查实体类与数据表规范!");					try {						throw new Exception("数据验证失败,检查实体类与数据表规范!");					} catch (Exception e) {						// TODO Auto-generated catch block						e.printStackTrace();					}					}else{					map.put(list.get(j), value);				}			}		}		return rs;	}	public List getValue(String url, Result rs) {		/**		 * list列表  value		 */		List resultlist = new ArrayList();		try {						this.getConsructor(url);			this.getProtect(url);			rs = checkResult(rs);			for (int i = 0; i < rs.getRowCount(); i++) {                            Object object = this.getObject(url);				for (int j = 0; j < classMethodsNum; j++) {					Method method = cs.getMethod(classMethods[j],							classParams[j]);										//System.out.println("当前调用set方法:"+method);										//System.out.println("表字段名:"+classMethods[j]					//	.substring(3).toLowerCase());//表字段名					String tstr = classMethods[j]					   						.substring(3).toLowerCase();										///System.out.println("表字段值:"+rs.getRows()[i].get(tstr));														//表字段值					method.invoke(object, rs.getRows()[i].get(tstr));//动态设值					//System.out.println((Nr_users)object);				}				resultlist.add(object);			}		} catch (SecurityException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (IllegalArgumentException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (NoSuchMethodException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (ClassNotFoundException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (InstantiationException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (IllegalAccessException e) {			// TODO Auto-generated catch block			e.printStackTrace();		} catch (InvocationTargetException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return resultlist;	}}
1 楼 apple0668 2012-04-23  
链表查询可以做到么?
2 楼 shiren1118 2012-04-23  
没啥大意义,反射慎用啊,如果需要的话可以考虑grails的orm
3 楼 tangjunjun1986 2012-04-23  
性能!!!!!
4 楼 yjingzeming 2012-04-23  
String tableName = c.getSimpleName();
String sql="select * from "+tableName;
这样子强迫对象名和表名字相同感觉有点不人性呀,对于一个表名字为T_WEBSERVICE_ORGANIZATIO的pojo类名也为这个的让我情何以堪?
再加个构造器
//表名称
public String tblname;
public SqlFactory(String tblname){
       this.tblname = tblname;
}
这样子是否可以?
5 楼 cfan_haifeng 2012-04-23  
更多的是使用代码生成器,连同jsp、dao、service、pojo、action都搞出来
6 楼 lohasle 2012-04-23  
yjingzeming 写道
String tableName = c.getSimpleName();
String sql="select * from "+tableName;
这样子强迫对象名和表名字相同感觉有点不人性呀,对于一个表名字为T_WEBSERVICE_ORGANIZATIO的pojo类名也为这个的让我情何以堪?
再加个构造器
//表名称
public String tblname;
public SqlFactory(String tblname){
       this.tblname = tblname;
}
这样子是否可以?

嗯,受用。
7 楼 jyjava 2012-04-23  
其实应该都是单表的操作,或者像ibates那样生成链表的javaBean结果
8 楼 allan_chan 2012-04-25  
实用性不强,但可以很好的理解反射机制
  相关解决方案