欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-01 19:45:34
...

 

   内省(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