`
lohasle
  • 浏览: 254792 次
社区版块
存档分类
最新评论

利用反射机制实现的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;
	}
}

3
5
分享到:
评论
8 楼 allan_chan 2012-04-25  
实用性不强,但可以很好的理解反射机制
7 楼 jyjava 2012-04-23  
其实应该都是单表的操作,或者像ibates那样生成链表的javaBean结果
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;
}
这样子是否可以?

嗯,受用。
5 楼 cfan_haifeng 2012-04-23  
更多的是使用代码生成器,连同jsp、dao、service、pojo、action都搞出来
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;
}
这样子是否可以?
3 楼 tangjunjun1986 2012-04-23  
性能!!!!!
2 楼 shiren1118 2012-04-23  
没啥大意义,反射慎用啊,如果需要的话可以考虑grails的orm
1 楼 apple0668 2012-04-23  
链表查询可以做到么?

相关推荐

    C#封装MySql数据库操作,反射动态生成SQL语句

    C#封装MySql数据库操作,反射动态生成SQL语句。看程序前,最好请先看看里面的“数据库说明”文档,不然可能会一头雾水。 这是我第一次写数据库的程序,我知道有很多地方写得不好,希望能得到大家的指点。我的联系...

    自动生成SQL语句_C#_sql_

    总结,自动生成SQL语句在C#开发中是一项实用的技术,可以帮助我们简化数据库操作,提高代码的可读性和维护性。无论是使用ORM框架如Entity Framework,轻量级库如Dapper,还是手工构造或利用辅助库,都有其适用的场景...

    根据SQLServer数据表生成C#实体类。生成数据库模型.zip

    2. 生成C#实体类:使用提供的工具或源码,通过连接到SQLServer数据库,读取表结构信息,自动生成C#类。这些类通常会包含公共属性,对应数据库表的字段,以及可能的getter和setter方法。 3. SQLHelper类:这是一个...

    多数据库支持、自动生成实体类和SQL语句的工具1.3.6版 最新版

    标题中的“多数据库支持、自动生成实体类和SQL语句的工具1.3.6版 最新版”指的是一款能够跨多种数据库系统工作的开发工具,它具有自动化代码生成的功能,特别是针对实体类和SQL查询语句。这个版本是1.3.6,可能是对...

    多数据库支持、自动生成实体类和SQL语句的工具1.3.5版 最新版

    标题中的“多数据库支持、自动生成实体类和SQL语句的工具1.3.5版 最新版”指的是一款能够跨多种数据库系统工作的开发工具,它具有自动化生成实体类和SQL查询语句的功能。这样的工具在软件开发中非常实用,可以极大地...

    泛型封装的sql语句

    在`SqlExecutor&lt;T&gt;`类中,我们可以使用反射来动态构建SQL语句,根据实体类`T`的属性生成对应的INSERT、UPDATE、DELETE等SQL语句。例如,对于INSERT操作,我们可以遍历`T`的所有公开属性,生成`SET`子句,然后结合...

    .net 自动生成实体类、DAO工具

    在.NET开发环境中,自动生成实体类和DAO(Data Access Object)是提高开发效率的重要手段,尤其是在处理大量数据库交互时。这个".net 自动生成实体类、DAO工具"是一个实用的小型工具,能够帮助开发者快速构建数据...

    C#实现实体类自动生成(源代码)

    本文将详细介绍如何使用C#和ADO.NET来实现实体类的自动生成,以及两种不同的实现方法:一种基于SQL语句,另一种不依赖SQL。 1. ADO.NET基础 ADO.NET是.NET Framework的一部分,它提供了与数据库交互的全面解决方案...

    C# .net数据库表实体类生成,一键生成数据库所有表的实体类

    总的来说,通过创建一个C# .NET项目,利用ADO.NET和EF Core的概念,我们可以构建一个数据库表实体类代码生成器,以满足开发中的自动化需求。这个工具不仅可以提高开发效率,而且在处理大量表或频繁更改数据库结构时...

    myeclipse 自动生成DAO层,实体类,mybatis 实体映射文件

    MyEclipse作为一款强大的Java集成开发环境,提供了丰富的功能,其中包括自动生成DAO层、实体类以及MyBatis的实体映射文件。这样的自动化工具可以帮助开发者节省大量手动编写代码的时间,减少错误,并保持代码的一致...

    一个DELPHI的ORM类设计工具,可以自动生成实体类

    1. **简化数据库操作**:通过自动生成的实体类,开发者可以使用面向对象的方式来操作数据库,无需编写大量手动的SQL语句。 2. **提高代码质量**:ORM工具通常会处理事务管理、错误处理等细节,使代码更简洁,减少了...

    qt 封装的类 表根据字段名和值 生成sql语句

    为了在C++中封装一个类来生成这样的SQL语句,我们可以创建一个名为`CSqlFile`的类,该类包含以下核心方法: 1. `initTableInfo(std::string tableName)`: 初始化表信息,包括表名。 2. `addInsertField(std::string...

    create-springbootjava自动实体类生成包含pojo,papper;service和实体类).zip

    手动创建这些类可能会消耗大量时间,因此,"create-springbootjava自动实体类生成"工具应运而生,它能帮助开发者快速生成这些必备的类。 该压缩包"create-springbootjava自动实体类生成包含pojo,papper;service和...

    Sql Server 生成实体类

    本文将围绕“Sql Server 生成实体类”的主题展开,深入探讨如何通过SQL语句自动生成实体类,以及这一过程背后的逻辑和技术细节。 ### 一、理解实体类与数据库映射 实体类是面向对象编程中的一种设计模式,主要用于...

    mybatis自动生成实体类及实体类映射文件

    MBG是MyBatis官方提供的一个代码生成工具,它可以自动生成Java实体类、Mapper接口和XML映射文件,甚至可以生成DAO接口和实现类。这样,我们就不需要手动编写这些重复性高的代码,从而节省了大量时间。 1. **配置MBG...

    (带源码)根据MS SQLServer数据库信息生成C#或JAVA实体类DEMO

    标题中的"(带源码)根据MS SQLServer数据库信息生成C#或JAVA实体类DEMO"表明这是一个编程示例,展示了如何从Microsoft SQL Server数据库中获取结构信息,并自动生成C#或Java的实体类代码。这样的工具在开发过程中非常...

    实体类,实体操作类,存储过程 代码自动生成工具

    "实体类,实体操作类,存储过程 代码自动生成工具"正是一种这样的解决方案,它旨在帮助开发者快速生成与数据库交互所需的代码,包括对实体对象的封装、操作这些实体的类以及数据库的存储过程。 实体类(Entity ...

    ssm框架自动生成实体类及dao,mapper

    SSM框架,全称为Spring、SpringMVC和MyBatis的组合,...综上所述,这个主题主要涉及了如何在SSM框架下利用自动化工具,根据数据库表结构自动生成实体类、DAO接口以及Mapper XML文件,从而简化开发工作,提高开发效率。

    SSM框架生成java实体类xml映射文件jar包

    标题中的"SSM框架生成java实体类xml映射文件jar包",指的是在SSM框架下,利用某种工具或方法自动生成Java实体类(Entity Class)和对应的XML映射文件,这些文件是MyBatis框架进行数据操作的基础。实体类是Java对象,...

    C#根据模型动态生成SQL和DBHelper

    此外,可以利用Linq-to-SQL或Entity Framework等ORM(对象关系映射)工具,根据实体模型自动生成SQL语句,简化数据库交互。 二、Entity Framework(EF) Entity Framework是微软提供的一个开源ORM框架,它允许...

Global site tag (gtag.js) - Google Analytics