当前位置 > it书童 > java > 正文
推荐小册
java高效编程
怎样更高效地用 java 编程

juc并发工具库
java并发编程工具库

设计模式
设计模式

jvm调优
jvm调优

rabbitmq实战
rabbitmq实战

redis实战
redis实战

Keepavlied高可用集群
Keepavlied高可用集群

nginx入门到实战
nginx入门到实战

java调试
java调试中遇到的各种坑

java输入输出流
java输入输出流

Java JDBC 入门详解

java it书童 2020-08-13 11:32:29 0赞 0踩 274阅读 0评论

概述

Java DataBase Connectivity Java 数据库连接, Java语言操作数据库

JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

java 只定义接口,具体的实现类由数据库厂商实现

数据库有很多种,程序员希望能用相同的 java 代码操作不同的数据库,减少学习的成本。程序员最重要的是实现产品功能,而不是陷入各种语法的汪洋大海中

初始化数据库

快速入门

步骤:

  1. 导入 驱动 jar 包 ,不同版本的 mysql 有相应的 jar 包

mysql-connector-java-8.0.21.jar 放到项目的 libs 目录下,然后右键 --> Add As Library

  1. 获取数据库连接对象 Connection

  2. 定义sql

  3. 获取执行sql语句的对象 Statement

  4. 执行sql,接受返回结果

  5. 处理结果

  6. 释放资源

代码实现

// 获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "Mac_2020Pwd_Root");
// 定义sql语句
String sql = "update users set age = 25 where id = 1";
// 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
System.out.println(stmt);
// 执行sql
int count = stmt.executeUpdate(sql);
// 打印结果
System.out.println(count);
// 释放资源
stmt.close();
conn.close();

异常抛出

以上代码过于简单,没有考虑到异常情况,完整的写法应该将 jdbc 操作过程中可能产生的异常抛出或者处理

代码实现

Statement stmt = null;
Connection conn = null;
try {
  String sql = "insert into users (name, password, age) values ('赵六', '456', 45)";
  conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "Mac_2020Pwd_Root");
  stmt = conn.createStatement();
  int count = stmt.executeUpdate(sql);
  System.out.println(count);
  if (count > 0) {
    System.out.println("添加成功!");
  } else {
    System.out.println("添加失败!");
  }
} catch (SQLException throwables) {
  throwables.printStackTrace();
} finally {
  if (stmt != null) {
    try {
      stmt.close();
    } catch (SQLException throwables) {
      throwables.printStackTrace();
    }
  }

  if (conn != null) {
    try {
      conn.close();
    } catch (SQLException throwables) {
      throwables.printStackTrace();
    }
  }
}

读取数据

用 jdbc 遍历读取从 mysql 取出的数据集

代码实现

// ...
conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "Mac_2020Pwd_Root");
String sql = "select * from users";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()) {
  int id = rs.getInt(1);
  String name = rs.getString("name");
  int age = rs.getInt("age");
  System.out.println(id + " - " + name + " - " + age);
}
// ...

封装工具类

如果每次写 JDBC 都要写一大堆释放资源的代码,编程就显得很无趣,于是我们将这些重复单调的代码封装成一个工具类

src/util/JDBCUtils.java

将数据库连接放到一个单独的配置文件 src/jdbc.properties

url=jdbc:mysql:///test
user=root
password=Mac_2020Pwd_Root

工具类读取配置文件

// 读取配置文件
static {
  try {
    Properties pro = new Properties();
    // 获取文件路径
    ClassLoader classLoader = JDBCUtils.class.getClassLoader();
    URL res = classLoader.getResource("jdbc.properties");
    String path = res.getPath();
    // 加载文件
    pro.load(new FileReader(path));
    // 获取数据
    url = pro.getProperty("url");
    user = pro.getProperty("user");
    password = pro.getProperty("password");
  } catch (IOException e) {
    e.printStackTrace();
  }
}

获取连接

public static Connection getConnection() throws SQLException {
  return DriverManager.getConnection(url, user, password);
}

关闭资源

public static void close(Statement stmt, Connection conn) {
  if (stmt != null) {
    try {
      stmt.close();
    } catch (SQLException throwables) {
      throwables.printStackTrace();
    }
  }

  if (conn != null) {
    try {
      conn.close();
    } catch (SQLException throwables) {
      throwables.printStackTrace();
    }
  }
}

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

  if (stmt != null) {
    try {
      stmt.close();
    } catch (SQLException throwables) {
      throwables.printStackTrace();
    }
  }

  if (conn != null) {
    try {
      conn.close();
    } catch (SQLException throwables) {
      throwables.printStackTrace();
    }
  }
}

用一个登录案例校验工具类是否可用

代码实现

try {
  conn = JDBCUtils.getConnection();
  String sql = "select * from users where name = ? and password = ?";
  pstmt = conn.prepareStatement(sql);
  // 对 ? 进行赋值
  pstmt.setString(1, username);
  pstmt.setString(2, password);
  rs = pstmt.executeQuery();
  return rs.next();
} catch (SQLException throwables) {
  throwables.printStackTrace();
} finally {
  JDBCUtils.close(rs, pstmt, conn);
}

事务操作

代码实现

try {
  conn = JDBCUtils.getConnection();
  // 开启事务
  conn.setAutoCommit(false);
  // 定义 sql
  String sql1 = "update accounts set balance = balance - ? where id = ?";
  String sql2 = "update accounts set balance = balance + ? where id = ?";
  pstmt1 = conn.prepareStatement(sql1);
  pstmt2 = conn.prepareStatement(sql2);
  pstmt1.setDouble(1, 500);;
  pstmt1.setInt(2, 1);
  pstmt2.setDouble(1, 500);
  pstmt2.setInt(2, 2);
  pstmt1.executeUpdate();
  // 手动制造异常 将会回滚整个操作
  // int i = 3 / 0;
  pstmt2.executeUpdate();
  // 提交事务
  conn.commit();
} catch (SQLException throwables) {
  // 有异常时回滚事务
  try {
    if (conn != null) {
      conn.rollback();
    }
  } catch (SQLException e) {
    e.printStackTrace();
  }
  throwables.printStackTrace();
} finally {
  JDBCUtils.close(pstmt1, conn);
  JDBCUtils.close(pstmt2, null);
}
关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/610/introduction-to-java-jdbc