8、关于增强版的GenericityJDBCUtils的实现,可灵活的处理select的返回结果

1、在数据库的查找过程中,有的时候会涉及到返回一个集合,有的时候会涉及到返回一个具体的实体类,应做到可灵活的处理select的返回结果

2、为了方便的处理ResultSet的返回结果,定义了下面的接口和实现类

      2.1    ResultSetHandle

      

package com.jdbc.enhancegenericity.utils;

import java.sql.ResultSet;

/**
 * 用于处理select返回的ResultSet,是实体类的集合,还是一个单一的实体类
 *
 * @param <T>
 *            泛型T,在调用的时候传入具体的处理结果;例如User或者List<User>
 */
public interface ResultSetHandle<T> {
	/**
	 * 
	 * @param rs
	 *            select语句执行后,返回的ResultSet结果集
	 * @return 返回实体,或者集合,看具体的实现类
	 */
	public T handle(ResultSet rs);

}

       2.2  BeanHandle

package com.jdbc.enhancegenericity.utils;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

/**
 * 
 * ResultSetHandle<T>接口的实现类,用于处理select语句返回一个具体实体的情况
 * 
 * @param <T>
 */
public class BeanHandle<T> implements ResultSetHandle<T> {

	/**
	 * 用于保存具体实体类的Class对象
	 */
	private Class<T> clazz;

	/**
	 * 在构造BeanHandle的时候,传入具体实体的Class对象
	 * 
	 * @param clazz
	 *            具体实体的Class对象
	 */
	public BeanHandle(Class<T> clazz) {
		this.clazz = clazz;
	}

	@Override
	public T handle(ResultSet rs) {

		try {
			// 如果查询的ResultSet结果集为空,直接返回null
			if (!rs.next()) {
				return null;
			}
			T bean = clazz.newInstance();
			// 得到结果集的元数据
			ResultSetMetaData metaData = rs.getMetaData();
			int count = metaData.getColumnCount();
			for (int i = 0; i < count; i++) {
				// 注意jdbc的下标,从1开始
				// 去获取到数据库中的列的名称
				String name = metaData.getColumnName(i + 1);
				// 获取到,数据库列对应的数值
				Object value = rs.getObject(name);
				// 反射bean上与列名相同的属性
				Field f = bean.getClass().getDeclaredField(name);
				f.setAccessible(true);
				f.set(bean, value);
			}
			// 返回查询到的实体对象
			return bean;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

}
   

        2.3  ListBeanHandle

package com.jdbc.enhancegenericity.utils;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * 因为ListBeanHandle<T>是用于处理返回结果是集合的情况, 所以要注意ResultSetHandle<List<T>>的具体写法
 * 
 * @param <T>
 */
public class ListBeanHandle<T> implements ResultSetHandle<List<T>> {
	/**
	 * 用于保存具体实体类的Class对象
	 */
	private Class<T> clazz;

	/**
	 * 在构造BeanHandle的时候,传入具体实体的Class对象
	 * 
	 * @param clazz
	 *            具体实体的Class对象
	 */
	public ListBeanHandle(Class<T> clazz) {
		this.clazz = clazz;
	}

	@Override
	public List<T> handle(ResultSet rs) {
		try {

			List<T> lists = new ArrayList<T>();
			while (rs.next()) {
				T bean = clazz.newInstance();
				// 得到结果集的元数据
				ResultSetMetaData metaData = rs.getMetaData();
				int count = metaData.getColumnCount();
				for (int i = 0; i < count; i++) {
					// 注意jdbc的下标,从1开始
					// 去获取到数据库中的列的名称
					String name = metaData.getColumnName(i + 1);
					// 获取到,数据库列对应的数值
					Object value = rs.getObject(name);
					// 反射bean上与列名相同的属性
					Field f = bean.getClass().getDeclaredField(name);
					f.setAccessible(true);
					f.set(bean, value);
				}
				// 将得到的记录加入到lists中
				lists.add(bean);
			}
			// 返回查询到的实体对象的集合lists
			return lists;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}


3、GenericityJDBCUtils的实现代码

package com.jdbc.enhancegenericity.utils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.jdbc.entity.User;
import com.jdbc.utils.MyJDBCUtils;

public class GenericityJDBCUtils {

	private static Connection conn;
	private static PreparedStatement pstate;
	private static ResultSet rs;
	// 为了程序的更好的解耦合,利用Properties文件保存连接Mysql的配置文件
	private static Properties config = new Properties();
	/**
	 * 使用static块,加载数据库的配置文件和数据库的驱动
	 */
	static {
		try {
			config.load(MyJDBCUtils.class.getClassLoader().getResourceAsStream(
					"db.properties"));
			Class.forName(config.getProperty("driver"));
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	/**
	 * 获取一个数据库的连接
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(config.getProperty("url"),
					config.getProperty("username"),
					config.getProperty("password"));
		} catch (SQLException e) {
			throw new RuntimeException("获取连接Mysql数据库连接失败");
		}
		return conn;
	}

	/**
	 * 释放数据库的连接
	 * 
	 * @param conn
	 * @param st
	 * @param rs
	 */
	public static void release(Connection conn, Statement st, ResultSet rs) {

		if (rs != null) {
			try {
				rs.close();
			} catch (Exception e) {
				throw new RuntimeException("ResultSet关闭异常");
			}
			rs = null;
		}
		if (st != null) {
			try {
				st.close();
			} catch (Exception e) {
				throw new RuntimeException("Statement关闭异常");
			}
			st = null;
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (Exception e) {
				throw new RuntimeException("Connection关闭异常");
			}
			conn = null;
		}

	}

	/**
	 * 
	 * @param clazz
	 *            要返回的类型的字节码
	 * @param id
	 *            要查找记录在表里面的id
	 * @return 在数据库里面查找到的记录,并返回
	 */
	public static <T> T findById(Class<T> clazz, int id) {
		T bean = null;
		// System.out.println(clazz.getSimpleName());
		try {
			bean = clazz.newInstance();
			String tableName = clazz.getSimpleName();
			String sql = "select * from " + tableName + " where id = ? ";
			conn = getConnection();
			pstate = conn.prepareStatement(sql);
			pstate.setInt(1, id);
			rs = pstate.executeQuery();
			if (rs.next()) {
				// 得到结果集的元数组
				ResultSetMetaData metaData = rs.getMetaData();
				int count = metaData.getColumnCount();
				for (int i = 0; i < count; i++) {
					// 注意jdbc的下标,从1开始
					// 去获取到数据库中的列的名称
					String name = metaData.getColumnName(i + 1);
					// 获取到,数据库列对应的数值
					Object value = rs.getObject(name);
					// 反射bean上与列名相同的属性
					Field f = bean.getClass().getDeclaredField(name);
					f.setAccessible(true);
					f.set(bean, value);
				}

			}
			return bean;

		} catch (Exception e) {
			throw new RuntimeException("在数据库中,查找id为" + id + "的User记录失败." + e);
		} finally {
			// 释放资源,关闭与数据库的连接
			release(conn, pstate, rs);
		}

	}

	/**
	 * 郑强版本的sql查询,支持查询一个具体的实体或者是一个实体集合
	 * 
	 * @param sql
	 *            查询的sql语句
	 * @param args
	 *            对应sql语句中的参数
	 * @param handle
	 *            具体的ResultSet处理器, BeanHandle用于处理一个具体的实体类,
	 *            ListBeanHandle用于处理返回一个集合的情况
	 * @return
	 */
	public static <T> T query(String sql, Object[] args,
			ResultSetHandle<T> handle) {
		try {
			// 获取连接Connection
			conn = getConnection();
			// 获取PreparedStatement
			pstate = conn.prepareStatement(sql);
			// 设置参数
			for (int i = 0; i < args.length; i++) {
				pstate.setObject(i + 1, args[i]);
			}
			// 获取rs
			rs = pstate.executeQuery();
			// 通过ResultSetHandle处理ResultSet,并返回结果
			return handle.handle(rs);

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			release(conn, pstate, rs);
		}

	}

	/**
	 * 适应于sql语句不带参数的问题
	 * 
	 * @param sql
	 * @param handle
	 * @return
	 */
	public static <T> T query(String sql, ResultSetHandle<T> handle) {
		try {
			// 获取连接Connection
			conn = getConnection();
			// 获取PreparedStatement
			pstate = conn.prepareStatement(sql);
			// 获取rs
			rs = pstate.executeQuery();
			// 通过ResultSetHandle处理ResultSet,并返回结果
			return handle.handle(rs);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			release(conn, pstate, rs);
		}

	}

	/**
	 * 根据传进来的sql语句,来跟新数据库的表记录
	 * 
	 * @param sql
	 * @param args
	 */
	public static void update(String sql, Object[] args) {
		try {
			if (args.length < 0) {
				throw new RuntimeException("Object[] args的数组长度,不应该为空");
			}
			conn = getConnection();
			pstate = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				pstate.setObject(i + 1, args[i]);
			}
			// 注意要调用这个方法
			pstate.executeUpdate();

		} catch (Exception e) {
			throw new RuntimeException("更新数据库中的记录失败" + e);
		} finally {
			// 释放资源,关闭与数据库的连接
			release(conn, pstate, null);
		}
	}

	/**
	 * 根据sql语句来更新数据库表中的记录
	 * 
	 * @param sql
	 */
	public static void update(String sql) {
		try {
			conn = getConnection();
			pstate = conn.prepareStatement(sql);
			// 注意要调用这个方法
			pstate.executeUpdate();
		} catch (Exception e) {
			throw new RuntimeException("更新数据库中的记录失败" + e);
		} finally {
			// 释放资源,关闭与数据库的连接
			release(conn, pstate, null);
		}
	}

}

4、测试代码

package com.jdbc.enhancegenericity.utils;

import java.util.List;

import org.junit.Test;

import com.jdbc.entity.Person;
import com.jdbc.entity.User;

public class GenericityJDBCUtilsTest {

	@Test
	public void testQuery() {
		String sql = "select * from user ";
		List<User> users = GenericityJDBCUtils.query(sql,
				new ListBeanHandle<User>(User.class) {
				});
		for (int i = 0; i < users.size(); i++) {
			System.out.println(users.get(i));
		}

		sql = "select * from person where id = ? ";
		Person person = GenericityJDBCUtils.query(sql, new Object[] { 1 },
				new BeanHandle<Person>(Person.class));
		System.out.println(person);

	}
}

5、数据库数据

      

             

6、程序运行结果








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值