JavaWeb学习-JDBC系列-5-ResultSet介绍

到学习四个核心对象的最后一个ResultSet,也就是结果集。前面一篇是操作SQL,这篇是对操作结果进行处理。结果集在客户端表现是一张虚拟的表,也就是存储在内存里。ResultSetz有两个功能,一个是对结果集进行封装,第二个是有可移动游标方法。

1.对结果集进行封装

前面的例子,我们对结果集的操作就是打印到控制台。在实际编程中,肯定是需要返回给前端数据的。这个在Java中,是这样处理的。例如Student表中,一行表示一个学生的信息。那么如果把一行看做一个对象,一行里面的年龄,id就是这个对象的属性。我们可以把对象存储在一个集合里,这样就方便后续操作和给前端数据。所以,接下来,我们对结果集进行封装成对象,然后存储到集合里。在封装之前,我们需要写一个Java Bean类。什么是Bean类呢?就是一个类,里面属性全部是私有的,提供set和get方法,和一个无参构造方法。

package demo;

public class Student {
	private int Id;
	private String Name;
	private String Gender;
	private int Age;
	
	public Student() {}
	
	public int getId() {
		return Id;
	}
	public void setId(int id) {
		Id = id;
	}
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
	public String getGender() {
		return Gender;
	}
	public void setGender(String gender) {
		Gender = gender;
	}
	public int getAge() {
		return Age;
	}
	public void setAge(int age) {
		Age = age;
	}

	@Override
	public String toString() {
		return "Student [Id=" + Id + ", Name=" + Name + ", Gender=" + Gender + ", Age=" + Age + ", toString()="
				+ super.toString() + "]";
	}
	
}

Bean类创建好了之后,接下来,我们要思考,如何把数据库中不同类型的数据,转成Java中的数据类型。例如数据库中也有int float double char varchar date这些类型和Java中的int byte short float double String如何对应起来呢。

                                  下面这个表格,左侧是Java的数据类型/对象,右侧是数据库的数据类型的对应关系

bytetityint
shortsmallint
intint
longbigint
floatfloat
doubledouble
Stringchar varchar
Datedate

我们Student表中的,ID和Age对应数据类型是int, Name和性别对应的是varchar,也就是Java Bean类我们用String对象来保存从数据库拿到的内容。搞清楚了这个数据类型对应关系,接下来我们要学习JDBC中ResultSet提供的相关get方法。

得到结果集中某一列的方法
Object getObject(int columnIndex)根据列的序号取值,索引从1开始
Object getObject(String columnName)根据列的名称取值

上面这两个方法可以拿到结果集中任意的一列,那么如何拿到列中的一些字段/属性的值呢,下面表格的方法就是获取结果集当前行的不同数据类型的get方法。

int getInt(int colIndex)以int形式获取ResultSet结果集当前行指定列号值
int getInt(String colLabel)以int形式获取ResultSet结果集当前行指定列名值
float getFloat(int colIndex)以float形式获取ResultSet结果集当前行指定列号值
float getFloat(String colLabel)以float形式获取ResultSet结果集当前行指定列名值
String getString(int colIndex)以String形式获取ResultSet结果集当前行指定列号值
String getString(String colLabel)以String形式获取ResultSet结果集当前行指定列名值
Date getDate(int colIndex)以Date形式获取ResultSet结果集当前行指定列号值
Date getDate(String colLabel)以Date形式获取ResultSet结果集当前行指定列名值

下面,我们来用Junit写一个测试例子,把查询到全部信息封装成Student对象并存储到ArrayList中去,然后遍历ArrayList看看效果。

package demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

