读书人

利用反照机制实现的sql语句自动生成、

发布时间: 2012-09-02 21:00:34 作者: rapoo

利用反射机制实现的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 blocke.printStackTrace();System.out.println("IllegalArgumentException***类反射失败");} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("IllegalAccessException***类反射失败");} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.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 stubUsers 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);//1Map<String, Object> ma = new HashMap<String, Object>();ma.put("userName", "张三");ma.put("userPass", new Time(new Date().getTime()));String qsql = sf2.createQuerySql(ma);//2System.out.println(qsql);Object[] oo2 = sf2.getSqlParams();//3System.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));//testtestif(value==null){System.out.println("数据验证失败,检查实体类与数据表规范!");try {throw new Exception("数据验证失败,检查实体类与数据表规范!");} catch (Exception e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.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 实用性不强,但可以很好的理解反射机制

读书人网 >SQL Server

热点推荐