`

基于java 简易ORM 框架实现(二)

阅读更多

 

   内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。

  将JavaBean中的属性封装起来进行操作。在程序把一个类当做JavaBean来看,就是调用Introspector.getBeanInfo()方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息。

 

  getPropertyDescriptors(),获得属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。

通过内省机制改进Orm类,代码如下:

package orm;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import util.JdbcUtils;
/**
 * 
 * @author fengzb
 *
 * @param <T>
 */
public class Orm2<T> {

	private static final int NOT_FOUND = -1;

	/**
	 * 获得映射数据库后的一个装配好的实体对象bean
	 * 
	 * @param sql
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public  T getBean(String sql, Class<T> clazz) throws Exception {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();

			T t = clazz.newInstance();
			int[] pos = mapColumnsToProperties(rs, clazz);
			if(rs.next()){
				callSetter(t,pos,rs);
			}
			return t;
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}

	/**
	 * 获得映射数据库后的装配好的实体对象bean List
	 * 
	 * @param sql
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public List<T> getBeanList(String sql, Class<T> clazz) throws Exception {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> ts = new ArrayList<T>();
		try {
			conn = JdbcUtils.getConnection();
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();

			T t = null;
			int[] pos = mapColumnsToProperties(rs, clazz);
			while(rs.next()){
				t = clazz.newInstance();
				callSetter(t,pos,rs);
				ts.add(t);
			}
			return ts;
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}
	
	/**
	 * 利用Java反射与内省(Introspector)机制进行装配
	 * 
	 * @param t
	 * @param pos
	 * @param rs
	 * @throws Exception
	 */
	private void callSetter(T t, int[] pos, ResultSet rs) throws Exception {
		ResultSetMetaData rsmd = rs.getMetaData();
		PropertyDescriptor[] props = null;
		BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
		props = beanInfo.getPropertyDescriptors();
		for(int i = 1; i<=rsmd.getColumnCount();i++){
			if(pos[i]!= NOT_FOUND){
				props[pos[i]].getWriteMethod().invoke(t, rs.getObject(i));
			}
		}
	}
	
	/**
	 * 找到resultset中每个值对应 bean中属性的位置
	 * 
	 * @param rs
	 * @param clazz
	 * @return
	 * @throws SQLException
	 * @throws IntrospectionException
	 */
	private int[] mapColumnsToProperties(ResultSet rs,Class<T> clazz) throws SQLException, IntrospectionException{
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnLength = rsmd.getColumnCount();
		int[] columnsToProperties = new int[columnLength+1];
		PropertyDescriptor[] props = null;
		BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
		props = beanInfo.getPropertyDescriptors();
		Arrays.fill(columnsToProperties,NOT_FOUND);
		for(int col = 1; col <= columnLength; col++){
			String columnName = rsmd.getColumnLabel(col);
			if (null == columnName || 0 == columnName.length()) {
				columnName = rsmd.getColumnName(col);
	        }
			for(int i=0;i<props.length;i++){
				if(props[i].getName().equalsIgnoreCase(columnName)){
					columnsToProperties[col] = i;
					break;
				}
			}
		}
		return columnsToProperties;
	}
}
 比较两种方式的执行效率:
package orm;


import java.util.List;

import model.User;

import org.junit.Test;


public class OrmTest {
	@Test
	public void ormTest() throws Exception{
		long start = System.currentTimeMillis();
		Orm<User> orm = new Orm<User>();
		User user= (User) orm.getBean("SELECT userId ,department,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user",User.class);
		System.out.println(user);

		List<User> userList= orm.getBeanList("SELECT userId,department,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user",User.class);
		for(User u : userList){
			System.out.println(u);
		}
		System.out.println("耗时:"+(System.currentTimeMillis() - start)+"ms");
	}
	
	@Test
	public void orm2Test() throws Exception{
		long start = System.currentTimeMillis();
		Orm2<User> orm2 = new Orm2<User>();
		User user2 = orm2.getBean("SELECT userId,department,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user", User.class);
		System.out.println(user2);
		
		List<User> userList2= orm2.getBeanList("SELECT userId,department,division,email,employeeNo,name,passwordMD5,phone,position,state,type FROM tb_user",User.class);
		for(User u : userList2){
			System.out.println(u);
		}
		System.out.println("耗时:"+(System.currentTimeMillis() - start)+"ms");
	}
}
 

 

 结果如下:

User [userId=1, department=321, division=3213, email=321, employeeNo=321, name=321, passwordMD5=321, phone=321, position=321, state=321, type=21]
User [userId=1, department=321, division=3213, email=321, employeeNo=321, name=321, passwordMD5=321, phone=321, position=321, state=321, type=21]
User [userId=2, department=321, division=3213, email=321, employeeNo=321, name=321, passwordMD5=321, phone=321, position=321, state=321, type=21]
耗时:464ms
User [userId=1, department=321, division=3213, email=321, employeeNo=321, name=321, passwordMD5=321, phone=321, position=321, state=321, type=21]
User [userId=1, department=321, division=3213, email=321, employeeNo=321, name=321, passwordMD5=321, phone=321, position=321, state=321, type=21]
User [userId=2, department=321, division=3213, email=321, employeeNo=321, name=321, passwordMD5=321, phone=321, position=321, state=321, type=21]
耗时:35ms

 
 
 可见用内省机制改进后执行效率得到很大提高。

 

  • orm.rar (14.2 KB)
  • 下载次数: 2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics