MySQL系列-正确使用原生JDBC

本文详细介绍了如何正确使用原生JDBC操作MySQL数据库,包括加载数据库驱动、获取数据库连接、创建Statement对象、执行SQL、处理结果集及释放资源等步骤。强调了防止SQL注入和优化资源释放的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般我们也很少原生JDBC,都是在ORM框架上做二次开发,确实框架帮我们做了很多事情,但是原生JDBC我们还是需要掌握的,网上很多代码为了省事写的很不规范,很容易误导第一次接触的人JDBC的人,接下来我详细解释一下使用原生JDBC的每个步骤,以及规范的编写代码,以MySQL为例。

主要分为以下六个步骤:

1.加载数据库驱动

2.根据配置的信息(用户、密码等等)获取链接

3.根据链接获取向数据库发送SQL语句的statement对象

4.执行statement对象获取结果集对象

5.从结果集对象中获取数据

6.释放资源

下面开始详细说明每个步骤,具体的每个类的所有使用方法可以参照API文档

1.加载数据库驱动

毫无疑问,首先到导入jdbc的驱动jar包,把mysql-connector-java-commercial-5.1.25-bin.jar添加到依赖库当中,我的MySQL版本5.5。

下面就是正式的加载驱动,网上大致有三种写法:

导包如下

import com.mysql.jdbc.Driver;
import java.sql.DriverManager;
DriverManager.registerDriver(new Driver());  //方法一
new Driver();                                //方法二
Class.forName("com.mysql.jdbc.Driver");      //方法三

这三种方法都可以将MySQL的驱动注册到DeiverManager当中,方法一最直接明了,显式的注册,其实我们可以打开驱动源码看看

static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }

也就是说,我们只要对这个驱动类进行初始化(静态代码块将执行)就可以了,他会自动注册到DriverManager中。所以方法一和方法二都无端new出了一个Driver对象,其实并不需要这个对象,又麻烦垃圾回收器再进行一次回收,所以方法三是最优的,Class.forName()将触发类加载的初始化过程。

2.根据配置的信息(用户、密码等等)获取链接

DriverManager manager = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdb", "root", "root");

这个信息写到配置文件当中更好,然后从配置文件当中读取,例如:

private static Properties dbConfig = new Properties();
static {
	try {
	        dbConfig.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
		Class.forName(dbConfig.getProperty("driver"));
	} catch (Exception e) {
		throw new Error(e);
	}
}
public static Connection getConnection() {
	Connection conn = null;
	try {
		conn = DriverManager.getConnection(dbConfig.getProperty("url"), dbConfig.getProperty("username"),dbConfig.getProperty("password"));
	} catch (Exception e) {
		e.printStackTrace();
	}
	return conn;
}

3.根据链接获取向数据库发送SQL语句的statement对象

有两种获取statement对象的方式:

Statement state = conn.createStatement();
String id="1";
ResultSet set = state.executeQuery("select * from lab where id>"+id);
String sql = "select * from user where id>?";
PreparedStatement state = conn.prepareStatement(sql);
state.setLong(1, id);
ResultSet set = st.executeQuery();

第一个方法会引发SQL注入问题,而第二个方法对sql语句进行预编译,这样可以避免SQL注入问题,而且预编译好的sql语句数据库执行起来更快。

4.执行statement对象获取结果集对象

 ResultSet set = state.executeQuery();  //查询操作执行该方法
 int r = state.executeUpdate(); //增删改执行该方法

5.从结果集对象中获取数据

while(set.next()) {
            System.out.println(set.getInt(2)+" "+set.getString("name"));
 }
我们可以从列名或者第几列(下标从第1列开始,而不是第0列)来获取数据,每次next会将游标移到下一行数据,直到数据读取完 返回false,后面我会专门出一篇博客讲解如何用java获取MySQL的各种常用数据类型。 操作各种数据类型

6.释放资源

释放资源不只是要释放链接,还要释放statement对象和resultset对象,在finally里面按获取的相反顺序释放。

finally {
            if (set != null) {
                try {
                    set.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(state!=null) {
                try {
                    state.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } 

resultset对象释放之后就无法继续从里面获取数据了,ResultSet依赖于当前的链接,它必须保持与数据库的连接(非离线),如果一定要传递ResultSet里面的数据,可以考虑在遍历ResultSet的时候获取需要的数据把数据封装进一个java对象中,转而传递这个java对象,这样便于传输、序列化(实现序列化接口)等等。

拓展学习 其实有个东西叫 RowSet  [JAVA基础之RowSet]

下面是一个完整的例子,在一个类中展示了所有的步骤,但是你应该把一些代码抽取出来,比如:加载驱动和资源释放放入一个专门的类当中。

import com.mysql.jdbc.Driver;
import java.sql.*;

public class MainJDBC {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement state = null;
        ResultSet set = null;
        try {
            //1.加载数据库驱动
            DriverManager.registerDriver(new Driver());
            //2.根据配置的信息(用户、密码等等)获取链接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdb", "root", "root");
            //3.根据链接获取向数据库发送SQL语句的statement对象
            state = conn.prepareStatement("select * from lab where id>?");
            state.setInt(1, 1);
            //4.执行statement对象获取结果集对象
            set = state.executeQuery();
            //5.从结果集对象中获取数据
            while (set.next()) {
                System.out.println(set.getInt(2) + " " + set.getString("name"));
            }
            //6.释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (set != null) {
                try {
                    set.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (state != null) {
                try {
                    state.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值