public class TestDemo1 {
	@Test
	public void test1() throws Exception {
		//加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		//获取连接Connection对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "root", "123456");
		//得到执行SQL语句的Statement对象
		Statement stmt = conn.createStatement();
		//执行SQL语句,拿到结果集
		ResultSet rs = stmt.executeQuery("SELECT * FROM student");
		//封装结果集成Java 自定义对象
		List<Student> list = new ArrayList<Student>();
		while(rs.next()) {
			Student s = new Student();
			s.setName(rs.getString("Name"));
			s.setId(rs.getInt("ID"));
			s.setGender(rs.getString("Gender"));
			s.setAge(rs.getInt("Age"));
			// 把student对象添加到集合中
			list.add(s);
		}
		//遍历集合
		for (Student student : list) {
			System.out.println(student.toString());
		}
		
		//关闭资源
		rs.close();
		stmt.close();
		conn.close();
	}
	
}

测试结果:

Student [Id=192101, Name=Tom, Gender=male, Age=19, toString()=demo.Student@5bcea91b]
Student [Id=192102, Name=Lucy, Gender=female, Age=18, toString()=demo.Student@5f3a4b84]
Student [Id=192103, Name=Dniel, Gender=male, Age=20, toString()=demo.Student@27f723]
Student [Id=192104, Name=Sunny, Gender=female, Age=18, toString()=demo.Student@670b40af]
Student [Id=192105, Name=Anthony, Gender=male, Age=23, toString()=demo.Student@4923ab24]

通过打印内容,我们知道确实存储到了Bean类,也就是高级对象中,如果前端开发需要利用这些数据,可能还需要进一步序列化成JSON数据或者文件。上面我们只尝试了几个get方法,还有几个类型没有用到,例如getDate(), 如果内容是一个日期时间,我们在Java中建议使用util包下的Date,而不是sql包下的Date,因为sql包下Date继承了util包下的Date,所以使用父类来保存变量就好。

2.可移动游标方法

boolean next()将游标从当前位置向下移动一行
boolean previous()将游标从当前位置向上移动一行 (很少用)
boolean absolute(int row)参数是当前行的索引,从1开始,根据行的索引定位移动到指定行
void afterLast()游标移动到最后一行之后
void beforeFirst()游标移动到开头,也就是第一行之前,表头

什么是游标,在ResultSet结果集中提供了游标方法。JDK文档中有这么一句话:ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。

如何理解游标默认放在第一行之前,一张表中,第一行之前也就是表头的列名。这里也提到next方法,就是游标从第一行之前,一行一行往下走,如果next()方法返回true,所以,我们前面用到while(rs.next()),为什么这么用,就是这个原因。既然有Next方法,这里也说下previous方法,现在基本上不用这个方法。就是让游标往上移动一行,我们习惯使用next方法。

最后,简单看看ResultSet 的close方法,这个方法就是用来关闭资源的,没什么好说的。下面简单些一个例子,游标移动到最后一行之后位置,然后使用previous方法定位到最后一行,读取最后一行的数据。

@Test
	public void test2() throws Exception {
		//加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		//获取连接Connection对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "root", "123456");
		//得到执行SQL语句的Statement对象
		Statement stmt = conn.createStatement();
		//执行SQL语句,拿到结果集
		ResultSet rs = stmt.executeQuery("SELECT * FROM student");
		//封装结果集成Java 自定义对象
		List<Student> list = new ArrayList<Student>();
		//移动最后一行
		rs.afterLast();
		rs.previous(); //此时就在最后一行
		
		Student s = new Student();
		s.setName(rs.getString("Name"));
		s.setId(rs.getInt("ID"));
		s.setGender(rs.getString("Gender"));
		s.setAge(rs.getInt("Age"));
		// 把student对象添加到集合中
		list.add(s);
		
		//遍历集合
		for (Student student : list) {
			System.out.println(student.toString());
		}
		
		//关闭资源
		rs.close();
		stmt.close();
		conn.close();
	}
	

测试结果

Student [Id=192105, Name=Anthony, Gender=male, Age=23, toString()=demo.Student@7a3d45bd]

根据前面test1()测试打印全部表内容,这里打印一行数据确实是最后一行获取的数据。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值