在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结果集描述接口
- 创建方式
假设已实例化结果集对象ResultSet rs = new ResultSet();
即可通过rs对象创建结果集描述对象ResultSetMetaData rsmd = rs.getMetaData();
rsmd.getColumnCount();
:计算列数方法。返回值为intrsmd.getColumnLabel(i)
:通过第i列,获得列名。返回值为String
优化思想
目标:将查询结果以Map<列名,该列查询结果>
的格式,自动装入目标Map容器
步骤:
- 使用
rsmd.getColumnCount()
计算查询结果列数column - 循环所有列,
for(int i=1 ; i<=column ; i++)
- 通过列数i,使用
rsmd.getColumnLabel(i)
获得该列的列名,使用rs.getString(i)
获得该列的数据 - 列名和数据装载到容器中,完成列级映射
优化尝试
假设要查询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的时候,自定义初始化了容量。