JDBC的查询操作
ResultSet 是 JDBC (Java 数据库连接) API 提供的接口,它用于表示 SQL 查询的结果集。ResultSet 对象中包含了查询结果的所有行,可以通过 next() 方法逐行地获取并处理每一行的数据。它最常用于执行 SELECT 语句查询出来的结果集。
ResultSet 的遍历是基于 JDBC 的流式处理机制的,即一行一行地获取结果,避免将所有结果全部取出后再进行处理导致内存溢出问题。
在使用 ResultSet 遍历查询结果时,一般会采用以下步骤:
- 执行 SQL 查询,获取 ResultSet 对象。
- 使用 ResultSet 的 next() 方法移动游标指向结果集的下一行,判断是否有更多的数据行。
- 如果有更多的数据行,则使用 ResultSet 对象提供的 getXXX() 方法获取当前行的各个字段(XXX 表示不同的数据类型)。例如,getLong("id") 方法用于获取当前行的 id 列对应的 Long 类型的值。
- 处理当前行的数据,例如将其存入 Java 对象中。
- 重复执行步骤 2~4,直到结果集中的所有行都被遍历完毕。
- 调用 ResultSet 的 close() 方法释放资源。
需要注意的是,在使用完 ResultSet 对象之后,需要及时关闭它,以释放数据库资源并避免潜在的内存泄漏问题。否则,如果在多个线程中打开了多个 ResultSet 对象,并且没有正确关闭它们的话,可能会导致数据库连接过多,从而影响系统的稳定性和性能。
通过列索引获取数据(以String类型获取)
需求:获取t_user表中所有数据,在控制台打印输出每一行的数据。
select id,name,password,realname,gender,tel from t_user;
要查询的数据如下图:
代码如下(重点关注第4步 第5步 第6步):
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.ResultSet;
public class JDBCTest09 {
public static void main(String[] args){
// 通过以下代码获取属性文件中的配置信息
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
// 3. 获取数据库操作对象
stmt = conn.createStatement();
// 4. 执行SQL语句
String sql = "select id,name,password,realname,gender,tel from t_user";
rs = stmt.executeQuery(sql);
// 5. 处理查询结果集(这里的处理方式就是:遍历所有数据并输出)
while(rs.next()){
String id = rs.getString(1);
String name = rs.getString(2);
String pwd = rs.getString(3);
String realname = rs.getString(4);
String gender = rs.getString(5);
String tel = rs.getString(6);
System.out.println(id + "\t" + name + "\t" + pwd + "\t" + realname + "\t" + gender + "\t" + tel);
}
} catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} finally {
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
public class JDBCTest03 {
public static void main(String[] args) {
// 读取属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.jdbc.jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
System.out.println(conn);
// 3.获取数据库操作对象
stmt = conn.createStatement();
// 4.执行SQL
String sql = "select realname,id,name,password from t_user";
rs = stmt.executeQuery(sql);
// 5.处理查询结果集
// 这里的处理方式就是直接打印输出。
/*
+----------+----+----------+----------+
| realname | id | name | password |
+----------+----+----------+----------+
| 张三 | 1 | zhangsan | 123 |
| 管理员 | 2 | admin | admin123 |
+----------+----+----------+----------+
*/
/*boolean hasNext = rs.next();
if(hasNext) {
// 取出光标指向的当前行的数据
// 不管数据库表中是什么数据类型,统一以字符串的形式取出。
// 以下的获取方式是通过列下标获取的,列下标从1开始。
String realname = rs.getString(1);
String id = rs.getString(2);
String name = rs.getString(3);
String pwd = rs.getString(4);
System.out.println(realname + "\t" + id + "\t" + name + "\t" + pwd);
}
hasNext = rs.next();
if(hasNext) {
String realname = rs.getString(1);
String id = rs.getString(2);
String name = rs.getString(3);
String pwd = rs.getString(4);
System.out.println(realname + "\t" + id + "\t" + name + "\t" + pwd);
}
hasNext = rs.next();
System.out.println(hasNext);*/
while(rs.next()){
// 取出当前光标指向的这一行的数据。
String s1 = rs.getString(1);
String s2 = rs.getString(2);
String s3 = rs.getString(3);
String s4 = rs.getString(4);
System.out.println(s1 + "\t" + s2 + "\t" + s3 + "\t" + s4);
}
// 查询所有员工信息
String sql2 = "select empno,ename,sal from emp";
rs = stmt.executeQuery(sql2);
while(rs.next()){
// 以指定的类型获取数据
int empno = rs.getInt(1);
String ename = rs.getString(2);
double sal = rs.getDouble(3);
System.out.println(empno + "," + ename + "," + sal * 10);
}
System.out.println("==============================");
// 查询所有员工信息
String sql3 = "select empno a, ename b, sal c from emp";
/*
+------+--------+---------+
| a | b | c |
+------+--------+---------+
| 7369 | SMITH | 800.00 |
| 7499 | ALLEN | 1600.00 |
| 7521 | WARD | 1250.00 |
| 7566 | JONES | 2975.00 |
| 7654 | MARTIN | 1250.00 |
| 7698 | BLAKE | 2850.00 |
| 7782 | CLARK | 2450.00 |
| 7788 | SCOTT | 3000.00 |
| 7839 | KING | 5000.00 |
| 7844 | TURNER | 1500.00 |
| 7876 | ADAMS | 1100.00 |
| 7900 | JAMES | 950.00 |
| 7902 | FORD | 3000.00 |
| 7934 | MILLER | 1300.00 |
+------+--------+---------+
*/
rs = stmt.executeQuery(sql3);
while(rs.next()){
int empno = rs.getInt("a");
// 报错,原因:这是因为查询结果集中没有empno这个列。只有a这个列。
//int empno = rs.getInt("empno");
String ename = rs.getString("b");
String sal = rs.getString("c");
System.out.println(empno + "," + ename + "," + sal);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 6.释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
执行结果如下:
代码解读:
// 4. 执行SQL语句
String sql = "select id,name,password,realname,gender,tel from t_user";
rs = stmt.executeQuery(sql);
执行insert delete update语句的时候,调用Statement接口的executeUpdate()方法。执行select语句的时候,调用Statement接口的executeQuery()方法。执行select语句后返回结果集对象:ResultSet。
代码解读:
// 5. 处理查询结果集(这里的处理方式就是:遍历所有数据并输出)
while(rs.next()){
String id = rs.getString(1);
String name = rs.getString(2);
String pwd = rs.getString(3);
String realname = rs.getString(4);
String gender = rs.getString(5);
String tel = rs.getString(6);
System.out.println(id + "\t" + name + "\t" + pwd + "\t" + realname + "\t" + gender + "\t" + tel);
}
- rs.next() 将游标移动到下一行,如果移动后指向的这一行有数据则返回true,没有数据则返回false。
- while循环体当中的代码是处理当前游标指向的这一行的数据。(注意:是处理的一行数据)
- rs.getString(int columnIndex) 其中 int columnIndex 是查询结果的列下标,列下标从1开始,以1递增。
- rs.getString(...) 方法在执行时,不管底层数据库中的数据类型是什么,统一以字符串String类型来获取。
代码解读:
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
ResultSet最终也是需要关闭的。先关闭ResultSet,再关闭Statement,最后关闭Connection。
通过列名获取数据(以String类型获取)
获取当前行的数据,不仅可以通过列下标获取,还可以通过查询结果的列名来获取,通常这种方式是被推荐的,因为可读性好。例如这样的SQL:
select id, name as username, realname from t_user;
执行结果是:
我们可以按照查询结果的列名来获取数据:
注意:是根据查询结果的列名,而不是表中的列名。以上查询的时候将字段name起别名username了,所以要根据username来获取,而不能再根据name来获取了。
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.ResultSet;
public class JDBCTest10 {
public static void main(String[] args){
// 通过以下代码获取属性文件中的配置信息
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
// 3. 获取数据库操作对象
stmt = conn.createStatement();
// 4. 执行SQL语句
String sql = "select id,name as username,realname from t_user";
rs = stmt.executeQuery(sql);
// 5. 处理查询结果集(这里的处理方式就是:遍历所有数据并输出)
while(rs.next()){
String id = rs.getString("id");
String name = rs.getString("username");
String realname = rs.getString("realname");
System.out.println(id + "\t" + name + "\t" + realname);
}
} catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} finally {
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
执行结果如下:
如果将上面代码中rs.getString("username")
修改为rs.getString("name")
,执行就会出现以下错误:
提示name列是不存在的。所以一定是根据查询结果中的列名来获取,而不是表中原始的列名。
以指定的类型获取数据
前面的程序可以看到,不管数据库表中是什么数据类型,都以String类型返回。当然,也能以指定类型返回。使用PowerDesigner再设计一张商品表:t_product,使用Navicat for MySQL工具准备数据如下:
id以long类型获取,name以String类型获取,price以double类型获取,create_time以java.sql.Date类型获取,代码如下:
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.ResultSet;
public class JDBCTest11 {
public static void main(String[] args){
// 通过以下代码获取属性文件中的配置信息
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
// 3. 获取数据库操作对象
stmt = conn.createStatement();
// 4. 执行SQL语句
String sql = "select id,name,price,create_time as createTime from t_product";
rs = stmt.executeQuery(sql);
// 5. 处理查询结果集(这里的处理方式就是:遍历所有数据并输出)
while(rs.next()){
long id = rs.getLong("id");
String name = rs.getString("name");
double price = rs.getDouble("price");
java.sql.Date createTime = rs.getDate("createTime");
// 以指定类型获取后是可以直接用的,例如获取到价格后,统一让价格乘以2
System.out.println(id + "\t" + name + "\t" + price * 2 + "\t" + createTime);
}
} catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} finally {
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
public class JDBCTest04 {
public static void main(String[] args) {
// 读取属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.jdbc.jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1.注册驱动
Class.forName(driver);
// 2.获取连接
conn = DriverManager.getConnection(url, user, password);
// 3.获取数据库操作对象
stmt = conn.createStatement();
// 4.执行SQL语句
String sql = "select id,name,price,create_time from t_product";
rs = stmt.executeQuery(sql);
// 5.处理查询结果集
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
while(rs.next()){
// 以特定的类型获取数据
long id = rs.getLong("id");
String name = rs.getString("name");
double price = rs.getDouble("price");
// 注意:从mysql数据库当中获取的日期类型的数据对应的java类型是:java.sql.Date。不是java.util.Date。
Date createTime = rs.getDate("create_time");
System.out.println(id + "," + name + "," + price + "," + createTime);
// 将java.sql.Date 转换成 java.util.Date(通过构造方法来完成转换。)
java.util.Date date = new java.util.Date(createTime.getTime());
// 进行格式化显示
String strDate = sdf.format(date);
System.out.println(strDate);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
// 6.释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
执行结果如下:
获取结果集的元数据信息(了解)
ResultSetMetaData 是一个接口,用于描述 ResultSet 中的元数据信息,即查询结果集的结构信息,例如查询结果集中包含了哪些列,每个列的数据类型、长度、标识符等。
ResultSetMetaData 可以通过 ResultSet 接口的 getMetaData() 方法获取,一般在对 ResultSet 进行元数据信息处理时使用。例如,可以使用 ResultSetMetaData 对象获取查询结果中列的信息,如列名、列的类型、列的长度等。通过 ResultSetMetaData 接口的方法,可以实现对查询结果的基本描述信息操作,例如获取查询结果集中有多少列、列的类型、列的标识符等。以下是一段通过 ResultSetMetaData 获取查询结果中列的信息的示例代码:
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class JDBCTest12 {
public static void main(String[] args){
// 通过以下代码获取属性文件中的配置信息
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
// 3. 获取数据库操作对象
stmt = conn.createStatement();
// 4. 执行SQL语句
String sql = "select id,name,price,create_time as createTime from t_product";
rs = stmt.executeQuery(sql);
// 获取元数据信息
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
System.out.println("列名:" + rsmd.getColumnName(i) + ",数据类型:" + rsmd.getColumnTypeName(i) +
",列的长度:" + rsmd.getColumnDisplaySize(i));
}
} catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} finally {
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
执行结果如下:
在上面的代码中,我们首先创建了一个 Statement 对象,然后执行了一条 SQL 查询语句,生成了一个 ResultSet 对象。接下来,我们通过 ResultSet 对象的 getMetaData() 方法获取了 ResultSetMetaData 对象,进而获取了查询结果中列的信息并进行输出。需要注意的是,在进行列信息的获取时,列的编号从 1 开始计算。该示例代码将获取查询结果集中所有列名、数据类型以及长度等信息。
获取新增行的主键值
有很多表的主键字段值都是自增的,在某些特殊的业务环境下,当我们插入了新数据后,希望能够获取到这条新数据的主键值,应该如何获取呢?在 JDBC 中,如果要获取插入数据后的主键值,可以使用 Statement 接口的 executeUpdate() 方法的重载版本,该方法接受一个额外的参数,用于指定是否需要获取自动生成的主键值。然后,通过以下两个步骤获取插入数据后的主键值:
- 在执行 executeUpdate() 方法时指定一个标志位,表示需要返回插入的主键值。
- 调用 Statement 对象的 getGeneratedKeys() 方法,返回一个包含插入的主键值的 ResultSet 对象。
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.ResultSet;
public class JDBCTest13 {
public static void main(String[] args){
// 通过以下代码获取属性文件中的配置信息
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
// 3. 获取数据库操作对象
stmt = conn.createStatement();
// 4. 执行SQL语句
String sql = "insert into t_user(name,password,realname,gender,tel) values('zhangsan','111','张三','男','19856525352')";
// 第一步
int count = stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
// 第二步
rs = stmt.getGeneratedKeys();
if(rs.next()){
int id = rs.getInt(1);
System.out.println("新增数据行的主键值:" + id);
}
} catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} finally {
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
public class JDBCTest06 {
public static void main(String[] args) {
// 读取属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.jdbc.jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1.注册驱动
Class.forName(driver);
// 2.获取连接
conn = DriverManager.getConnection(url, user, password);
// 3.获取数据库操作对象
stmt = conn.createStatement();
// 4.执行SQL语句
String sql = "insert into t_product(name,price,create_time) values('小米su7', 1.0, '2024-02-23')";
// 注意:第二个参数是标志位,用来表示是否将新插入的数据行的主键值返回
int count = stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
System.out.println("插入了" + count + "条记录");
// 获取这个新增行的主键值
// 返回的这个rs结果集中就包含了新增行的主键值
rs = stmt.getGeneratedKeys();
// 通过结果集取主键值
if(rs.next()){
long id = rs.getLong(1);
System.out.println("新增行的主键值:" + id);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
// 6.释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
执行结果如下:
以上代码中,我们将 Statement.RETURN_GENERATED_KEYS 传递给 executeUpdate() 方法,以指定需要获取插入的主键值。然后,通过调用 Statement 对象的 getGeneratedKeys() 方法获取包含插入的主键值的 ResultSet 对象,通过 ResultSet 对象获取主键值。需要注意的是,在使用 Statement 对象的 getGeneratedKeys() 方法获取自动生成的主键值时,主键值的获取方式具有一定的差异,需要根据不同的数据库种类和版本来进行调整。
工具类
public class DbUtils {
/**
* 工具类的构造方法一般都是私有化的,因为工具类中的一般都是静态的,
* 工具类就是为了方便编程,所以工具类中的方法都是直接采用“类名.”
* 的方式访问,因此不需要new对象。
*/
private DbUtils(){}
// 静态变量
private static String driver;
private static String url;
private static String user;
private static String password;
// 静态代码块
static {
// 在这里读取属性配置文件,给静态变量赋值
ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.jdbc.jdbc");
driver = bundle.getString("driver");
url = bundle.getString("url");
user = bundle.getString("user");
password = bundle.getString("password");
// 在类加载的时候,注册驱动,对于整个应用程序来说,注册驱动只需要做一次即可。所以选择静态代码块。
// 静态代码块在类加载时执行,并且只执行一次。
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 获取数据库连接对象
* @return 连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
// 实际上这里每一次调用 getConnection() 方法时都会获取一个全新的数据库连接对象,实际上这样效率是比较低的,后期会使用连接池进行改造。
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
}
/**
* 释放资源
* @param conn 连接对象
* @param stmt 数据库操作对象
* @param rs 结果集对象
*/
public static void close(Connection conn, Statement stmt, ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
public class JDBCTest07 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = DbUtils.getConnection();
stmt = conn.createStatement();
String sql = "insert into t_product(name,price,create_time) values('小米su7', 1.0, '2024-02-23')";
int count = stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
System.out.println("插入了" + count + "条记录");
rs = stmt.getGeneratedKeys();
if(rs.next()){
long id = rs.getLong(1);
System.out.println("新增行的主键值:" + id);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DbUtils.close(conn, stmt, rs);
}
}
}
使用IDEA工具编写JDBC程序
创建空的工程并设置JDK
创建一个空的工程:mypro
工程结构:
设置JDK以及编译器版本:
创建一个模块
将驱动加入到CLASSPATH
在模块jdbc下创建一个目录:lib
将mysql的驱动jar包拷贝到lib目录当中:
将jar包加入到classpath:
编写JDBC程序
新建软件包:com.powernode.jdbc
新建JDBCTest01类:
在JDBCTest01类中编写main方法,main方法中编写JDBC代码:
package com.powernode.jdbc;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.ResultSet;
public class JDBCTest01 {
public static void main(String[] args){
// 通过以下代码获取属性文件中的配置信息
ResourceBundle bundle = ResourceBundle.getBundle("com.powernode.jdbc.jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 注册驱动
Class.forName(driver);
// 2. 获取连接
conn = DriverManager.getConnection(url, user, password);
// 3. 获取数据库操作对象
stmt = conn.createStatement();
// 4. 执行SQL语句
String sql = "select id,name,password from t_user";
rs = stmt.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String pwd = rs.getString("password");
System.out.println(id + "," + name + "," + pwd);
}
} catch(SQLException | ClassNotFoundException e){
e.printStackTrace();
} finally {
// 6. 释放资源
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
提供配置文件,在com.powernode.jdbc包下新建jdbc.properties文件:
jdbc.properties文件中如下配置:
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=true&characterEncoding=utf-8
user=root
password=123456
执行结果如下: