论坛首页 Java企业应用论坛

自己写的简单框架模型,模仿hibernate和mybatis

浏览 2623 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-01-13   最后修改:2012-01-13

之前发了以个HQLModel(HQL语句生成器)觉得意义不大。最近对数据库操作很感兴趣。



这几天在公司偷懒,写了一个小玩具。就是想模仿hibernate和mybatis做一个框架实现ORM。

由于技术和时间有限,暂时写到了一对多查询和SQL自动生成,where条件设置,

但是没有考虑到between and  in left join 这些关键字。


东西其实很简单,就是希望能得到指教,因为我对反省和反射还不是很了解,而且硬编码的能力也欠缺太多。

目前只完成了查询功能。


使用的时候配置两个文件,然后对应类写上主键注解,还有一对多(只完成了查询)


希望有兴趣的朋友能一起完成这个小玩意。

下面是效果图.

下面是测试代码

import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.List;

import com.leaves.dao.connection.CollectionConfig;
import com.leaves.dao.exceptions.getClassPropException;
import com.leaves.dao.util.ExeSQLOneAndMany;
import com.leaves.model.TaskReport;
import com.leaves.model.WeekReport;

public class TestMain {
	public static void main(String[] args) throws IllegalArgumentException, SQLException, IntrospectionException,
			IllegalAccessException, InvocationTargetException, getClassPropException {

//		testQuery();
		testManyQuery();
	}

	/** 
	* 
	*void 
	*/
	private static void testManyQuery() {
		
		CollectionConfig collectionConfig = new CollectionConfig(CollectionConfig.ORACLE_NAME);
		ExeSQLOneAndMany<WeekReport> jadbConnection = new ExeSQLOneAndMany<WeekReport>(collectionConfig);
		WeekReport weekReport= new WeekReport();
//		weekReport.setWeekreportid(136);
		List<WeekReport> weekReportList = jadbConnection.exeQueryByPage(weekReport, false, false, 0, 5);
		
		
		for (WeekReport weekReport2 : weekReportList) {
			System.out.println(weekReport2);
			for (TaskReport taskReport : weekReport2.getTaskreports()) {
				System.out.println(taskReport);
			}
		}
	}

	/**
	 * 测试单个查询
	 * 
	 * void
	 */
	private static void testQuery() {
		CollectionConfig collectionConfig = new CollectionConfig(CollectionConfig.ORACLE_NAME);

		ExeSQLOneAndMany<TaskReport> jadbConnection = new ExeSQLOneAndMany<TaskReport>(collectionConfig);
		TaskReport taskreport = new TaskReport();
		taskreport.setUserid(107);
		taskreport.setFtpAddress("清扬测");
		List<TaskReport> taskReportList = jadbConnection.exeQueryByPage(taskreport, true, true, 1, 5);
		// List<TaskReport> taskReportList = jadbConnection.exeQuery(taskreport,
		// false, false);

		for (TaskReport taskReport2 : taskReportList) {
			System.out.println(taskReport2);
		}
		System.out.println("--------------------------------");
	}

}

 




使用的时候要在src目录下创建两个配置文件。

如图


内容是配置数据库属性和配置类对应表的属性

oracledriver=oracle.jdbc.driver.OracleDriver
oracleurl=jdbc:oracle:thin:@192.168.1.2:1521:orcl
oracleusername=test
oraclepassword=test


mysqldriver=com.mysql.jdbc.Driver
mysqlurl=jdbc:mysql://127.0.0.1:3306/file
mysqlusername=root
mysqlpassword=admin

 

com.leaves.model.TaskReport=TASK_REPORT
com.leaves.model.TaskReport.reportid=REPORTID
com.leaves.model.TaskReport.taskid=TASKID
com.leaves.model.TaskReport.startTime=START_TIME
com.leaves.model.TaskReport.userid=USERID
com.leaves.model.TaskReport.hours=HOURS
com.leaves.model.TaskReport.actualHours=ACTUAL_HOURS
com.leaves.model.TaskReport.cent=CENT
com.leaves.model.TaskReport.codeLine=CODE_LINE
com.leaves.model.TaskReport.ftpAddress=FTP_ADDRESS
com.leaves.model.TaskReport.weekReportId=WEEK_REPORTID

com.leaves.model.WeekReport=WEEK_REPORT
com.leaves.model.WeekReport.weekreportid=WEEKREPORTID
com.leaves.model.WeekReport.userid=USERID

 

注解和异常还有常量类我就不贴出了。下面贴出核心的sql语句构建器还有辅助工具类和执行器

package com.leaves.dao.connection;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 
 * <b>JDBCCollection说明:</b> <br>
 * 此类有一个带有一个String类型参数的构造方法,用来接收一个字符串作为所连接数据库的标识。并加载驱动<br>
 * 
 * @author leaves叶知泉
 * @version 1.0
 * @since 2012-1-12 上午9:26:16
 */
public class CollectionManager {
	
	
	
	/**
	 * 根据数据库名称实例化。
	 * 
	 * @param databaseName
	 *            数据库名
	 */
	public CollectionManager(CollectionConfig collectionConfig) {
		Properties prop = new Properties();
		String dbName=collectionConfig.getDbName();
		InputStream is;
		File propFile = null;
		try {
			propFile= new File("src/connectionConfig.properties");
			is = new FileInputStream(propFile);
			prop.load(is);
			is.close();
			driver = prop.getProperty(dbName + "driver");
			url = prop.getProperty(dbName + "url");
			username = prop.getProperty(dbName + "username");
			password = prop.getProperty(dbName + "password");
		} catch (Exception e) {
			System.err.println("打开属性文件失败,目标文件路径(相对):"+propFile.getPath());
		}
		try {
			Class.forName(driver).newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获得一个与数据库的链接。
	 * 
	 * @return Connection 与数据库建立的连接
	 * @see java.sql.Connection
	 */
	public Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, username, password);
		} catch (Exception ee) {
			ee.printStackTrace();
		}
		if (conn == null) {
			System.err.println("警告: DriverManager.getConnection() 获得数据库链接失败.\r\n\r\n链接类型:" + driver + "\r\n链接位置:" + url
					+ "\r\n用户/密码" + username + "/" + password);
		}
		return conn;
	}

	/**
	 * 关闭所有连接,并且提交,捕获异常,不打印内容。
	 */
	public void closeAndCommitQuietly() {
		try {
			conn.commit();
		} catch (SQLException e1) {
		}
		closeAll();
	}

	/**
	 * 关闭所有连接,并且回滚,捕获异常,不打印内容。
	 */
	public void closeAndRollBackQuiet() {
		try {
			conn.rollback();
		} catch (SQLException e1) {
		}
		closeAll();
	}

	/**
	 * 关闭所有连接,捕获异常,不打印内容。
	 */
	public void closeAll() {
		try {
			if (rs != null)
				rs.close();
			if (prestmt != null)
				prestmt.close();
			if (stmt != null)
				stmt.close();
			if (conn != null)
				conn.close();
		} catch (Exception e) {
		}
	}

	private String driver;
	private String url;
	private String username;
	private String password;

	protected Connection conn = null;
	protected ResultSet rs = null;
	protected PreparedStatement prestmt = null;
	protected Statement stmt = null;

}

 

package com.leaves.dao.connection;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.leaves.dao.exceptions.ClassTypeAndStatementException;
import com.leaves.dao.util.ClassPropUtil;

/**
 * 
 * <b>StatementConnection说明:</b> <br>
 * 专门构建查询sql语句的类.也就是对PreparedStatement类或者Statement类进行操作
 * 
 * @author leaves叶知泉
 * @version 1.0
 * @since 2012-1-12 上午9:58:30
 * @see java.sql.Statement
 * @see java.sql.PreparedStatement
 */
public class QueryStatementCreater extends CollectionManager {
	/**
	 * 使用过的参数列表,用来debug。
	 */
	private List<String> paramsList = new ArrayList<String>();

	public QueryStatementCreater(CollectionConfig collectionConfig) {
		super(collectionConfig);
	}

	/**
	 * 获取预编译语句执行器
	 * 
	 * @param theSQL
	 *            需要执行的sql语句
	 * @param classPropUtil
	 *            类信息
	 * @return PreparedStatement 预编译语句执行器
	 */
	public PreparedStatement getStatement(String theSQL, ClassPropUtil classPropUtil, boolean likeSel) {
		conn = getConnection();
		System.out.printf("准备执行的sql语句====>%s\n", theSQL);
		try {
			prestmt = conn.prepareStatement(theSQL);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		setPropsForPrepareStatement(classPropUtil, likeSel);
		System.out.println("所传入参数是:====>" + paramsList);
		return prestmt;
	}

	/**
	 * 
	 * @Title: createWhereStatements 构建where条件语句
	 * @param likeSel
	 *            是否开启模糊查询
	 * @param classPropUtil
	 *            封装类信息的工具类
	 * @return StringBuffer 构建好的where条件的的缓冲区,如果没有任何where条件,返回null
	 */
	public StringBuffer createWhereSQL(boolean likeSel, ClassPropUtil classPropUtil) {
		StringBuffer whereSQLBuff = new StringBuffer();

		Map<String, String> columnNameMap = classPropUtil.getColumnNameMap();

		whereSQLBuff.append(" ");
		whereSQLBuff.append("WHERE");
		whereSQLBuff.append(" ");

		for (Field field : classPropUtil.getFields()) {
			String fieldName = field.getName();
			Object objTemp = classPropUtil.getValueByField(field);

			if (objTemp == null)
				continue;

			if (objTemp.getClass().equals(String.class)) {
				if (likeSel) {
					whereSQLBuff.append(columnNameMap.get(fieldName) + " like ?");
					whereSQLBuff.append(" AND ");
				} else {
					whereSQLBuff.append(columnNameMap.get(fieldName) + "=?");
					whereSQLBuff.append(" AND ");
				}
			} else {
				whereSQLBuff.append(columnNameMap.get(fieldName) + "=?");
				whereSQLBuff.append(" AND ");
			}
		}

		if (whereSQLBuff.toString().endsWith("AND "))
			whereSQLBuff.delete(whereSQLBuff.lastIndexOf(" AND "), whereSQLBuff.length() - 1);

		if (whereSQLBuff.toString().endsWith("WHERE "))
			return null;
		return whereSQLBuff;
	}

	/**
	 * 
	 * @Title: createsqlHead 创建查询语句头部信息,会带有rownum字段,如果是分页查询,会添加分页需要的前缀
	 * @param classPropUtil
	 *            封装了类型信息的工具类
	 * @param isByNotNulFieldl
	 *            是否根据空字段构建查询语句
	 * @param headModel
	 *            增删改查的标志头信息
	 * @param isByPage
	 *            是否分页
	 * @return StringBuffer 构建好的sql语句,到达from tableName
	 */
	protected StringBuffer createHeadSQL(ClassPropUtil classPropUtil, boolean isByNotNulField, String headModel,
			boolean isByPage) {
		StringBuffer headSQLBuf = new StringBuffer();
		Map<String, String> columnNameMap = classPropUtil.getColumnNameMap();

		StringBuffer headSQL = new StringBuffer(headModel);
		headSQL.append(" ");
		headSQL.append("ROWNUM AS RN ");

		StringBuffer columnSQL = new StringBuffer();
		for (Field field : classPropUtil.getFields()) {

			if (isByNotNulField)
				if (classPropUtil.getValueByField(field) == null)
					continue;

			String fieldName = field.getName();

			String columnName = columnNameMap.get(fieldName);
			if (columnName != null) {
				columnSQL.append(",");
				columnSQL.append(columnName);
			}
		}
		if (isByPage) {
			headSQLBuf.append(headModel);
			headSQLBuf.append(" RN");
			headSQLBuf.append(columnSQL);
			headSQLBuf.append("  FROM ( ");
			headSQLBuf.append(headSQL);
			headSQLBuf.append(columnSQL);
			headSQLBuf.append(" ");
			headSQLBuf.append("FROM");
			headSQLBuf.append(" ");
			headSQLBuf.append(classPropUtil.getTableName());
		} else {
			headSQLBuf.append(headSQL);
			headSQLBuf.append(columnSQL);
			headSQLBuf.append(" ");
			headSQLBuf.append("FROM");
			headSQLBuf.append(" ");
			headSQLBuf.append(classPropUtil.getTableName());
		}
		return headSQLBuf;
	}

	/**
	 * 
	 * @Title: createSQL 生成查询的sql语句
	 * @param classPropUtil
	 *            类信息工具
	 * @param sqlhead
	 *            要生成的语句头类型
	 * @param isByNotNulField
	 *            是否按照非空属性来构建
	 * @param isByPage
	 *            是否分页
	 * @param likeSel
	 *            是否开启模糊查询
	 * @return String 返回类型 构建好的sql语句
	 * @throws
	 */
	public String createSQL(ClassPropUtil classPropUtil, String sqlhead, boolean isByNotNulField, boolean likeSel) {
		StringBuffer sqlBuff = new StringBuffer();
		StringBuffer headSQLBuff = createHeadSQL(classPropUtil, isByNotNulField, sqlhead, false);
		StringBuffer whereSQLBuff = createWhereSQL(likeSel, classPropUtil);
		sqlBuff.append(headSQLBuff);
		if (whereSQLBuff != null)
			sqlBuff.append(whereSQLBuff);
		String querySql = sqlBuff.toString();

		return querySql;
	}

	/**
	 * @param endRecord
	 * @param startRecord
	 * 
	 * @Title: createSQLByPage 生成查询的sql语句,并且支持分页
	 * @param classPropUtil
	 *            类信息工具
	 * @param sqlhead
	 *            要生成的语句头类型
	 * @param isByNotNulField
	 *            是否按照非空属性来构建
	 * @param isByPage
	 *            是否分页
	 * @param likeSel
	 *            是否开启模糊查询
	 * @return String 返回类型 构建好的sql语句
	 * @throws
	 */
	public String createSQLByPage(ClassPropUtil classPropUtil, String sqlhead, boolean isByNotNulField,
			boolean likeSel, int startRecord, int endRecord) {
		StringBuffer sqlBuff = new StringBuffer();
		if (CollectionConfig.SLECT_HEAD_SQL.equals(sqlhead)) {
			StringBuffer headSQLLBuff = createHeadSQL(classPropUtil, isByNotNulField, sqlhead, true);
			StringBuffer whereSQLBuff = createWhereSQL(likeSel, classPropUtil);
			sqlBuff.append(headSQLLBuff);
			if (whereSQLBuff != null) {
				sqlBuff.append(whereSQLBuff);
				sqlBuff.append(" AND ROWNUM<=?)");
			} else
				sqlBuff.append(" WHERE ROWNUM<=?)");
			sqlBuff.append("WHERE RN>?");
		}
		String querySql = sqlBuff.toString();
		querySql = setPageParams(querySql, startRecord, endRecord);
		return querySql;
	}

	/**
	 * 为一条PreparedStatement根据传入的对象属性工具类设置占位符的值<br>
	 * 注意:如果传入对象属性工具类和PreparedStatement对象不一致,将会出现错误.
	 * 
	 * @param classPropUtil
	 *            类信息
	 */
	public void setPropsForPrepareStatement(ClassPropUtil classPropUtil, boolean likeSel) {
		int index = 1;
		List<String> whereParamList = new ArrayList<String>();
		for (Field field : classPropUtil.getFields()) {
			Object objTemp = classPropUtil.getValueByField(field);
			if (objTemp == null)
				continue;

			try {
				Object parma = null;
				if (objTemp.getClass().equals(Date.class)) {
					parma = new Timestamp(((Date) objTemp).getTime());
					prestmt.setTimestamp(index++, (Timestamp) parma);
				} else if (objTemp.getClass().equals(String.class) && likeSel) {
					parma = "%" + objTemp + "%";
					prestmt.setString(index++, (String) parma);
				} else{
					parma=objTemp;
					prestmt.setObject(index++, objTemp);
					}

				whereParamList.add(0, parma.toString() + "(" + parma.getClass().getSimpleName() + ")");
			} catch (SQLException e) {
				new ClassTypeAndStatementException().printStackTrace();
				e.printStackTrace();
			}
		}
		Collections.reverse(whereParamList);
		paramsList.addAll(0, whereParamList);
	}

	/**
	 * 
	 * 设置分页条件参数
	 * 
	 * @param querySq
	 *            要设置的sql语句l
	 * @param startRecord
	 *            开始记录条数
	 * @param endRecord
	 *            结束记录条数
	 * @return String 设置好的sql语句
	 */
	private String setPageParams(String querySql, Integer startRecord, Integer endRecord) {
		System.out.println("分页条件:" + startRecord + "(开始行数)");
		System.out.println("分页条件:" + endRecord + "(结束行数)");
		querySql = querySql.replaceAll("ROWNUM[><=\\s\\?]+\\?", "ROWNUM<=" + endRecord);
		querySql = querySql.replaceAll("RN[><=\\s\\?]+\\?", "RN>" + startRecord);
		paramsList.add(endRecord + "(" + endRecord.getClass().getSimpleName() + ")");
		paramsList.add(startRecord + "(" + startRecord.getClass().getSimpleName() + ")");
		return querySql;
	}
}

 

package com.leaves.dao.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.leaves.dao.annotations.OneToMany;
import com.leaves.dao.annotations.PrimaryKey;
import com.leaves.dao.exceptions.getClassPropException;

public class ClassPropUtil {
	public ClassPropUtil(Object object) {
		this.setObject(object);
		init(object);

	}

	/**
	 * 初始化方法设置几个所需要的属性
	 * 
	 * @param object
	 * @throws getClassPropException
	 */
	private void init(Object object) {
		Class<?> theClass = object.getClass();
		Properties prop = getProps();
		this.setTheClass(theClass);
		String tableName = prop.getProperty(theClass.getName());
		if (tableName == null) {
			getClassPropException getclasspropexception = new getClassPropException(
					getClassPropException.GET_TABLE_NAME);
			try {
				throw getclasspropexception;
			} catch (getClassPropException e) {
				e.printStackTrace();
			}
		} else
			this.setTableName(tableName);

		Field[] fields = this.getFields();

		Map<String, String> columnNameMap = new HashMap<String, String>();
		for (Field field : fields) {
			String columnName = prop.getProperty(theClass.getName() + "." + field.getName());
			if (columnName != null)
				columnNameMap.put(field.getName(), columnName);
		}
		this.setColumnNameMap(columnNameMap);
	}

	/**
	 * 获取properties属性配置
	 * 
	 * @return
	 */
	public Properties getProps() {
		Properties prop = new Properties();
		InputStream is;
		try {
			is = new FileInputStream(new File("src/tableProp.properties"));
			prop.load(is);
			is.close();
		} catch (Exception e) {
			System.out.println("Open property File  " + "tableProp.properties" + " error!");
		}
		return prop;
	}

