JDBC进化史(八)优化之:查询结果描述优化

JDBC进化史(六)JDBC常见操作–单行查询中,已经实现了单行查询的基本方案,但它依旧不方便于我们实际的使用:在代码中,我们需要知道每一列的名称,并将其一行一行的put到目标容器中。先贴出完整方法代码

	//查找学生
	public Map<String,String> findById(Object id)throws Exception
	{
		//1.定义JDBC接口变量
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try
		{
			//2.创建连接
			conn = DBUtils.getConnection();
			//3.定义sql
			StringBuilder sql = new StringBuilder()
					.append("SELECT A.STUID,A.SNAME,A.SDATE,A.SCORE,A.MEMO")
					.append("  FROM STUDENT A")
					.append(" WHERE A.STUID=?");
			//3.预编译sql
			pstm = conn.prepareStatement(sql.toString());
			//4.参数赋值
			pstm.setObject(1, id);
			//5.执行sql
			rs = pstm.executeQuery();
			//6.定义用于装载的Map容器
			Map<String,String> cup = new HashMap<>();
			//7.判断是否查询到数据
			if(rs.next())
			{
				//8.装载结果集数据
				cup.put("stuid", rs.getString(1));
				cup.put("sname", rs.getString(2));
				cup.put("sdate", rs.getString(3));
				cup.put("score", rs.getString(4));
				cup.put("memo", rs.getString(5));
			}
			return cup;
		}
		finally
		{
			DBUtils.close(rs);
			DBUtils.close(pstm);
			DBUtils.close(conn);
		}
	}

参见步骤8。如果能够让程序自动识别列名,自动将数据装载到容器中导出,这样显然会让操作者省心很多!于是我们将寻求新的方式,优化我们的结果集描述。

导入:ResultSetMetaData结果集描述接口

  1. 创建方式
    假设已实例化结果集对象ResultSet rs = new ResultSet();
    即可通过rs对象创建结果集描述对象ResultSetMetaData rsmd = rs.getMetaData();
  2. rsmd.getColumnCount();:计算列数方法。返回值为int
  3. rsmd.getColumnLabel(i):通过第i列,获得列名。返回值为String

优化思想

目标:将查询结果以Map<列名,该列查询结果>的格式,自动装入目标Map容器
步骤

  1. 使用rsmd.getColumnCount()计算查询结果列数column
  2. 循环所有列,for(int i=1 ; i<=column ; i++)
  3. 通过列数i,使用rsmd.getColumnLabel(i)获得该列的列名,使用rs.getString(i)获得该列的数据
  4. 列名和数据装载到容器中,完成列级映射

优化尝试

假设要查询id=25的学生
StudentServicesInit.java

//查找学生
	public Map<String,String> findById(Object id)throws Exception
	{
		//1.定义JDBC接口变量
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try
		{
			//2.创建连接
			conn = DBUtils.getConnection();
			//3.定义sql
			StringBuilder sql = new StringBuilder()
					.append("SELECT A.STUID,A.SNAME,A.SDATE,A.SCORE,A.MEMO")
					.append("  FROM STUDENT A")
					.append(" WHERE A.STUID=?");
			//4.预编译sql
			pstm = conn.prepareStatement(sql.toString());
			//5.参数赋值
			pstm.setObject(1, id);
			//6.执行sql
			rs = pstm.executeQuery();
			//7.定义用于装载的Map容器
			Map<String,String> cup = null;
			//8.判断是否查询到数据
			if(rs.next())
			{
				//9.创建结果集描述对象
				ResultSetMetaData rsmd = rs.getMetaData();
				//10.计算列数
				int column = rsmd.getColumnCount();
				//11.计算安全容量
				int size = ((int)(column/0.75))+1;
				//12.实例化Map容器
				cup = new HashMap<>(size);
				//13.循环所有列
				for(int i=1 ; i<=column ; i++)
				{
					//14.完成列级映射
					cup.put(rsmd.getColumnLabel(i).toLowerCase(), rs.getString(i));
				}
			}
			return cup;
		}
		finally
		{
			DBUtils.close(rs);
			DBUtils.close(pstm);
			DBUtils.close(conn);
		}
	}

StudentServicesInitTest.java

	//查找学生
	public static void findByIdTest()throws Exception
	{
		StudentServicesInit services = new StudentServicesInit();
		Map<String,String> cup = services.findById("25");
		System.out.println(cup);
	}

获得查询结果

{score=100, memo=圣诞快乐!, sdate=2018-12-25 00:00:00, stuid=25, sname=圣诞老人}

显然,通过以上代码,我们完成了目标!
优化细节: 为了节省内存空间,我在初始化HashMap的时候,自定义初始化了容量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值