JDBC——实现通用的查询

引言

上一篇jdbc的文章《JDBC——概述与JDBC的使用》介绍了JDBC的概念和背景知识,同时也讨论了获取数据库连接的方式,以及简单的实现了入库操作(更新、删除同理)。

本篇博客将会聚焦 PreparedStatement 的查询操作、以及 ResultSet 的结果集处理逻辑,结合 ResultSetMetaData 和反射技术实现通用的查询方法。

一、Java与SQL对应数据类型转换表

Java类型SQL类型
booleanBIT
byteTINYINT
shortSMALLINT
intINTEGER
longBIGINT
StringCHAR、VARCHAR、LONGVARCHAR
byte arrayBINARY、VAR BINARY
java.sql.DateDATE
java.sql.TimeTIME
java.sql.timestampTIMESTAMP

 

 

 

 

 

 

 

 

 

 

 

二、相关类

JDBCUtils 封装了获取连接关闭资源等通用操作(封装逻辑见《JDBC——概述与JDBC的使用》):

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtils {
    
    public static Connection getConnection() {
        Connection connection = null;
        try {
            // 默认的识别路径就是 src 目录下
            InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
            Properties props = new Properties();
            props.load(is);
            String url = props.getProperty("url");
            String username = props.getProperty("username");
            String password = props.getProperty("password");
            String driverName = props.getProperty("driverName");
            // 加载驱动类
            Class.forName(driverName);
            // 获取连接
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    public static void closeResource(Connection conn, Statement statement, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (statement != null) {
                statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

二、查询一条记录

public static <T> T selectOne(Class<T> clazz, String sql, Object... args) {
	Connection connection = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		// 获取数据连接
		connection = JDBCUtils.getConnection();
		// 获取预编译语句对象
		ps = connection.prepareStatement(sql);
		// 填充属性值,注意下标从 1 开始
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		// 执行查询,获取结果集
		rs = ps.executeQuery();
		// 获取结果集的元数据:ResultSetMetaData
		ResultSetMetaData rsmd = rs.getMetaData();
		// 通过元数据获取结果集中的列数
		int columnCount = rsmd.getColumnCount();
		// rs.next()方法判断是否存在下一条,相当于集合迭代器的 hasNext()
		if (rs.next()) {
			// 实体类必须包含空参构造器,才可以正常执行 newInstance()
			T t = clazz.newInstance();
			for (int i = 0; i < columnCount; i++) {
				// 获取别名(getColumnName()是获取列名,不建议使用)
				// 下标同样是从 1 开始
				String columnLabel = rsmd.getColumnLabel(i + 1);
				// 获取列值
				Object columnVal = rs.getObject(i + 1);
				// 通过反射封装对象
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(t, columnVal);
			}
			return t;
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		JDBCUtils.closeResource(connection, ps, rs);
	}
	return null;
}

三、查询集合

将 if (rs.next()) 换成 while(rs.next()) 即可,并通过构造一个 List 存储取得的对象元素。

总结

只要掌握了获取一条数据的通用方法,列表的处理逻辑就不在话下了。

需要关注一些重点:

1、PreparedStatement 填充占位符时,下标都是从 1 开始,通用的情况往往不知道填充的参数是何种类型,通过 setObject(..) 即可

2、与增删改不同的是,执行查询时,我们需要使用 executeQuery() 方法,并接收返回的 ResultSet 对象

3、ResultSet 并没有直接存储返回列的数量,我们需要获取到 ResultSetMetaData 获取列的数量,以及列的别名

4、rs.next() 实例方法用于判断结果集中是否存在下一条数据,它的作用相当于集合迭代器中的 hasNext() ,同时带有指针下移的操作

5、在使用 clazz.newInstance() 方法获取对象时,一定要记得实体类必须要有空参构造器

6、使用反射方法封装对象是唯一通用的方法,这样才能保证不论我们封装的是何种类型,都可以在运行时获取到对应的属性信息

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书提供了JDBCTMAPI的权威教程与参考·~JDBCAPI技术支持使用JavaTM编程语言进行通用数据访问,该版本进行了更新和扩展,覆盖整个JDBC 3.0API的内容,包括。iava.sql包和易于构建服务器端应用程序的javax.sql包。 除了介绍JDBC 3.0 API规范外,本书还包含了更深层次的解释——从循序渐进的教程到每一个类和接口的全面参考。 对于那些学习Java技术的新手而言,本书还介绍了Java编程语言和SQL的基础知识。以此为起点,您将学习如何建立数据库、如何建立连接、如何从结果集中获取值以及如何使用准备语句,从而学会创建完整的JDBC应用程序。另外,本书提供了很多示例,也举例说明了执行通用任务的方法。然后,本书转向更高级的主题,集中介绍JDBC 3.0API的一些高级功能,如可滚动和可更新的结果集、批量更新、SQL99数据类型、定制映射、保存点、语句池以及自动生成键等。 除了深入介绍JDBC元数据API之外,本书还给出了行集的最新信息。行集技术支持以JavaBeansTM组件来处理数据集。此外,本书还介绍了JdbcRowSet、CachedRowSet、WebRowSet、JoinRowSet和FilteredRowSet对象的标准实现。 本书对JDBCAPI中的每个类和接口(从Array到XADataSource)都提供了简洁但完整的信息。每个类不但包含用例的概述,还包含方法和域的详尽解释。 文中有关SQL类型和Java编程语言中的类型之间的映射关系的章节、附录A、JDBC 2.0和3.0API中新特征的总结以及术语表,对所有数据库程序员来说都是必不可少的资源。
好的,JDBCJava Database Connectivity的缩写,它是Java语言中用于操作数据库的标准API。在Java程序中使用JDBC查询数据的步骤如下: 1. 加载JDBC驱动程序 在使用JDBC操作数据库之前,需要先加载JDBC驱动程序。可以通过Class.forName()方法来加载驱动程序,例如: ``` Class.forName("com.mysql.jdbc.Driver"); ``` 2. 建立数据库连接 使用DriverManager.getConnection()方法建立与数据库的连接,需要指定数据库的URL、用户名和密码,例如: ``` String url = "jdbc:mysql://localhost:3306/test"; String username = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, username, password); ``` 3. 创建Statement对象 使用Connection对象的createStatement()方法创建Statement对象,用于执行SQL语句,例如: ``` Statement stmt = conn.createStatement(); ``` 4. 执行SQL语句 使用Statement对象的executeQuery()方法执行查询语句,例如: ``` String sql = "select * from student where age > 18"; ResultSet rs = stmt.executeQuery(sql); ``` 5. 处理查询结果 使用ResultSet对象处理查询结果,例如: ``` while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("id=" + id + ", name=" + name + ", age=" + age); } ``` 6. 关闭资源 使用完ResultSet、Statement和Connection等资源后需要关闭,例如: ``` rs.close(); stmt.close(); conn.close(); ``` 以上就是使用JDBC查询数据的步骤,希望能对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值