	/**
	 * 根据字段来查询其值相当于执行getter方法
	 * 
	 * @param field
	 * @return
	 */
	public Object getValueByField(Field field) {
		PropertyDescriptor pd = null;
		try {
			pd = new PropertyDescriptor(field.getName(), theClass);
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
		Method getMethod = pd.getReadMethod();
		Object objTemp = null;
		try {
			objTemp = getMethod.invoke(object);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return objTemp;
	}

	/**
	 * 根据字段设置值
	 * 
	 * @param field
	 *            字段
	 * @return 如果失败(找不到字段),则返回false,否则返回true
	 */
	public boolean setValueByField(Field field, Object object) {
		boolean flag = false;
		PropertyDescriptor pd = null;
		try {
			pd = new PropertyDescriptor(field.getName(), theClass);
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
		Method getMethod = pd.getWriteMethod();
		try {
			getMethod.invoke(this.getObject(), object);
			flag = true;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 根据字段名称设置值
	 * 
	 * @param fieldName
	 *            字段名称
	 * @return 如果失败(找不到字段),则返回false,否则返回true
	 */
	public boolean setValueByFieldName(String fieldName, Object object) {
		boolean flag = false;
		PropertyDescriptor pd;
		try {
			pd = new PropertyDescriptor(fieldName, theClass);
			pd.getWriteMethod().invoke(this.getObject(), object);
			flag = true;
		} catch (IntrospectionException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 设置指定类型的主键
	 * 
	 * @param primaryKey
	 *            主键值
	 * @return boolean 成功查询到主键并且设置则返回true,否则返回false
	 */
	public boolean setPrimaryKey(Integer primaryKey) {
		boolean flag = false;
		for (Field field : this.getFields()) {
			if (field.getAnnotation(PrimaryKey.class) != null) {
				PropertyDescriptor pd = null;
				try {
					pd = new PropertyDescriptor(field.getName(), this.getTheClass());
					Method setMethod = pd.getWriteMethod();
					setMethod.invoke(this.getObject(), primaryKey);
					flag = true;
				} catch (IntrospectionException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;
	}

	/**
	 * 查询指定类型的主键 (如果返回null标示没有注解主键)
	 * 
	 * @return Integer 主键值
	 */
	public Integer getPrimaryKey() {
		Integer primaryKeyValue = null;
		for (Field field : this.getFields()) {
			if (field.getAnnotation(PrimaryKey.class) != null) {
				PropertyDescriptor pd = null;
				try {
					pd = new PropertyDescriptor(field.getName(), this.getTheClass());
					Method getMethod = pd.getReadMethod();
					primaryKeyValue = (Integer) getMethod.invoke(this.getObject());
				} catch (IntrospectionException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return primaryKeyValue;
	}

	/**
	 * 设置内部集合的值(有问题)
	 * 
	 * @param list
	 * @return Integer
	 */
	public Integer setManyList(List<? extends Object> list) {
		Integer primaryKeyValue = null;
		for (Field field : this.getFields()) {
			if (field.getAnnotation(OneToMany.class) != null) {
				PropertyDescriptor pd = null;
				try {
					pd = new PropertyDescriptor(field.getName(), this.getTheClass());
					Method getMethod = pd.getWriteMethod();
					getMethod.invoke(this.getObject(), list);
				} catch (IntrospectionException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return primaryKeyValue;
	}

	public Map<String, String> getColumnNameMap() {
		return columnNameMap;
	}

	public void setColumnNameMap(Map<String, String> columnNameMap) {
		this.columnNameMap = columnNameMap;
	}

	public Object getObject() {
		return object;
	}

	public void setObject(Object object) {
		this.object = object;
	}

	public Class<?> getTheClass() {
		return theClass;
	}

	public void setTheClass(Class<?> theClass) {
		this.theClass = theClass;
	}

	public String getTableName() {
		return TableName;
	}

	public void setTableName(String tableName) {
		TableName = tableName;
	}

	/**
	 * 获取所有属性数组的方法
	 * 
	 * @return
	 */
	public Field[] getFields() {
		Field[] fileds = theClass.getDeclaredFields();
		return fileds;
	}

	/**
	 * 此属性用来存放类的字段名称和在配置文件中对应的列名
	 */
	private Map<String, String> columnNameMap;
	/**
	 * 此属性用来存放类型
	 */
	private Class<?> theClass;

	private String TableName;

	private Object object;
}

 

package com.leaves.dao.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.leaves.dao.annotations.OneToMany;
import com.leaves.dao.connection.CollectionConfig;
import com.leaves.dao.connection.QueryStatementCreater;

/**
 * 
 * <b>ExeSQL说明:</b> <br>
 * 此类用于执行对数据库的操作,执行之后会返回封装好的实体类对象。<br>
 * 每次使用完本类后需要手动调用close()方法关闭所使用的资源.
 * 
 * @author leaves叶知泉
 * @version 1.0
 * @since 2012-1-12 上午9:23:36
 * @param <T>要针对哪个实体类进行操作。
 */
public class ExeSQLOneAndMany<T> extends ExeSQL<T> {
	private ClassPropUtil classPropUtil;
	private QueryStatementCreater qsc;

	/**
	 * 按照指定数据库名创建执行器
	 * 
	 * @param databaseName
	 */
	public ExeSQLOneAndMany(CollectionConfig collectionConfig) {
		super(collectionConfig);
	}

	/**
	 * 查询数据库内容,不分页
	 * 
	 * @param object
	 *            要查询的类的对象模型
	 * @param likeSel
	 *            是否进行模糊查询
	 * @param isByNotNulField
	 *            是否按照非空属性查询
	 * @return List<T> 查询结果所封装的结果集
	 */
	public List<T> exeQuery(Object object, boolean likeSel, boolean isByNotNulField) {
		classPropUtil = new ClassPropUtil(object);
		qsc = new QueryStatementCreater(collectionConfig);

		String theSQL = qsc.createSQL(classPropUtil, CollectionConfig.SLECT_HEAD_SQL, isByNotNulField, likeSel);


		prestmt = qsc.getStatement(theSQL, classPropUtil,likeSel);
		try {
			rs = prestmt.executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		List<T> resultList = resultSetToObjectList(rs, classPropUtil, isByNotNulField);

		return resultList;
	}

	/**
	 * 查询数据库内容,可以分页
	 * 
	 * @param object
	 *            要查询的类的对象模型
	 * @param likeSel
	 *            是否进行模糊查询
	 * @param isByNotNulField
	 *            是否按照非空属性查询
	 * @param startRecord
	 *            起始记录条数
	 * @param endRecord
	 *            结束记录条数
	 * @return List<T> 查询结果所封装的结果集
	 */
	public List<T> exeQueryByPage(Object object, boolean likeSel, boolean isByNotNulField, int startRecord,
			int endRecord) {
		classPropUtil = new ClassPropUtil(object);
		qsc = new QueryStatementCreater(collectionConfig);

		String theSQL = qsc.createSQLByPage(classPropUtil, CollectionConfig.SLECT_HEAD_SQL, isByNotNulField, likeSel,
				startRecord, endRecord);

		prestmt = qsc.getStatement(theSQL, classPropUtil,likeSel);
		try {
			rs = prestmt.executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		List<T> resultList = resultSetToObjectList(rs, classPropUtil, isByNotNulField);

		for (Field field : classPropUtil.getFields()) {
			OneToMany oneToMany = field.getAnnotation(OneToMany.class);
			if (oneToMany != null) {
				try {

					Object theObject = Class.forName(oneToMany.toTypeName()).newInstance();

					new ClassPropUtil(theObject)
							.setValueByFieldName(oneToMany.toField(), classPropUtil.getPrimaryKey());
					for (T t : resultList) {
						new ClassPropUtil(t).setManyList(exeQuery(theObject, false, false));
					}
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InstantiationException e) {
					e.printStackTrace();
				}

			}
		}
		qsc.closeAll();
		return resultList;
	}

	/**
	 * 功能:执行更新操作 executeUpdate()方法执行更新语句,并且返回一个int值,包含给定查询所生成数据的 ResultSet 对象
	 * 
	 * @param sql
	 *            要执行的查询语句,此语句是预编译语句
	 * @param objects
	 *            此sql语句需要处理的预编译参量
	 * @return result 包含给定sql语句操作的数据条数,如果执行不成功,则返回0
	 */
	public int exeUpdate(String sql, Object... objects) {
		int result;
		try {
			conn = qsc.getConnection();
			prestmt = conn.prepareStatement(sql, ResultSet.CONCUR_READ_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE);
			for (int i = 0; i < objects.length; i++)
				prestmt.setObject(i + 1, objects[i]);
			result = prestmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
			result = 0;
		}
		return result;

	}

	/**
	 * 功能:执行更新操作 executeUpdate()方法执行更新语句,并且返回一个int值,包含给定查询所生成数据的 ResultSet 对象
	 * 
	 * @return result 包含给定sql语句操作的数据条数,如果执行不成功,则返回0
	 */
	public int exeUpdate(String sql) {
		int result = 0;
		try {
			conn = qsc.getConnection();
			stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			result = stmt.executeUpdate(sql);
		} catch (SQLException ex) {
			result = 0;
		}
		return result;
	}

	/**
	 * 
	 * @Title: resultSetToObjectList
	 * @Description: TODO 把查询结果封装成对象集
	 * @param @param rs 查询结果集
	 * @param @param classPropUtil 对象属性工具类
	 * @param @param isByNotNulFieldl 是否按照非空属性
	 * @return List<T> 转换后的结果集
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	protected List<T> resultSetToObjectList(ResultSet rs, ClassPropUtil classPropUtil, boolean isByNotNulFieldl) {
		Class<?> theClass = classPropUtil.getTheClass();
		Map<String, String> columnNameMap = classPropUtil.getColumnNameMap();
		List<T> resultList = new ArrayList<T>();
		try {
			while (rs.next()) {
				Object object = null;
				try {
					object = theClass.newInstance();
				} catch (Exception e) {
					e.printStackTrace();
				}
				for (Field field : classPropUtil.getFields()) {
					if (isByNotNulFieldl)
						if (classPropUtil.getValueByField(field) == null)
							continue;

					PropertyDescriptor pd = null;
					try {
						pd = new PropertyDescriptor(field.getName(), theClass);
					} catch (IntrospectionException e) {
						e.printStackTrace();
					}
					Method setMethod = pd.getWriteMethod();
					try {
						Object columnValue = null;
						if (setMethod.getParameterTypes()[0].equals(Byte.class))
							columnValue = rs.getByte(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Short.class))
							columnValue = rs.getShort(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Integer.class))
							columnValue = rs.getInt(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Long.class))
							columnValue = rs.getLong(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Float.class))
							columnValue = rs.getFloat(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Double.class))
							columnValue = rs.getDouble(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(BigDecimal.class))
							columnValue = rs.getBigDecimal(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Blob.class))
							columnValue = rs.getBlob(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Time.class))
							columnValue = rs.getTime(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Timestamp.class))
							columnValue = rs.getTimestamp(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(String.class))
							columnValue = rs.getString(columnNameMap.get(field.getName()));
						else if (setMethod.getParameterTypes()[0].equals(Date.class))
							columnValue = rs.getDate(columnNameMap.get(field.getName()));

						if (null != columnValue)
							setMethod.invoke(object, columnValue);

					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}
				}
				resultList.add((T) object);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return resultList;

	}

	protected Connection conn = null;
	protected ResultSet rs = null;
	protected PreparedStatement prestmt = null;
	protected Statement stmt = null;
}

 
附带上源码包


论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics