通过反射完成resultSet到Object的转换

发表时间:2017-05-11 16:54:50 浏览量( 16 ) 留言数( 0 )

学习目标:

1、了解Java的历史

2、为什么要学习Java语言

3、端正学习态度


学习过程:

有关JDBC的内容就讲到这里,下面我们对BaseDao进一步封装,主要应用一下以前学习的泛型和反射的概念。毕竟大家对java高级方面的内容掌握的并不是很好。

首先我们先看看在所有的查询语句中都需要把结果集的内容转换成为对象如下面的这段代码:

 while (rs.next()) {
	// System.out.println(rs.getInt("user_id")+":"+rs.getString("user_name"));
	User user = new User();
	user.setUserId(rs.getInt("user_id"));
	user.setUserName(rs.getString("user_name"));

	users.add(user);
}

像这样的代码还有很多,那我们能不能封装一下呢?下面我们就利用泛型和反射的技术封装一下,上面的这段代码的逻辑是很简单的,就是调用所有的pojo对象的set方法,但是在实现之前我们必须先定下一个命名规范,否则表的字段和pojo对象的属性是对应不起来的,规范如下:

所有的表的字段的下划线命名方式都需要改成对应的驼峰式命名:如字段:表字段:user_id,那么它对应的对象的属性就是userId。

新建一个FatherDao类继承BaseDao,在这个FatherDao写一个rs2Object方法,代码如下:

public class FatherDao<T> extends BaseDao {

	private Class<T> clazz;

	public FatherDao(Class<T> clazz) {
		this.clazz = clazz;
	}

	// Result Object
	public T rs2Object(ResultSet resultSet) {
		T t = null;
		try {
			t = clazz.newInstance();
			// 1、通过反射技术获得所有的属性。
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				// 获得对应的set方法。
				String setMethod = "set"
						+ field.getName().substring(0, 1).toUpperCase()
						+ field.getName().substring(1);
				// System.out.println(setMethod);
				Method method = clazz.getDeclaredMethod(setMethod,
						field.getType());
				// 调用方法
				method.invoke(t, resultSet.getObject(fieldNameToClumeName(field
						.getName())));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}

	// userId >> user_id
	// userName >> user_name
	private String fieldNameToClumeName(String fieldName) {

		if (fieldName == null) {
			return null;

		}

		StringBuilder sb = new StringBuilder();

		boolean upperCase = false;

		for (int i = 0; i < fieldName.length(); i++) {
			char c = fieldName.charAt(i);
			boolean nextUpperCase = true;
			if (i < (fieldName.length() - 1)) {
				nextUpperCase = Character.isUpperCase(fieldName.charAt(i + 1));
			}
			if ((i >= 0) && Character.isUpperCase(c)) {
				if (!upperCase || !nextUpperCase) {
					if (i > 0)
						sb.append("_");
				}
				upperCase = true;
			} else {
				upperCase = false;
			}
			sb.append(Character.toLowerCase(c));

		}

		return sb.toString();

	}

}

所有Dao层类,现在都不需要直接继承BaseDao了,只需要继承FatherDao,然后显示的调用父类的构造方法即可:

 public class UserDao extends FatherDao<User>{
	public UserDao() {
		super(User.class);
	}

}

结果集合ResultSet转换可以直接调用这个方法即可,在也不需要一个一个的属性set进去了。

 if (resultSet.next()) {
    user = rs2Object(resultSet);
}